Something went wrong. Try again.
javascript for 🐜's, a tiny runtime with big ambitions antjs.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332#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);}