Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F4463966
math.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
math.c
View Options
#include
<float.h>
#include
"ant.h"
#include
"errors.h"
#include
"internal.h"
#include
"runtime.h"
#include
"modules/symbol.h"
#include
"modules/crypto.h"
#if DBL_MANT_DIG >= 64
#error "Unsupported double mantissa width for Math.random"
#endif
enum
{
MATH_RANDOM_MANTISSA_BITS
=
DBL_MANT_DIG
,
MATH_RANDOM_DISCARD_BITS
=
64
-
DBL_MANT_DIG
,
};
static
const
double
math_random_scale
=
1.0
/
(
double
)(
UINT64_C
(
1
)
<<
MATH_RANDOM_MANTISSA_BITS
);
static
ant_value_t
builtin_Math_abs
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
fabs
(
x
));
}
static
ant_value_t
builtin_Math_acos
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
acos
(
x
));
}
static
ant_value_t
builtin_Math_acosh
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
acosh
(
x
));
}
static
ant_value_t
builtin_Math_asin
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
asin
(
x
));
}
static
ant_value_t
builtin_Math_asinh
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
asinh
(
x
));
}
static
ant_value_t
builtin_Math_atan
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
atan
(
x
));
}
static
ant_value_t
builtin_Math_atanh
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
atanh
(
x
));
}
static
ant_value_t
builtin_Math_atan2
(
ant_params_t
)
{
double
y
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
double
x
=
(
nargs
<
2
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
1
]);
if
(
isnan
(
y
)
||
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
atan2
(
y
,
x
));
}
static
ant_value_t
builtin_Math_cbrt
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
cbrt
(
x
));
}
static
ant_value_t
builtin_Math_ceil
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
ceil
(
x
));
}
static
ant_value_t
builtin_Math_clz32
(
ant_params_t
)
{
if
(
nargs
<
1
)
return
tov
(
32
);
uint32_t
n
=
js_to_uint32
(
js_to_number
(
js
,
args
[
0
]));
if
(
n
==
0
)
return
tov
(
32
);
int
lz
=
__builtin_clz
(
n
);
if
(
sizeof
(
unsigned
int
)
>
sizeof
(
uint32_t
))
{
lz
-=
(
int
)((
sizeof
(
unsigned
int
)
-
sizeof
(
uint32_t
))
*
8
);
}
return
tov
((
double
)
lz
);
}
static
ant_value_t
builtin_Math_cos
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
cos
(
x
));
}
static
ant_value_t
builtin_Math_cosh
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
cosh
(
x
));
}
static
ant_value_t
builtin_Math_exp
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
exp
(
x
));
}
static
ant_value_t
builtin_Math_expm1
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
expm1
(
x
));
}
static
ant_value_t
builtin_Math_floor
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
floor
(
x
));
}
static
ant_value_t
builtin_Math_fround
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
((
double
)(
float
)
x
);
}
static
ant_value_t
builtin_Math_hypot
(
ant_params_t
)
{
if
(
nargs
==
0
)
return
tov
(
0.0
);
double
acc
=
0.0
;
bool
saw_nan
=
false
;
for
(
int
i
=
0
;
i
<
nargs
;
i
++
)
{
double
v
=
js_to_number
(
js
,
args
[
i
]);
if
(
isinf
(
v
))
return
tov
(
JS_INF
);
if
(
isnan
(
v
))
{
saw_nan
=
true
;
continue
;
}
acc
=
hypot
(
acc
,
v
);
}
if
(
saw_nan
)
return
tov
(
JS_NAN
);
return
tov
(
acc
);
}
static
ant_value_t
builtin_Math_imul
(
ant_params_t
)
{
if
(
nargs
<
2
)
return
tov
(
0
);
int32_t
a
=
js_to_int32
(
js_to_number
(
js
,
args
[
0
]));
int32_t
b
=
js_to_int32
(
js_to_number
(
js
,
args
[
1
]));
return
tov
((
double
)((
int32_t
)((
uint32_t
)
a
*
(
uint32_t
)
b
)));
}
static
ant_value_t
builtin_Math_log
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
log
(
x
));
}
static
ant_value_t
builtin_Math_log1p
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
log1p
(
x
));
}
static
ant_value_t
builtin_Math_log10
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
log10
(
x
));
}
static
ant_value_t
builtin_Math_log2
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
log2
(
x
));
}
static
ant_value_t
builtin_Math_max
(
ant_params_t
)
{
if
(
nargs
==
0
)
return
tov
(
JS_NEG_INF
);
double
max_val
=
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
max_val
))
return
tov
(
JS_NAN
);
for
(
int
i
=
1
;
i
<
nargs
;
i
++
)
{
double
v
=
js_to_number
(
js
,
args
[
i
]);
if
(
isnan
(
v
))
return
tov
(
JS_NAN
);
if
(
v
>
max_val
)
{
max_val
=
v
;
continue
;
}
if
(
v
==
0.0
&&
max_val
==
0.0
&&
!
signbit
(
v
)
&&
signbit
(
max_val
))
max_val
=
v
;
}
return
tov
(
max_val
);
}
static
ant_value_t
builtin_Math_min
(
ant_params_t
)
{
if
(
nargs
==
0
)
return
tov
(
JS_INF
);
double
min_val
=
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
min_val
))
return
tov
(
JS_NAN
);
for
(
int
i
=
1
;
i
<
nargs
;
i
++
)
{
double
v
=
js_to_number
(
js
,
args
[
i
]);
if
(
isnan
(
v
))
return
tov
(
JS_NAN
);
if
(
v
<
min_val
)
{
min_val
=
v
;
continue
;
}
if
(
v
==
0.0
&&
min_val
==
0.0
&&
signbit
(
v
)
&&
!
signbit
(
min_val
)
)
min_val
=
v
;
}
return
tov
(
min_val
);
}
static
ant_value_t
builtin_Math_pow
(
ant_params_t
)
{
double
base
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
double
exp
=
(
nargs
<
2
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
1
]);
if
(
isnan
(
base
)
||
isnan
(
exp
))
return
tov
(
JS_NAN
);
return
tov
(
pow
(
base
,
exp
));
}
static
ant_value_t
builtin_Math_random
(
ant_params_t
)
{
uint64_t
r
=
0
;
if
(
crypto_fill_random
(
&
r
,
sizeof
(
r
))
<
0
)
{
return
js_mkerr
(
js
,
"secure random generation failed"
);
}
uint64_t
fraction
=
r
>>
MATH_RANDOM_DISCARD_BITS
;
return
tov
((
double
)
fraction
*
math_random_scale
);
}
static
ant_value_t
builtin_Math_round
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
)
||
isinf
(
x
)
||
x
==
0.0
)
return
tov
(
x
);
if
(
x
<
0.0
&&
x
>=
-0.5
)
return
tov
(
-0.0
);
return
tov
(
floor
(
x
+
0.5
));
}
static
ant_value_t
builtin_Math_sign
(
ant_params_t
)
{
double
v
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
v
))
return
tov
(
JS_NAN
);
if
(
v
>
0
)
return
tov
(
1.0
);
if
(
v
<
0
)
return
tov
(
-1.0
);
return
tov
(
v
);
}
static
ant_value_t
builtin_Math_sin
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
sin
(
x
));
}
static
ant_value_t
builtin_Math_sinh
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
sinh
(
x
));
}
static
ant_value_t
builtin_Math_sqrt
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
sqrt
(
x
));
}
static
ant_value_t
builtin_Math_tan
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
tan
(
x
));
}
static
ant_value_t
builtin_Math_tanh
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
tanh
(
x
));
}
static
ant_value_t
builtin_Math_trunc
(
ant_params_t
)
{
double
x
=
(
nargs
<
1
)
?
JS_NAN
:
js_to_number
(
js
,
args
[
0
]);
if
(
isnan
(
x
))
return
tov
(
JS_NAN
);
return
tov
(
trunc
(
x
));
}
void
init_math_module
(
void
)
{
ant_t
*
js
=
rt
->
js
;
ant_value_t
glob
=
js_glob
(
js
);
ant_value_t
math_obj
=
mkobj
(
js
,
0
);
ant_value_t
object_proto
=
js
->
sym
.
object_proto
;
js_set_proto_init
(
math_obj
,
object_proto
);
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"E"
,
1
),
tov
(
M_E
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"LN10"
,
4
),
tov
(
M_LN10
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"LN2"
,
3
),
tov
(
M_LN2
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"LOG10E"
,
6
),
tov
(
M_LOG10E
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"LOG2E"
,
5
),
tov
(
M_LOG2E
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"PI"
,
2
),
tov
(
M_PI
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"SQRT1_2"
,
7
),
tov
(
M_SQRT1_2
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"SQRT2"
,
5
),
tov
(
M_SQRT2
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"abs"
,
3
),
js_mkfun
(
builtin_Math_abs
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"acos"
,
4
),
js_mkfun
(
builtin_Math_acos
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"acosh"
,
5
),
js_mkfun
(
builtin_Math_acosh
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"asin"
,
4
),
js_mkfun
(
builtin_Math_asin
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"asinh"
,
5
),
js_mkfun
(
builtin_Math_asinh
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"atan"
,
4
),
js_mkfun
(
builtin_Math_atan
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"atanh"
,
5
),
js_mkfun
(
builtin_Math_atanh
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"atan2"
,
5
),
js_mkfun
(
builtin_Math_atan2
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"cbrt"
,
4
),
js_mkfun
(
builtin_Math_cbrt
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"ceil"
,
4
),
js_mkfun
(
builtin_Math_ceil
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"clz32"
,
5
),
js_mkfun
(
builtin_Math_clz32
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"cos"
,
3
),
js_mkfun
(
builtin_Math_cos
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"cosh"
,
4
),
js_mkfun
(
builtin_Math_cosh
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"exp"
,
3
),
js_mkfun
(
builtin_Math_exp
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"expm1"
,
5
),
js_mkfun
(
builtin_Math_expm1
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"floor"
,
5
),
js_mkfun
(
builtin_Math_floor
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"fround"
,
6
),
js_mkfun
(
builtin_Math_fround
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"hypot"
,
5
),
js_mkfun
(
builtin_Math_hypot
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"imul"
,
4
),
js_mkfun
(
builtin_Math_imul
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"log"
,
3
),
js_mkfun
(
builtin_Math_log
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"log1p"
,
5
),
js_mkfun
(
builtin_Math_log1p
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"log10"
,
5
),
js_mkfun
(
builtin_Math_log10
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"log2"
,
4
),
js_mkfun
(
builtin_Math_log2
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"max"
,
3
),
js_mkfun
(
builtin_Math_max
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"min"
,
3
),
js_mkfun
(
builtin_Math_min
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"pow"
,
3
),
js_mkfun
(
builtin_Math_pow
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"random"
,
6
),
js_mkfun
(
builtin_Math_random
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"round"
,
5
),
js_mkfun
(
builtin_Math_round
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"sign"
,
4
),
js_mkfun
(
builtin_Math_sign
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"sin"
,
3
),
js_mkfun
(
builtin_Math_sin
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"sinh"
,
4
),
js_mkfun
(
builtin_Math_sinh
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"sqrt"
,
4
),
js_mkfun
(
builtin_Math_sqrt
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"tan"
,
3
),
js_mkfun
(
builtin_Math_tan
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"tanh"
,
4
),
js_mkfun
(
builtin_Math_tanh
));
js_setprop
(
js
,
math_obj
,
js_mkstr
(
js
,
"trunc"
,
5
),
js_mkfun
(
builtin_Math_trunc
));
js_set_sym
(
js
,
math_obj
,
get_toStringTag_sym
(),
js_mkstr
(
js
,
"Math"
,
4
));
js_setprop
(
js
,
glob
,
js_mkstr
(
js
,
"Math"
,
4
),
math_obj
);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, May 2, 5:57 PM (2 d)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
541598
Default Alt Text
math.c (11 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment