MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 331 lines 12 kB view raw
1#include <float.h> 2 3#include "ant.h" 4#include "errors.h" 5#include "internal.h" 6#include "runtime.h" 7 8#include "modules/symbol.h" 9#include "modules/crypto.h" 10 11#if DBL_MANT_DIG >= 64 12#error "Unsupported double mantissa width for Math.random" 13#endif 14 15enum { 16 MATH_RANDOM_MANTISSA_BITS = DBL_MANT_DIG, 17 MATH_RANDOM_DISCARD_BITS = 64 - DBL_MANT_DIG, 18}; 19 20static const double math_random_scale = 21 1.0 / (double)(UINT64_C(1) << MATH_RANDOM_MANTISSA_BITS); 22 23static ant_value_t builtin_Math_abs(ant_params_t) { 24 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 25 if (isnan(x)) return tov(JS_NAN); 26 return tov(fabs(x)); 27} 28 29static ant_value_t builtin_Math_acos(ant_params_t) { 30 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 31 if (isnan(x)) return tov(JS_NAN); 32 return tov(acos(x)); 33} 34 35static ant_value_t builtin_Math_acosh(ant_params_t) { 36 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 37 if (isnan(x)) return tov(JS_NAN); 38 return tov(acosh(x)); 39} 40 41static ant_value_t builtin_Math_asin(ant_params_t) { 42 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 43 if (isnan(x)) return tov(JS_NAN); 44 return tov(asin(x)); 45} 46 47static ant_value_t builtin_Math_asinh(ant_params_t) { 48 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 49 if (isnan(x)) return tov(JS_NAN); 50 return tov(asinh(x)); 51} 52 53static ant_value_t builtin_Math_atan(ant_params_t) { 54 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 55 if (isnan(x)) return tov(JS_NAN); 56 return tov(atan(x)); 57} 58 59static ant_value_t builtin_Math_atanh(ant_params_t) { 60 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 61 if (isnan(x)) return tov(JS_NAN); 62 return tov(atanh(x)); 63} 64 65static ant_value_t builtin_Math_atan2(ant_params_t) { 66 double y = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 67 double x = (nargs < 2) ? JS_NAN : js_to_number(js, args[1]); 68 if (isnan(y) || isnan(x)) return tov(JS_NAN); 69 return tov(atan2(y, x)); 70} 71 72static ant_value_t builtin_Math_cbrt(ant_params_t) { 73 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 74 if (isnan(x)) return tov(JS_NAN); 75 return tov(cbrt(x)); 76} 77 78static ant_value_t builtin_Math_ceil(ant_params_t) { 79 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 80 if (isnan(x)) return tov(JS_NAN); 81 return tov(ceil(x)); 82} 83 84static ant_value_t builtin_Math_clz32(ant_params_t) { 85 if (nargs < 1) return tov(32); 86 uint32_t n = js_to_uint32(js_to_number(js, args[0])); 87 if (n == 0) return tov(32); 88 int lz = __builtin_clz(n); 89 if (sizeof(unsigned int) > sizeof(uint32_t)) { 90 lz -= (int)((sizeof(unsigned int) - sizeof(uint32_t)) * 8); 91 } 92 return tov((double)lz); 93} 94 95static ant_value_t builtin_Math_cos(ant_params_t) { 96 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 97 if (isnan(x)) return tov(JS_NAN); 98 return tov(cos(x)); 99} 100 101static ant_value_t builtin_Math_cosh(ant_params_t) { 102 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 103 if (isnan(x)) return tov(JS_NAN); 104 return tov(cosh(x)); 105} 106 107static ant_value_t builtin_Math_exp(ant_params_t) { 108 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 109 if (isnan(x)) return tov(JS_NAN); 110 return tov(exp(x)); 111} 112 113static ant_value_t builtin_Math_expm1(ant_params_t) { 114 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 115 if (isnan(x)) return tov(JS_NAN); 116 return tov(expm1(x)); 117} 118 119static ant_value_t builtin_Math_floor(ant_params_t) { 120 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 121 if (isnan(x)) return tov(JS_NAN); 122 return tov(floor(x)); 123} 124 125static ant_value_t builtin_Math_fround(ant_params_t) { 126 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 127 if (isnan(x)) return tov(JS_NAN); 128 return tov((double)(float)x); 129} 130 131static ant_value_t builtin_Math_hypot(ant_params_t) { 132 if (nargs == 0) return tov(0.0); 133 double acc = 0.0; 134 bool saw_nan = false; 135 for (int i = 0; i < nargs; i++) { 136 double v = js_to_number(js, args[i]); 137 if (isinf(v)) return tov(JS_INF); 138 if (isnan(v)) { saw_nan = true; continue; } 139 acc = hypot(acc, v); 140 } 141 if (saw_nan) return tov(JS_NAN); 142 return tov(acc); 143} 144 145static ant_value_t builtin_Math_imul(ant_params_t) { 146 if (nargs < 2) return tov(0); 147 int32_t a = js_to_int32(js_to_number(js, args[0])); 148 int32_t b = js_to_int32(js_to_number(js, args[1])); 149 return tov((double)((int32_t)((uint32_t)a * (uint32_t)b))); 150} 151 152static ant_value_t builtin_Math_log(ant_params_t) { 153 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 154 if (isnan(x)) return tov(JS_NAN); 155 return tov(log(x)); 156} 157 158static ant_value_t builtin_Math_log1p(ant_params_t) { 159 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 160 if (isnan(x)) return tov(JS_NAN); 161 return tov(log1p(x)); 162} 163 164static ant_value_t builtin_Math_log10(ant_params_t) { 165 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 166 if (isnan(x)) return tov(JS_NAN); 167 return tov(log10(x)); 168} 169 170static ant_value_t builtin_Math_log2(ant_params_t) { 171 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 172 if (isnan(x)) return tov(JS_NAN); 173 return tov(log2(x)); 174} 175 176static ant_value_t builtin_Math_max(ant_params_t) { 177 if (nargs == 0) return tov(JS_NEG_INF); 178 double max_val = js_to_number(js, args[0]); 179 if (isnan(max_val)) return tov(JS_NAN); 180 for (int i = 1; i < nargs; i++) { 181 double v = js_to_number(js, args[i]); 182 if (isnan(v)) return tov(JS_NAN); 183 if (v > max_val) { max_val = v; continue; } 184 if (v == 0.0 && max_val == 0.0 && !signbit(v) && signbit(max_val)) max_val = v; 185 } 186 return tov(max_val); 187} 188 189static ant_value_t builtin_Math_min(ant_params_t) { 190 if (nargs == 0) return tov(JS_INF); 191 double min_val = js_to_number(js, args[0]); 192 if (isnan(min_val)) return tov(JS_NAN); 193 for (int i = 1; i < nargs; i++) { 194 double v = js_to_number(js, args[i]); 195 if (isnan(v)) return tov(JS_NAN); 196 if (v < min_val) { 197 min_val = v; 198 continue; 199 } 200 if (v == 0.0 201 && min_val == 0.0 202 && signbit(v) 203 && !signbit(min_val) 204 ) min_val = v; 205 } 206 return tov(min_val); 207} 208 209static ant_value_t builtin_Math_pow(ant_params_t) { 210 double base = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 211 double exp = (nargs < 2) ? JS_NAN : js_to_number(js, args[1]); 212 if (isnan(base) || isnan(exp)) return tov(JS_NAN); 213 return tov(pow(base, exp)); 214} 215 216static ant_value_t builtin_Math_random(ant_params_t) { 217 uint64_t r = 0; 218 if (crypto_fill_random(&r, sizeof(r)) < 0) { 219 return js_mkerr(js, "secure random generation failed"); 220 } 221 222 uint64_t fraction = r >> MATH_RANDOM_DISCARD_BITS; 223 return tov((double)fraction * math_random_scale); 224} 225 226static ant_value_t builtin_Math_round(ant_params_t) { 227 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 228 if (isnan(x) || isinf(x) || x == 0.0) return tov(x); 229 if (x < 0.0 && x >= -0.5) return tov(-0.0); 230 return tov(floor(x + 0.5)); 231} 232 233static ant_value_t builtin_Math_sign(ant_params_t) { 234 double v = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 235 if (isnan(v)) return tov(JS_NAN); 236 if (v > 0) return tov(1.0); 237 if (v < 0) return tov(-1.0); 238 return tov(v); 239} 240 241static ant_value_t builtin_Math_sin(ant_params_t) { 242 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 243 if (isnan(x)) return tov(JS_NAN); 244 return tov(sin(x)); 245} 246 247static ant_value_t builtin_Math_sinh(ant_params_t) { 248 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 249 if (isnan(x)) return tov(JS_NAN); 250 return tov(sinh(x)); 251} 252 253static ant_value_t builtin_Math_sqrt(ant_params_t) { 254 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 255 if (isnan(x)) return tov(JS_NAN); 256 return tov(sqrt(x)); 257} 258 259static ant_value_t builtin_Math_tan(ant_params_t) { 260 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 261 if (isnan(x)) return tov(JS_NAN); 262 return tov(tan(x)); 263} 264 265static ant_value_t builtin_Math_tanh(ant_params_t) { 266 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 267 if (isnan(x)) return tov(JS_NAN); 268 return tov(tanh(x)); 269} 270 271static ant_value_t builtin_Math_trunc(ant_params_t) { 272 double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 273 if (isnan(x)) return tov(JS_NAN); 274 return tov(trunc(x)); 275} 276 277void init_math_module(void) { 278 ant_t *js = rt->js; 279 280 ant_value_t glob = js_glob(js); 281 ant_value_t math_obj = mkobj(js, 0); 282 ant_value_t object_proto = js->sym.object_proto; 283 284 js_set_proto_init(math_obj, object_proto); 285 js_setprop(js, math_obj, js_mkstr(js, "E", 1), tov(M_E)); 286 js_setprop(js, math_obj, js_mkstr(js, "LN10", 4), tov(M_LN10)); 287 js_setprop(js, math_obj, js_mkstr(js, "LN2", 3), tov(M_LN2)); 288 js_setprop(js, math_obj, js_mkstr(js, "LOG10E", 6), tov(M_LOG10E)); 289 js_setprop(js, math_obj, js_mkstr(js, "LOG2E", 5), tov(M_LOG2E)); 290 js_setprop(js, math_obj, js_mkstr(js, "PI", 2), tov(M_PI)); 291 js_setprop(js, math_obj, js_mkstr(js, "SQRT1_2", 7), tov(M_SQRT1_2)); 292 js_setprop(js, math_obj, js_mkstr(js, "SQRT2", 5), tov(M_SQRT2)); 293 js_setprop(js, math_obj, js_mkstr(js, "abs", 3), js_mkfun(builtin_Math_abs)); 294 js_setprop(js, math_obj, js_mkstr(js, "acos", 4), js_mkfun(builtin_Math_acos)); 295 js_setprop(js, math_obj, js_mkstr(js, "acosh", 5), js_mkfun(builtin_Math_acosh)); 296 js_setprop(js, math_obj, js_mkstr(js, "asin", 4), js_mkfun(builtin_Math_asin)); 297 js_setprop(js, math_obj, js_mkstr(js, "asinh", 5), js_mkfun(builtin_Math_asinh)); 298 js_setprop(js, math_obj, js_mkstr(js, "atan", 4), js_mkfun(builtin_Math_atan)); 299 js_setprop(js, math_obj, js_mkstr(js, "atanh", 5), js_mkfun(builtin_Math_atanh)); 300 js_setprop(js, math_obj, js_mkstr(js, "atan2", 5), js_mkfun(builtin_Math_atan2)); 301 js_setprop(js, math_obj, js_mkstr(js, "cbrt", 4), js_mkfun(builtin_Math_cbrt)); 302 js_setprop(js, math_obj, js_mkstr(js, "ceil", 4), js_mkfun(builtin_Math_ceil)); 303 js_setprop(js, math_obj, js_mkstr(js, "clz32", 5), js_mkfun(builtin_Math_clz32)); 304 js_setprop(js, math_obj, js_mkstr(js, "cos", 3), js_mkfun(builtin_Math_cos)); 305 js_setprop(js, math_obj, js_mkstr(js, "cosh", 4), js_mkfun(builtin_Math_cosh)); 306 js_setprop(js, math_obj, js_mkstr(js, "exp", 3), js_mkfun(builtin_Math_exp)); 307 js_setprop(js, math_obj, js_mkstr(js, "expm1", 5), js_mkfun(builtin_Math_expm1)); 308 js_setprop(js, math_obj, js_mkstr(js, "floor", 5), js_mkfun(builtin_Math_floor)); 309 js_setprop(js, math_obj, js_mkstr(js, "fround", 6), js_mkfun(builtin_Math_fround)); 310 js_setprop(js, math_obj, js_mkstr(js, "hypot", 5), js_mkfun(builtin_Math_hypot)); 311 js_setprop(js, math_obj, js_mkstr(js, "imul", 4), js_mkfun(builtin_Math_imul)); 312 js_setprop(js, math_obj, js_mkstr(js, "log", 3), js_mkfun(builtin_Math_log)); 313 js_setprop(js, math_obj, js_mkstr(js, "log1p", 5), js_mkfun(builtin_Math_log1p)); 314 js_setprop(js, math_obj, js_mkstr(js, "log10", 5), js_mkfun(builtin_Math_log10)); 315 js_setprop(js, math_obj, js_mkstr(js, "log2", 4), js_mkfun(builtin_Math_log2)); 316 js_setprop(js, math_obj, js_mkstr(js, "max", 3), js_mkfun(builtin_Math_max)); 317 js_setprop(js, math_obj, js_mkstr(js, "min", 3), js_mkfun(builtin_Math_min)); 318 js_setprop(js, math_obj, js_mkstr(js, "pow", 3), js_mkfun(builtin_Math_pow)); 319 js_setprop(js, math_obj, js_mkstr(js, "random", 6), js_mkfun(builtin_Math_random)); 320 js_setprop(js, math_obj, js_mkstr(js, "round", 5), js_mkfun(builtin_Math_round)); 321 js_setprop(js, math_obj, js_mkstr(js, "sign", 4), js_mkfun(builtin_Math_sign)); 322 js_setprop(js, math_obj, js_mkstr(js, "sin", 3), js_mkfun(builtin_Math_sin)); 323 js_setprop(js, math_obj, js_mkstr(js, "sinh", 4), js_mkfun(builtin_Math_sinh)); 324 js_setprop(js, math_obj, js_mkstr(js, "sqrt", 4), js_mkfun(builtin_Math_sqrt)); 325 js_setprop(js, math_obj, js_mkstr(js, "tan", 3), js_mkfun(builtin_Math_tan)); 326 js_setprop(js, math_obj, js_mkstr(js, "tanh", 4), js_mkfun(builtin_Math_tanh)); 327 js_setprop(js, math_obj, js_mkstr(js, "trunc", 5), js_mkfun(builtin_Math_trunc)); 328 329 js_set_sym(js, math_obj, get_toStringTag_sym(), js_mkstr(js, "Math", 4)); 330 js_setprop(js, glob, js_mkstr(js, "Math", 4), math_obj); 331}