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.

de-couple math

+1140 -892
+2 -15
include/internal.h
··· 251 251 ant_offset_t lkp_sym_proto(ant_t *js, ant_value_t obj, ant_offset_t sym_off); 252 252 ant_offset_t vstr(ant_t *js, ant_value_t value, ant_offset_t *len); 253 253 ant_offset_t vstrlen(ant_t *js, ant_value_t value); 254 - ant_value_t rope_flatten(ant_t *js, ant_value_t rope); 255 254 ant_offset_t str_len_fast(ant_t *js, ant_value_t str); 255 + ant_offset_t js_alloc(ant_t *js, size_t size); 256 256 257 257 ant_value_t mkarr(ant_t *js); 258 258 ant_value_t mkval(uint8_t type, uint64_t data); 259 259 ant_value_t mkobj(ant_t *js, ant_offset_t parent); 260 + ant_value_t rope_flatten(ant_t *js, ant_value_t rope); 260 261 261 262 ant_value_t js_for_in_keys(ant_t *js, ant_value_t obj); 262 263 ant_value_t js_delete_prop(ant_t *js, ant_value_t obj, const char *key, size_t len); ··· 276 277 277 278 ant_value_t do_instanceof(ant_t *js, ant_value_t l, ant_value_t r); 278 279 ant_value_t do_in(ant_t *js, ant_value_t l, ant_value_t r); 279 - 280 - ant_value_t bigint_add(ant_t *js, ant_value_t a, ant_value_t b); 281 - ant_value_t bigint_sub(ant_t *js, ant_value_t a, ant_value_t b); 282 - ant_value_t bigint_mul(ant_t *js, ant_value_t a, ant_value_t b); 283 - ant_value_t bigint_div(ant_t *js, ant_value_t a, ant_value_t b); 284 - ant_value_t bigint_mod(ant_t *js, ant_value_t a, ant_value_t b); 285 - ant_value_t bigint_neg(ant_t *js, ant_value_t a); 286 - ant_value_t bigint_exp(ant_t *js, ant_value_t base, ant_value_t exp); 287 - int bigint_compare(ant_t *js, ant_value_t a, ant_value_t b); 288 - 289 - ant_value_t bigint_shift_left(ant_t *js, ant_value_t value, uint64_t shift); 290 - ant_value_t bigint_shift_right(ant_t *js, ant_value_t value, uint64_t shift); 291 - ant_value_t bigint_shift_right_logical(ant_t *js, ant_value_t value, uint64_t shift); 292 - ant_value_t bigint_asint_bits(ant_t *js, ant_value_t arg, uint64_t *bits_out); 293 280 294 281 #endif
+29
include/modules/bigint.h
··· 1 + #ifndef BIGINT_MODULE_H 2 + #define BIGINT_MODULE_H 3 + 4 + #include "types.h" 5 + 6 + void init_bigint_module(void); 7 + 8 + ant_value_t bigint_add(ant_t *js, ant_value_t a, ant_value_t b); 9 + ant_value_t bigint_sub(ant_t *js, ant_value_t a, ant_value_t b); 10 + ant_value_t bigint_mul(ant_t *js, ant_value_t a, ant_value_t b); 11 + ant_value_t bigint_div(ant_t *js, ant_value_t a, ant_value_t b); 12 + ant_value_t bigint_mod(ant_t *js, ant_value_t a, ant_value_t b); 13 + ant_value_t bigint_neg(ant_t *js, ant_value_t a); 14 + ant_value_t bigint_exp(ant_t *js, ant_value_t base, ant_value_t exp); 15 + 16 + ant_value_t bigint_shift_left(ant_t *js, ant_value_t value, uint64_t shift); 17 + ant_value_t bigint_shift_right(ant_t *js, ant_value_t value, uint64_t shift); 18 + ant_value_t bigint_shift_right_logical(ant_t *js, ant_value_t value, uint64_t shift); 19 + ant_value_t bigint_asint_bits(ant_t *js, ant_value_t arg, uint64_t *bits_out); 20 + 21 + bool bigint_is_negative(ant_t *js, ant_value_t v); 22 + bool bigint_is_zero(ant_t *js, ant_value_t v); 23 + 24 + 25 + size_t bigint_digits_len(ant_t *js, ant_value_t v); 26 + size_t strbigint(ant_t *js, ant_value_t value, char *buf, size_t len); 27 + size_t bigint_compare(ant_t *js, ant_value_t a, ant_value_t b); 28 + 29 + #endif
+6
include/modules/math.h
··· 1 + #ifndef MATH_MODULE_H 2 + #define MATH_MODULE_H 3 + 4 + void init_math_module(void); 5 + 6 + #endif
+3 -877
src/ant.c
··· 50 50 #endif 51 51 52 52 #include "modules/fs.h" 53 + #include "modules/bigint.h" 53 54 #include "modules/timer.h" 54 55 #include "modules/fetch.h" 55 56 #include "modules/symbol.h" ··· 309 310 static ant_value_t proxy_read_target(ant_t *js, ant_value_t obj); 310 311 static ant_offset_t proxy_aware_length(ant_t *js, ant_value_t obj); 311 312 static ant_value_t proxy_aware_get_elem(ant_t *js, ant_value_t obj, const char *key, size_t key_len); 312 - static bool bigint_is_zero(ant_t *js, ant_value_t v); 313 313 314 314 static ant_offset_t get_dense_buf(ant_t *js, ant_value_t arr); 315 315 static ant_offset_t dense_length(ant_t *js, ant_offset_t doff); ··· 324 324 static ant_value_t call_proto_accessor(ant_t *js, ant_value_t prim, ant_value_t accessor, bool has_accessor, ant_value_t *arg, int arg_count, bool is_setter); 325 325 static ant_value_t get_prototype_for_type(ant_t *js, uint8_t type); 326 326 327 - static size_t strbigint(ant_t *js, ant_value_t value, char *buf, size_t len); 328 327 static size_t tostr(ant_t *js, ant_value_t value, char *buf, size_t len); 329 328 static size_t strpromise(ant_t *js, ant_value_t value, char *buf, size_t len); 330 329 static ant_value_t js_call_valueOf(ant_t *js, ant_value_t value); ··· 349 348 static ant_value_t get_prototype_for_type(ant_t *js, uint8_t type); 350 349 static ant_value_t get_ctor_proto(ant_t *js, const char *name, size_t len); 351 350 static ant_offset_t lkp_interned(ant_t *js, ant_value_t obj, const char *search_intern, size_t len); 352 - 353 - static const char *bigint_digits(ant_t *js, ant_value_t v, size_t *len); 354 351 355 352 typedef struct { ant_value_t handle; bool is_new; } ctor_t; 356 353 ··· 434 431 } 435 432 buf[len] = '\0'; 436 433 return len; 437 - } 438 - 439 - static ant_value_t bigint_from_u64(ant_t *js, uint64_t value) { 440 - char buf[32]; 441 - size_t len = uint_to_str(buf, sizeof(buf), value); 442 - return js_mkbigint(js, buf, len, false); 443 434 } 444 435 445 436 static ant_value_t stringify_stack[MAX_STRINGIFY_DEPTH]; ··· 1809 1800 } 1810 1801 1811 1802 L_BIGINT: { 1812 - bigint_digits(js, value, &buflen); 1803 + buflen = bigint_digits_len(js, value); 1813 1804 buf = (char *)ant_calloc(buflen + 2); 1814 1805 len = strbigint(js, value, buf, buflen + 2); 1815 1806 ant_value_t result = js_mkstr(js, buf, len); ··· 1909 1900 if (js->gc_alloc_since > threshold) js->needs_gc = true; 1910 1901 } 1911 1902 1912 - static inline ant_offset_t js_alloc(ant_t *js, size_t size) { 1903 + ant_offset_t js_alloc(ant_t *js, size_t size) { 1913 1904 size = align64((ant_offset_t) size); 1914 1905 if (!js_ensure_space(js, size)) return ~(ant_offset_t) 0; 1915 1906 ··· 2113 2104 return mkval(T_STR, ofs); 2114 2105 } 2115 2106 2116 - static bool bigint_parse_abs_u64(ant_t *js, ant_value_t value, uint64_t *out) { 2117 - size_t len = 0; const char *digits = bigint_digits(js, value, &len); 2118 - uint64_t acc = 0; 2119 - 2120 - for (size_t i = 0; i < len; i++) { 2121 - char c = digits[i]; 2122 - if (!is_digit(c)) return false; 2123 - uint64_t digit = (uint64_t)(c - '0'); 2124 - if (acc > UINT64_MAX / 10 || (acc == UINT64_MAX / 10 && digit > (UINT64_MAX % 10))) { 2125 - return false; 2126 - } acc = acc * 10 + digit; 2127 - } 2128 - 2129 - *out = acc; 2130 - return true; 2131 - } 2132 - 2133 - static bool bigint_IsNegative(ant_t *js, ant_value_t v) { 2134 - ant_offset_t ofs = (ant_offset_t) vdata(v); 2135 - return js->mem[ofs + sizeof(ant_offset_t)] == 1; 2136 - } 2137 - 2138 - static bool bigint_parse_u64(ant_t *js, ant_value_t value, uint64_t *out) { 2139 - if (bigint_IsNegative(js, value)) return false; 2140 - return bigint_parse_abs_u64(js, value, out); 2141 - } 2142 - 2143 - ant_value_t js_mkbigint(ant_t *js, const char *digits, size_t len, bool negative) { 2144 - size_t total = len + 2; 2145 - ant_offset_t ofs = js_alloc(js, total + sizeof(ant_offset_t)); 2146 - if (ofs == (ant_offset_t) ~0) return js_mkerr(js, "oom"); 2147 - ant_offset_t header = (ant_offset_t) (total << 4); 2148 - memcpy(&js->mem[ofs], &header, sizeof(header)); 2149 - js->mem[ofs + sizeof(header)] = negative ? 1 : 0; 2150 - if (digits) memcpy(&js->mem[ofs + sizeof(header) + 1], digits, len); 2151 - js->mem[ofs + sizeof(header) + 1 + len] = 0; 2152 - return mkval(T_BIGINT, ofs); 2153 - } 2154 - 2155 - static const char *bigint_digits(ant_t *js, ant_value_t v, size_t *len) { 2156 - ant_offset_t ofs = (ant_offset_t) vdata(v); 2157 - ant_offset_t header = loadoff(js, ofs); 2158 - size_t total = (header >> 4) - 2; 2159 - if (len) *len = total; 2160 - return (const char *)&js->mem[ofs + sizeof(ant_offset_t) + 1]; 2161 - } 2162 - 2163 - static int bigint_cmp_abs(const char *a, size_t alen, const char *b, size_t blen) { 2164 - while (alen > 1 && a[0] == '0') { a++; alen--; } 2165 - while (blen > 1 && b[0] == '0') { b++; blen--; } 2166 - if (alen != blen) return alen > blen ? 1 : -1; 2167 - for (size_t i = 0; i < alen; i++) { 2168 - if (a[i] != b[i]) return a[i] > b[i] ? 1 : -1; 2169 - } 2170 - return 0; 2171 - } 2172 - 2173 - static char *bigint_add_abs(const char *a, size_t alen, const char *b, size_t blen, size_t *rlen) { 2174 - size_t maxlen = (alen > blen ? alen : blen) + 1; 2175 - char *result = (char *)malloc(maxlen + 1); 2176 - if (!result) return NULL; 2177 - int carry = 0; 2178 - size_t ri = 0; 2179 - for (size_t i = 0; i < maxlen; i++) { 2180 - int da = (i < alen) ? (a[alen - 1 - i] - '0') : 0; 2181 - int db = (i < blen) ? (b[blen - 1 - i] - '0') : 0; 2182 - int sum = da + db + carry; 2183 - carry = sum / 10; 2184 - result[ri++] = (char)('0' + (sum % 10)); 2185 - } 2186 - while (ri > 1 && result[ri - 1] == '0') ri--; 2187 - for (size_t i = 0; i < ri / 2; i++) { 2188 - char tmp = result[i]; result[i] = result[ri - 1 - i]; result[ri - 1 - i] = tmp; 2189 - } 2190 - result[ri] = 0; 2191 - *rlen = ri; 2192 - return result; 2193 - } 2194 - 2195 - static char *bigint_sub_abs(const char *a, size_t alen, const char *b, size_t blen, size_t *rlen) { 2196 - char *result = (char *)malloc(alen + 1); 2197 - if (!result) return NULL; 2198 - int borrow = 0; 2199 - size_t ri = 0; 2200 - for (size_t i = 0; i < alen; i++) { 2201 - int da = a[alen - 1 - i] - '0'; 2202 - int db = (i < blen) ? (b[blen - 1 - i] - '0') : 0; 2203 - int diff = da - db - borrow; 2204 - if (diff < 0) { diff += 10; borrow = 1; } else { borrow = 0; } 2205 - result[ri++] = (char)('0' + diff); 2206 - } 2207 - while (ri > 1 && result[ri - 1] == '0') ri--; 2208 - for (size_t i = 0; i < ri / 2; i++) { 2209 - char tmp = result[i]; result[i] = result[ri - 1 - i]; result[ri - 1 - i] = tmp; 2210 - } 2211 - result[ri] = 0; 2212 - *rlen = ri; 2213 - return result; 2214 - } 2215 - 2216 - static char *bigint_mul_abs(const char *a, size_t alen, const char *b, size_t blen, size_t *rlen) { 2217 - size_t reslen = alen + blen; 2218 - int *temp = (int *)calloc(reslen, sizeof(int)); 2219 - if (!temp) return NULL; 2220 - for (size_t i = 0; i < alen; i++) { 2221 - for (size_t j = 0; j < blen; j++) { 2222 - temp[i + j] += (a[alen - 1 - i] - '0') * (b[blen - 1 - j] - '0'); 2223 - } 2224 - } 2225 - for (size_t i = 0; i < reslen - 1; i++) { 2226 - temp[i + 1] += temp[i] / 10; 2227 - temp[i] %= 10; 2228 - } 2229 - size_t start = reslen - 1; 2230 - while (start > 0 && temp[start] == 0) start--; 2231 - char *result = (char *)malloc(start + 2); 2232 - if (!result) { free(temp); return NULL; } 2233 - for (size_t i = 0; i <= start; i++) result[i] = (char)('0' + temp[start - i]); 2234 - result[start + 1] = 0; 2235 - *rlen = start + 1; 2236 - free(temp); 2237 - return result; 2238 - } 2239 - 2240 - static char *bigint_div_abs(const char *a, size_t alen, const char *b, size_t blen, size_t *rlen, char **rem, size_t *remlen) { 2241 - if (blen == 1 && b[0] == '0') return NULL; 2242 - if (bigint_cmp_abs(a, alen, b, blen) < 0) { 2243 - char *result = (char *)malloc(2); result[0] = '0'; result[1] = 0; *rlen = 1; 2244 - if (rem) { *rem = (char *)malloc(alen + 1); memcpy(*rem, a, alen); (*rem)[alen] = 0; *remlen = alen; } 2245 - return result; 2246 - } 2247 - char *current = (char *)calloc(alen + 1, 1); 2248 - char *result = (char *)calloc(alen + 1, 1); 2249 - if (!current || !result) { free(current); free(result); return NULL; } 2250 - size_t curlen = 0, reslen = 0; 2251 - for (size_t i = 0; i < alen; i++) { 2252 - if (curlen == 1 && current[0] == '0') curlen = 0; 2253 - current[curlen++] = a[i]; current[curlen] = 0; 2254 - int count = 0; 2255 - while (bigint_cmp_abs(current, curlen, b, blen) >= 0) { 2256 - size_t sublen; 2257 - char *sub = bigint_sub_abs(current, curlen, b, blen, &sublen); 2258 - if (!sub) break; 2259 - memcpy(current, sub, sublen + 1); curlen = sublen; 2260 - free(sub); count++; 2261 - } 2262 - result[reslen++] = (char)('0' + count); 2263 - } 2264 - size_t start = 0; 2265 - while (start < reslen - 1 && result[start] == '0') start++; 2266 - memmove(result, result + start, reslen - start + 1); 2267 - *rlen = reslen - start; 2268 - if (rem) { *rem = current; *remlen = curlen; } else free(current); 2269 - return result; 2270 - } 2271 - 2272 - ant_value_t bigint_add(ant_t *js, ant_value_t a, ant_value_t b) { 2273 - bool aneg = bigint_IsNegative(js, a), bneg = bigint_IsNegative(js, b); 2274 - size_t alen, blen; 2275 - const char *ad = bigint_digits(js, a, &alen), *bd = bigint_digits(js, b, &blen); 2276 - char *result; size_t rlen; bool rneg; 2277 - if (aneg == bneg) { 2278 - result = bigint_add_abs(ad, alen, bd, blen, &rlen); rneg = aneg; 2279 - } else { 2280 - int cmp = bigint_cmp_abs(ad, alen, bd, blen); 2281 - if (cmp >= 0) { result = bigint_sub_abs(ad, alen, bd, blen, &rlen); rneg = aneg; } 2282 - else { result = bigint_sub_abs(bd, blen, ad, alen, &rlen); rneg = bneg; } 2283 - } 2284 - if (!result) return js_mkerr(js, "oom"); 2285 - if (rlen == 1 && result[0] == '0') rneg = false; 2286 - ant_value_t r = js_mkbigint(js, result, rlen, rneg); 2287 - free(result); 2288 - return r; 2289 - } 2290 - 2291 - ant_value_t bigint_sub(ant_t *js, ant_value_t a, ant_value_t b) { 2292 - bool aneg = bigint_IsNegative(js, a), bneg = bigint_IsNegative(js, b); 2293 - size_t alen, blen; 2294 - const char *ad = bigint_digits(js, a, &alen), *bd = bigint_digits(js, b, &blen); 2295 - char *result; size_t rlen; bool rneg; 2296 - if (aneg != bneg) { 2297 - result = bigint_add_abs(ad, alen, bd, blen, &rlen); rneg = aneg; 2298 - } else { 2299 - int cmp = bigint_cmp_abs(ad, alen, bd, blen); 2300 - if (cmp >= 0) { result = bigint_sub_abs(ad, alen, bd, blen, &rlen); rneg = aneg; } 2301 - else { result = bigint_sub_abs(bd, blen, ad, alen, &rlen); rneg = !aneg; } 2302 - } 2303 - if (!result) return js_mkerr(js, "oom"); 2304 - if (rlen == 1 && result[0] == '0') rneg = false; 2305 - ant_value_t r = js_mkbigint(js, result, rlen, rneg); 2306 - free(result); 2307 - return r; 2308 - } 2309 - 2310 - ant_value_t bigint_mul(ant_t *js, ant_value_t a, ant_value_t b) { 2311 - bool aneg = bigint_IsNegative(js, a), bneg = bigint_IsNegative(js, b); 2312 - size_t alen, blen; 2313 - const char *ad = bigint_digits(js, a, &alen), *bd = bigint_digits(js, b, &blen); 2314 - size_t rlen; 2315 - char *result = bigint_mul_abs(ad, alen, bd, blen, &rlen); 2316 - if (!result) return js_mkerr(js, "oom"); 2317 - bool rneg = (aneg != bneg) && !(rlen == 1 && result[0] == '0'); 2318 - ant_value_t r = js_mkbigint(js, result, rlen, rneg); 2319 - free(result); 2320 - return r; 2321 - } 2322 - 2323 - ant_value_t bigint_div(ant_t *js, ant_value_t a, ant_value_t b) { 2324 - bool aneg = bigint_IsNegative(js, a), bneg = bigint_IsNegative(js, b); 2325 - size_t alen, blen; 2326 - const char *ad = bigint_digits(js, a, &alen), *bd = bigint_digits(js, b, &blen); 2327 - if (blen == 1 && bd[0] == '0') return js_mkerr(js, "Division by zero"); 2328 - size_t rlen; 2329 - char *result = bigint_div_abs(ad, alen, bd, blen, &rlen, NULL, NULL); 2330 - if (!result) return js_mkerr(js, "oom"); 2331 - bool rneg = (aneg != bneg) && !(rlen == 1 && result[0] == '0'); 2332 - ant_value_t r = js_mkbigint(js, result, rlen, rneg); 2333 - free(result); 2334 - return r; 2335 - } 2336 - 2337 - ant_value_t bigint_mod(ant_t *js, ant_value_t a, ant_value_t b) { 2338 - bool aneg = bigint_IsNegative(js, a); 2339 - size_t alen, blen; 2340 - const char *ad = bigint_digits(js, a, &alen), *bd = bigint_digits(js, b, &blen); 2341 - if (blen == 1 && bd[0] == '0') return js_mkerr(js, "Division by zero"); 2342 - size_t rlen, remlen; char *rem; 2343 - char *result = bigint_div_abs(ad, alen, bd, blen, &rlen, &rem, &remlen); 2344 - if (!result) return js_mkerr(js, "oom"); 2345 - free(result); 2346 - bool rneg = aneg && !(remlen == 1 && rem[0] == '0'); 2347 - ant_value_t r = js_mkbigint(js, rem, remlen, rneg); 2348 - free(rem); 2349 - return r; 2350 - } 2351 - 2352 - ant_value_t bigint_neg(ant_t *js, ant_value_t a) { 2353 - size_t len; 2354 - const char *digits = bigint_digits(js, a, &len); 2355 - bool neg = bigint_IsNegative(js, a); 2356 - if (len == 1 && digits[0] == '0') return js_mkbigint(js, digits, len, false); 2357 - return js_mkbigint(js, digits, len, !neg); 2358 - } 2359 - 2360 - ant_value_t bigint_exp(ant_t *js, ant_value_t base, ant_value_t exp) { 2361 - if (bigint_IsNegative(js, exp)) return js_mkerr(js, "Exponent must be positive"); 2362 - size_t explen; 2363 - const char *expd = bigint_digits(js, exp, &explen); 2364 - if (explen == 1 && expd[0] == '0') return js_mkbigint(js, "1", 1, false); 2365 - ant_value_t result = js_mkbigint(js, "1", 1, false); 2366 - ant_value_t b = base; 2367 - ant_value_t e = exp; 2368 - ant_value_t two = js_mkbigint(js, "2", 1, false); 2369 - while (true) { 2370 - size_t elen; 2371 - const char *ed = bigint_digits(js, e, &elen); 2372 - if (elen == 1 && ed[0] == '0') break; 2373 - int last_digit = ed[elen - 1] - '0'; 2374 - if (last_digit % 2 == 1) { 2375 - result = bigint_mul(js, result, b); 2376 - if (is_err(result)) return result; 2377 - } 2378 - b = bigint_mul(js, b, b); 2379 - if (is_err(b)) return b; 2380 - e = bigint_div(js, e, two); 2381 - if (is_err(e)) return e; 2382 - } 2383 - return result; 2384 - } 2385 - 2386 - static inline ant_value_t bigint_pow2(ant_t *js, uint64_t bits) { 2387 - ant_value_t two = js_mkbigint(js, "2", 1, false); 2388 - if (is_err(two)) return two; 2389 - ant_value_t exp = bigint_from_u64(js, bits); 2390 - if (is_err(exp)) return exp; 2391 - return bigint_exp(js, two, exp); 2392 - } 2393 - 2394 - ant_value_t bigint_shift_left(ant_t *js, ant_value_t value, uint64_t shift) { 2395 - if (shift == 0) return value; 2396 - if (shift > 18446744073709551615ULL) return js_mkerr(js, "Shift count too large"); 2397 - 2398 - size_t digits_len; const char *digits = bigint_digits(js, value, &digits_len); 2399 - if (digits_len == 1 && digits[0] == '0') return js_mkbigint(js, "0", 1, false); 2400 - uint64_t u64 = 0; 2401 - if (!bigint_IsNegative(js, value) && shift < 64 && bigint_parse_u64(js, value, &u64)) { 2402 - if (u64 <= (UINT64_MAX >> shift)) return bigint_from_u64(js, u64 << shift); 2403 - } 2404 - 2405 - ant_value_t pow = bigint_pow2(js, shift); 2406 - if (is_err(pow)) return pow; 2407 - return bigint_mul(js, value, pow); 2408 - } 2409 - 2410 - ant_value_t bigint_shift_right(ant_t *js, ant_value_t value, uint64_t shift) { 2411 - if (shift == 0) return value; 2412 - if (shift > 18446744073709551615ULL) return js_mkerr(js, "Shift count too large"); 2413 - 2414 - size_t digits_len; const char *digits = bigint_digits(js, value, &digits_len); 2415 - if (digits_len == 1 && digits[0] == '0') return js_mkbigint(js, "0", 1, false); 2416 - uint64_t u64 = 0; 2417 - if (!bigint_IsNegative(js, value) && bigint_parse_u64(js, value, &u64)) { 2418 - if (shift >= 64) return js_mkbigint(js, "0", 1, false); 2419 - return bigint_from_u64(js, u64 >> shift); 2420 - } 2421 - 2422 - if (bigint_parse_abs_u64(js, value, &u64)) { 2423 - if (shift >= 64) return js_mkbigint( 2424 - js, bigint_IsNegative(js, value) ? "1" : "0", 1, 2425 - bigint_IsNegative(js, value) 2426 - ); 2427 - uint64_t shifted = u64 >> shift; 2428 - if (bigint_IsNegative(js, value)) { 2429 - if ((u64 & ((1ULL << shift) - 1)) != 0) shifted += 1; 2430 - ant_value_t pos = bigint_from_u64(js, shifted); 2431 - if (is_err(pos)) return pos; 2432 - return bigint_neg(js, pos); 2433 - } 2434 - return bigint_from_u64(js, shifted); 2435 - } 2436 - 2437 - ant_value_t pow = bigint_pow2(js, shift); 2438 - if (is_err(pow)) return pow; 2439 - return bigint_div(js, value, pow); 2440 - } 2441 - 2442 - ant_value_t bigint_shift_right_logical(ant_t *js, ant_value_t value, uint64_t shift) { 2443 - return js_mkerr_typed(js, JS_ERR_TYPE, "BigInts have no unsigned right shift, use >> instead"); 2444 - } 2445 - 2446 - int bigint_compare(ant_t *js, ant_value_t a, ant_value_t b) { 2447 - bool aneg = bigint_IsNegative(js, a), bneg = bigint_IsNegative(js, b); 2448 - size_t alen, blen; 2449 - const char *ad = bigint_digits(js, a, &alen), *bd = bigint_digits(js, b, &blen); 2450 - if (aneg && !bneg) return -1; 2451 - if (!aneg && bneg) return 1; 2452 - int cmp = bigint_cmp_abs(ad, alen, bd, blen); 2453 - return aneg ? -cmp : cmp; 2454 - } 2455 - 2456 - static bool bigint_is_zero(ant_t *js, ant_value_t v) { 2457 - size_t len; 2458 - const char *digits = bigint_digits(js, v, &len); 2459 - return len == 1 && digits[0] == '0'; 2460 - } 2461 - 2462 - static size_t strbigint(ant_t *js, ant_value_t value, char *buf, size_t len) { 2463 - bool neg = bigint_IsNegative(js, value); 2464 - size_t dlen; 2465 - const char *digits = bigint_digits(js, value, &dlen); 2466 - size_t n = 0; 2467 - if (neg) n += cpy(buf + n, REMAIN(n, len), "-", 1); 2468 - n += cpy(buf + n, REMAIN(n, len), digits, dlen); 2469 - return n; 2470 - } 2471 - 2472 - static ant_value_t builtin_BigInt(ant_t *js, ant_value_t *args, int nargs) { 2473 - if (vtype(js->new_target) != T_UNDEF) return js_mkerr_typed(js, JS_ERR_TYPE, "BigInt is not a constructor"); 2474 - if (nargs < 1) return js_mkbigint(js, "0", 1, false); 2475 - 2476 - ant_value_t arg = args[0]; 2477 - if (vtype(arg) == T_BIGINT) return arg; 2478 - if (vtype(arg) == T_NUM) { 2479 - double d = tod(arg); 2480 - if (!isfinite(d)) return js_mkerr(js, "Cannot convert Infinity or NaN to BigInt"); 2481 - if (d != trunc(d)) return js_mkerr(js, "Cannot convert non-integer to BigInt"); 2482 - bool neg = d < 0; 2483 - if (neg) d = -d; 2484 - char buf[64]; 2485 - snprintf(buf, sizeof(buf), "%.0f", d); 2486 - return js_mkbigint(js, buf, strlen(buf), neg); 2487 - } 2488 - if (vtype(arg) == T_STR) { 2489 - ant_offset_t slen, off = vstr(js, arg, &slen); 2490 - const char *str = (const char *)&js->mem[off]; 2491 - bool neg = false; 2492 - size_t i = 0; 2493 - if (slen > 0 && str[0] == '-') { neg = true; i++; } 2494 - else if (slen > 0 && str[0] == '+') { i++; } 2495 - while (i < slen && str[i] == '0') i++; 2496 - if (i >= slen) return js_mkbigint(js, "0", 1, false); 2497 - for (size_t j = i; j < slen; j++) { 2498 - if (!is_digit(str[j])) return js_mkerr(js, "Cannot convert string to BigInt"); 2499 - } 2500 - return js_mkbigint(js, str + i, slen - i, neg); 2501 - } 2502 - if (vtype(arg) == T_BOOL) { 2503 - return js_mkbigint(js, vdata(arg) ? "1" : "0", 1, false); 2504 - } 2505 - return js_mkerr(js, "Cannot convert to BigInt"); 2506 - } 2507 - 2508 - static ant_value_t bigint_to_u64(ant_t *js, ant_value_t value, uint64_t *out) { 2509 - if (!bigint_parse_u64(js, value, out)) { 2510 - return js_mkerr_typed(js, JS_ERR_RANGE, "Invalid bits"); 2511 - } 2512 - return js_mkundef(); 2513 - } 2514 - 2515 - ant_value_t bigint_asint_bits(ant_t *js, ant_value_t arg, uint64_t *bits_out) { 2516 - if (vtype(arg) == T_BIGINT) { 2517 - return bigint_to_u64(js, arg, bits_out); 2518 - } 2519 - double bits = js_to_number(js, arg); 2520 - if (!isfinite(bits) || bits < 0 || bits != floor(bits)) { 2521 - return js_mkerr_typed(js, JS_ERR_RANGE, "Invalid bits"); 2522 - } 2523 - if (bits > 18446744073709551615.0) { 2524 - return js_mkerr_typed(js, JS_ERR_RANGE, "Invalid bits"); 2525 - } 2526 - *bits_out = (uint64_t)bits; 2527 - return js_mkundef(); 2528 - } 2529 - 2530 - static ant_value_t builtin_BigInt_asIntN(ant_t *js, ant_value_t *args, int nargs) { 2531 - if (nargs < 2) return js_mkerr(js, "BigInt.asIntN requires 2 arguments"); 2532 - uint64_t bits = 0; 2533 - ant_value_t err = bigint_asint_bits(js, args[0], &bits); 2534 - if (is_err(err)) return err; 2535 - if (vtype(args[1]) != T_BIGINT) { 2536 - return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert to BigInt"); 2537 - } 2538 - if (bits == 0) return js_mkbigint(js, "0", 1, false); 2539 - 2540 - ant_value_t mod = bigint_pow2(js, bits); 2541 - if (is_err(mod)) return mod; 2542 - ant_value_t res = bigint_mod(js, args[1], mod); 2543 - if (is_err(res)) return res; 2544 - if (bigint_IsNegative(js, res)) { 2545 - ant_value_t adj = bigint_add(js, res, mod); 2546 - if (is_err(adj)) return adj; 2547 - res = adj; 2548 - } 2549 - 2550 - ant_value_t threshold = bigint_pow2(js, bits - 1); 2551 - if (is_err(threshold)) return threshold; 2552 - if (bigint_compare(js, res, threshold) >= 0) { 2553 - ant_value_t adj = bigint_sub(js, res, mod); 2554 - if (is_err(adj)) return adj; 2555 - res = adj; 2556 - } 2557 - return res; 2558 - } 2559 - 2560 - static ant_value_t builtin_BigInt_asUintN(ant_t *js, ant_value_t *args, int nargs) { 2561 - if (nargs < 2) return js_mkerr(js, "BigInt.asUintN requires 2 arguments"); 2562 - uint64_t bits = 0; 2563 - ant_value_t err = bigint_asint_bits(js, args[0], &bits); 2564 - if (is_err(err)) return err; 2565 - if (vtype(args[1]) != T_BIGINT) { 2566 - return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert to BigInt"); 2567 - } 2568 - if (bits == 0) return js_mkbigint(js, "0", 1, false); 2569 - 2570 - ant_value_t mod = bigint_pow2(js, bits); 2571 - if (is_err(mod)) return mod; 2572 - ant_value_t res = bigint_mod(js, args[1], mod); 2573 - if (is_err(res)) return res; 2574 - if (bigint_IsNegative(js, res)) { 2575 - ant_value_t adj = bigint_add(js, res, mod); 2576 - if (is_err(adj)) return adj; 2577 - res = adj; 2578 - } 2579 - return res; 2580 - } 2581 - 2582 - static ant_value_t builtin_bigint_toString(ant_t *js, ant_value_t *args, int nargs) { 2583 - ant_value_t val = js->this_val; 2584 - if (vtype(val) != T_BIGINT) return js_mkerr(js, "toString called on non-BigInt"); 2585 - 2586 - int radix = 10; 2587 - if (nargs >= 1 && vtype(args[0]) == T_NUM) { 2588 - radix = (int)tod(args[0]); 2589 - if (radix < 2 || radix > 36) return js_mkerr(js, "radix must be between 2 and 36"); 2590 - } 2591 - 2592 - bool neg = bigint_IsNegative(js, val); 2593 - size_t dlen; const char *digits = bigint_digits(js, val, &dlen); 2594 - 2595 - if (radix == 10) { 2596 - size_t buflen = dlen + 2; 2597 - char *buf = (char *)ant_calloc(buflen); 2598 - if (!buf) return js_mkerr(js, "oom"); 2599 - size_t n = 0; if (neg) buf[n++] = '-'; 2600 - memcpy(buf + n, digits, dlen); n += dlen; 2601 - ant_value_t ret = js_mkstr(js, buf, n); free(buf); 2602 - return ret; 2603 - } 2604 - 2605 - const uint32_t base = 1000000000U; 2606 - size_t result_cap = dlen * 4 + 16; 2607 - 2608 - char *result = (char *)ant_calloc(result_cap); 2609 - if (!result) return js_mkerr(js, "oom"); 2610 - 2611 - size_t rpos = result_cap - 1; 2612 - result[rpos] = '\0'; 2613 - 2614 - size_t limb_cap = (dlen + 8) / 9 + 1; 2615 - uint32_t *limbs = (uint32_t *)ant_calloc(limb_cap * sizeof(uint32_t)); 2616 - if (!limbs) { free(result); return js_mkerr(js, "oom"); } 2617 - size_t limb_len = 1; 2618 - 2619 - for (size_t i = 0; i < dlen; i++) { 2620 - uint64_t carry = (uint64_t)(digits[i] - '0'); 2621 - for (size_t j = 0; j < limb_len; j++) { 2622 - uint64_t cur = (uint64_t)limbs[j] * 10 + carry; 2623 - limbs[j] = (uint32_t)(cur % base); 2624 - carry = cur / base; 2625 - } 2626 - if (carry != 0) { 2627 - if (limb_len == limb_cap) { 2628 - size_t new_cap = limb_cap * 2; 2629 - uint32_t *new_limbs = (uint32_t *)ant_realloc(limbs, new_cap * sizeof(uint32_t)); 2630 - if (!new_limbs) { free(limbs); free(result); return js_mkerr(js, "oom"); } 2631 - limbs = new_limbs; 2632 - limb_cap = new_cap; 2633 - } 2634 - limbs[limb_len++] = (uint32_t)carry; 2635 - } 2636 - } 2637 - 2638 - static const char digit_map[] = "0123456789abcdefghijklmnopqrstuvwxyz"; 2639 - while (limb_len > 0 && !(limb_len == 1 && limbs[0] == 0)) { 2640 - uint64_t remainder = 0; 2641 - for (size_t i = limb_len; i-- > 0;) { 2642 - uint64_t cur = (uint64_t)limbs[i] + remainder * base; 2643 - limbs[i] = (uint32_t)(cur / (uint64_t)radix); 2644 - remainder = cur % (uint64_t)radix; 2645 - } 2646 - 2647 - while (limb_len > 0 && limbs[limb_len - 1] == 0) limb_len--; 2648 - if (rpos == 0) { 2649 - size_t new_cap = result_cap * 2; 2650 - char *new_result = (char *)ant_calloc(new_cap); 2651 - if (!new_result) { free(limbs); free(result); return js_mkerr(js, "oom"); } 2652 - 2653 - size_t used = result_cap - rpos; 2654 - memcpy(new_result + new_cap - used, result + rpos, used); 2655 - free(result); 2656 - 2657 - result = new_result; 2658 - rpos = new_cap - used; 2659 - result_cap = new_cap; 2660 - } 2661 - result[--rpos] = digit_map[remainder]; 2662 - } 2663 - 2664 - free(limbs); 2665 - 2666 - if (rpos == result_cap - 1) result[--rpos] = '0'; 2667 - if (neg) result[--rpos] = '-'; 2668 - 2669 - ant_value_t ret = js_mkstr(js, result + rpos, result_cap - 1 - rpos); 2670 - free(result); return ret; 2671 - } 2672 2107 2673 2108 ant_value_t mkobj(ant_t *js, ant_offset_t parent) { 2674 2109 ant_offset_t buf[2] = { parent, 0 }; ··· 5205 4640 return this_val; 5206 4641 } 5207 4642 5208 - static ant_value_t builtin_Math_abs(ant_t *js, ant_value_t *args, int nargs) { 5209 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5210 - if (isnan(x)) return tov(JS_NAN); 5211 - return tov(fabs(x)); 5212 - } 5213 - 5214 - static ant_value_t builtin_Math_acos(ant_t *js, ant_value_t *args, int nargs) { 5215 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5216 - if (isnan(x)) return tov(JS_NAN); 5217 - return tov(acos(x)); 5218 - } 5219 - 5220 - static ant_value_t builtin_Math_acosh(ant_t *js, ant_value_t *args, int nargs) { 5221 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5222 - if (isnan(x)) return tov(JS_NAN); 5223 - return tov(acosh(x)); 5224 - } 5225 - 5226 - static ant_value_t builtin_Math_asin(ant_t *js, ant_value_t *args, int nargs) { 5227 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5228 - if (isnan(x)) return tov(JS_NAN); 5229 - return tov(asin(x)); 5230 - } 5231 - 5232 - static ant_value_t builtin_Math_asinh(ant_t *js, ant_value_t *args, int nargs) { 5233 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5234 - if (isnan(x)) return tov(JS_NAN); 5235 - return tov(asinh(x)); 5236 - } 5237 - 5238 - static ant_value_t builtin_Math_atan(ant_t *js, ant_value_t *args, int nargs) { 5239 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5240 - if (isnan(x)) return tov(JS_NAN); 5241 - return tov(atan(x)); 5242 - } 5243 - 5244 - static ant_value_t builtin_Math_atanh(ant_t *js, ant_value_t *args, int nargs) { 5245 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5246 - if (isnan(x)) return tov(JS_NAN); 5247 - return tov(atanh(x)); 5248 - } 5249 - 5250 - static ant_value_t builtin_Math_atan2(ant_t *js, ant_value_t *args, int nargs) { 5251 - double y = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5252 - double x = (nargs < 2) ? JS_NAN : js_to_number(js, args[1]); 5253 - if (isnan(y) || isnan(x)) return tov(JS_NAN); 5254 - return tov(atan2(y, x)); 5255 - } 5256 - 5257 - static ant_value_t builtin_Math_cbrt(ant_t *js, ant_value_t *args, int nargs) { 5258 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5259 - if (isnan(x)) return tov(JS_NAN); 5260 - return tov(cbrt(x)); 5261 - } 5262 - 5263 - static ant_value_t builtin_Math_ceil(ant_t *js, ant_value_t *args, int nargs) { 5264 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5265 - if (isnan(x)) return tov(JS_NAN); 5266 - return tov(ceil(x)); 5267 - } 5268 - 5269 - static ant_value_t builtin_Math_clz32(ant_t *js, ant_value_t *args, int nargs) { 5270 - if (nargs < 1) return tov(32); 5271 - double x = js_to_number(js, args[0]); 5272 - if (isnan(x) || isinf(x)) return tov(32); 5273 - uint32_t n = (uint32_t) x; 5274 - if (n == 0) return tov(32); 5275 - int count = 0; 5276 - while ((n & 0x80000000U) == 0) { count++; n <<= 1; } 5277 - return tov((double) count); 5278 - } 5279 - 5280 - static ant_value_t builtin_Math_cos(ant_t *js, ant_value_t *args, int nargs) { 5281 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5282 - if (isnan(x)) return tov(JS_NAN); 5283 - return tov(cos(x)); 5284 - } 5285 - 5286 - static ant_value_t builtin_Math_cosh(ant_t *js, ant_value_t *args, int nargs) { 5287 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5288 - if (isnan(x)) return tov(JS_NAN); 5289 - return tov(cosh(x)); 5290 - } 5291 - 5292 - static ant_value_t builtin_Math_exp(ant_t *js, ant_value_t *args, int nargs) { 5293 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5294 - if (isnan(x)) return tov(JS_NAN); 5295 - return tov(exp(x)); 5296 - } 5297 - 5298 - static ant_value_t builtin_Math_expm1(ant_t *js, ant_value_t *args, int nargs) { 5299 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5300 - if (isnan(x)) return tov(JS_NAN); 5301 - return tov(expm1(x)); 5302 - } 5303 - 5304 - static ant_value_t builtin_Math_floor(ant_t *js, ant_value_t *args, int nargs) { 5305 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5306 - if (isnan(x)) return tov(JS_NAN); 5307 - return tov(floor(x)); 5308 - } 5309 - 5310 - static ant_value_t builtin_Math_fround(ant_t *js, ant_value_t *args, int nargs) { 5311 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5312 - if (isnan(x)) return tov(JS_NAN); 5313 - return tov((double)(float)x); 5314 - } 5315 - 5316 - static ant_value_t builtin_Math_hypot(ant_t *js, ant_value_t *args, int nargs) { 5317 - if (nargs == 0) return tov(0.0); 5318 - double sum = 0.0; 5319 - for (int i = 0; i < nargs; i++) { 5320 - double v = js_to_number(js, args[i]); 5321 - if (isnan(v)) return tov(JS_NAN); 5322 - sum += v * v; 5323 - } 5324 - return tov(sqrt(sum)); 5325 - } 5326 - 5327 - static int32_t toInt32(double d) { 5328 - if (isnan(d) || isinf(d) || d == 0) return 0; 5329 - double int_val = trunc(d); 5330 - double two32 = (double)(1ULL << 32); 5331 - double two31 = (double)(1ULL << 31); 5332 - double mod_val = fmod(int_val, two32); 5333 - if (mod_val < 0) mod_val += two32; 5334 - if (mod_val >= two31) mod_val -= two32; 5335 - return (int32_t)mod_val; 5336 - } 5337 - 5338 - static ant_value_t builtin_Math_imul(ant_t *js, ant_value_t *args, int nargs) { 5339 - if (nargs < 2) return tov(0); 5340 - int32_t a = toInt32(js_to_number(js, args[0])); 5341 - int32_t b = toInt32(js_to_number(js, args[1])); 5342 - return tov((double)((int32_t)((uint32_t)a * (uint32_t)b))); 5343 - } 5344 - 5345 - static ant_value_t builtin_Math_log(ant_t *js, ant_value_t *args, int nargs) { 5346 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5347 - if (isnan(x)) return tov(JS_NAN); 5348 - return tov(log(x)); 5349 - } 5350 - 5351 - static ant_value_t builtin_Math_log1p(ant_t *js, ant_value_t *args, int nargs) { 5352 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5353 - if (isnan(x)) return tov(JS_NAN); 5354 - return tov(log1p(x)); 5355 - } 5356 - 5357 - static ant_value_t builtin_Math_log10(ant_t *js, ant_value_t *args, int nargs) { 5358 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5359 - if (isnan(x)) return tov(JS_NAN); 5360 - return tov(log10(x)); 5361 - } 5362 - 5363 - static ant_value_t builtin_Math_log2(ant_t *js, ant_value_t *args, int nargs) { 5364 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5365 - if (isnan(x)) return tov(JS_NAN); 5366 - return tov(log2(x)); 5367 - } 5368 - 5369 - static ant_value_t builtin_Math_max(ant_t *js, ant_value_t *args, int nargs) { 5370 - if (nargs == 0) return tov(JS_NEG_INF); 5371 - double max_val = JS_NEG_INF; 5372 - for (int i = 0; i < nargs; i++) { 5373 - double v = js_to_number(js, args[i]); 5374 - if (isnan(v)) return tov(JS_NAN); 5375 - if (v > max_val) max_val = v; 5376 - } 5377 - return tov(max_val); 5378 - } 5379 - 5380 - static ant_value_t builtin_Math_min(ant_t *js, ant_value_t *args, int nargs) { 5381 - if (nargs == 0) return tov(JS_INF); 5382 - double min_val = JS_INF; 5383 - for (int i = 0; i < nargs; i++) { 5384 - double v = js_to_number(js, args[i]); 5385 - if (isnan(v)) return tov(JS_NAN); 5386 - if (v < min_val) min_val = v; 5387 - } 5388 - return tov(min_val); 5389 - } 5390 - 5391 - static ant_value_t builtin_Math_pow(ant_t *js, ant_value_t *args, int nargs) { 5392 - double base = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5393 - double exp = (nargs < 2) ? JS_NAN : js_to_number(js, args[1]); 5394 - if (isnan(base) || isnan(exp)) return tov(JS_NAN); 5395 - return tov(pow(base, exp)); 5396 - } 5397 - 5398 - static bool random_seeded = false; 5399 - 5400 - static ant_value_t builtin_Math_random(ant_t *js, ant_value_t *args, int nargs) { 5401 - if (!random_seeded) { 5402 - srand((unsigned int) time(NULL)); 5403 - random_seeded = true; 5404 - } 5405 - return tov((double) rand() / ((double) RAND_MAX + 1.0)); 5406 - } 5407 - 5408 - static ant_value_t builtin_Math_round(ant_t *js, ant_value_t *args, int nargs) { 5409 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5410 - if (isnan(x) || isinf(x)) return tov(x); 5411 - return tov(floor(x + 0.5)); 5412 - } 5413 - 5414 - static ant_value_t builtin_Math_sign(ant_t *js, ant_value_t *args, int nargs) { 5415 - double v = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5416 - if (isnan(v)) return tov(JS_NAN); 5417 - if (v > 0) return tov(1.0); 5418 - if (v < 0) return tov(-1.0); 5419 - return tov(v); 5420 - } 5421 - 5422 - static ant_value_t builtin_Math_sin(ant_t *js, ant_value_t *args, int nargs) { 5423 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5424 - if (isnan(x)) return tov(JS_NAN); 5425 - return tov(sin(x)); 5426 - } 5427 - 5428 - static ant_value_t builtin_Math_sinh(ant_t *js, ant_value_t *args, int nargs) { 5429 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5430 - if (isnan(x)) return tov(JS_NAN); 5431 - return tov(sinh(x)); 5432 - } 5433 - 5434 - static ant_value_t builtin_Math_sqrt(ant_t *js, ant_value_t *args, int nargs) { 5435 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5436 - if (isnan(x)) return tov(JS_NAN); 5437 - return tov(sqrt(x)); 5438 - } 5439 - 5440 - static ant_value_t builtin_Math_tan(ant_t *js, ant_value_t *args, int nargs) { 5441 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5442 - if (isnan(x)) return tov(JS_NAN); 5443 - return tov(tan(x)); 5444 - } 5445 - 5446 - static ant_value_t builtin_Math_tanh(ant_t *js, ant_value_t *args, int nargs) { 5447 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5448 - if (isnan(x)) return tov(JS_NAN); 5449 - return tov(tanh(x)); 5450 - } 5451 - 5452 - static ant_value_t builtin_Math_trunc(ant_t *js, ant_value_t *args, int nargs) { 5453 - double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 5454 - if (isnan(x)) return tov(JS_NAN); 5455 - return tov(trunc(x)); 5456 - } 5457 4643 5458 4644 typedef ant_value_t (*dynamic_kv_mapper_fn)( 5459 4645 ant_t *js, ··· 12029 11215 js_setprop(js, boolean_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_boolean_valueOf)); 12030 11216 js_setprop(js, boolean_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_boolean_toString)); 12031 11217 12032 - ant_value_t bigint_proto = js_mkobj(js); 12033 - set_proto(js, bigint_proto, object_proto); 12034 - js_setprop(js, bigint_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_bigint_toString)); 12035 - 12036 11218 ant_value_t error_proto = js_mkobj(js); 12037 11219 set_proto(js, error_proto, object_proto); 12038 11220 js_setprop(js, error_proto, ANT_STRING("name"), ANT_STRING("Error")); ··· 12229 11411 js_setprop(js, p_ctor_obj, ANT_STRING("name"), ANT_STRING("Promise")); 12230 11412 js_setprop(js, glob, js_mkstr(js, "Promise", 7), js_obj_to_func(p_ctor_obj)); 12231 11413 12232 - ant_value_t bigint_ctor_obj = mkobj(js, 0); 12233 - set_proto(js, bigint_ctor_obj, function_proto); 12234 - set_slot(js, bigint_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_BigInt)); 12235 - js_setprop(js, bigint_ctor_obj, js_mkstr(js, "asIntN", 6), js_mkfun(builtin_BigInt_asIntN)); 12236 - js_setprop(js, bigint_ctor_obj, js_mkstr(js, "asUintN", 7), js_mkfun(builtin_BigInt_asUintN)); 12237 - js_setprop_nonconfigurable(js, bigint_ctor_obj, "prototype", 9, bigint_proto); 12238 - js_setprop(js, bigint_ctor_obj, ANT_STRING("name"), ANT_STRING("BigInt")); 12239 - js_setprop(js, glob, js_mkstr(js, "BigInt", 6), js_obj_to_func(bigint_ctor_obj)); 12240 - 12241 11414 js_setprop(js, glob, js_mkstr(js, "parseInt", 8), js_mkfun(builtin_parseInt)); 12242 11415 js_setprop(js, glob, js_mkstr(js, "parseFloat", 10), js_mkfun(builtin_parseFloat)); 12243 11416 js_setprop(js, glob, js_mkstr(js, "eval", 4), js_mkfun(builtin_eval)); ··· 12251 11424 js_set_descriptor(js, glob, "Infinity", 8, 0); 12252 11425 js_setprop(js, glob, js_mkstr(js, "undefined", 9), js_mkundef()); 12253 11426 js_set_descriptor(js, glob, "undefined", 9, 0); 12254 - 12255 - ant_value_t math_obj = mkobj(js, 0); 12256 - set_proto(js, math_obj, object_proto); 12257 - js_setprop(js, math_obj, js_mkstr(js, "E", 1), tov(M_E)); 12258 - js_setprop(js, math_obj, js_mkstr(js, "LN10", 4), tov(M_LN10)); 12259 - js_setprop(js, math_obj, js_mkstr(js, "LN2", 3), tov(M_LN2)); 12260 - js_setprop(js, math_obj, js_mkstr(js, "LOG10E", 6), tov(M_LOG10E)); 12261 - js_setprop(js, math_obj, js_mkstr(js, "LOG2E", 5), tov(M_LOG2E)); 12262 - js_setprop(js, math_obj, js_mkstr(js, "PI", 2), tov(M_PI)); 12263 - js_setprop(js, math_obj, js_mkstr(js, "SQRT1_2", 7), tov(M_SQRT1_2)); 12264 - js_setprop(js, math_obj, js_mkstr(js, "SQRT2", 5), tov(M_SQRT2)); 12265 - js_setprop(js, math_obj, js_mkstr(js, "abs", 3), js_mkfun(builtin_Math_abs)); 12266 - js_setprop(js, math_obj, js_mkstr(js, "acos", 4), js_mkfun(builtin_Math_acos)); 12267 - js_setprop(js, math_obj, js_mkstr(js, "acosh", 5), js_mkfun(builtin_Math_acosh)); 12268 - js_setprop(js, math_obj, js_mkstr(js, "asin", 4), js_mkfun(builtin_Math_asin)); 12269 - js_setprop(js, math_obj, js_mkstr(js, "asinh", 5), js_mkfun(builtin_Math_asinh)); 12270 - js_setprop(js, math_obj, js_mkstr(js, "atan", 4), js_mkfun(builtin_Math_atan)); 12271 - js_setprop(js, math_obj, js_mkstr(js, "atanh", 5), js_mkfun(builtin_Math_atanh)); 12272 - js_setprop(js, math_obj, js_mkstr(js, "atan2", 5), js_mkfun(builtin_Math_atan2)); 12273 - js_setprop(js, math_obj, js_mkstr(js, "cbrt", 4), js_mkfun(builtin_Math_cbrt)); 12274 - js_setprop(js, math_obj, js_mkstr(js, "ceil", 4), js_mkfun(builtin_Math_ceil)); 12275 - js_setprop(js, math_obj, js_mkstr(js, "clz32", 5), js_mkfun(builtin_Math_clz32)); 12276 - js_setprop(js, math_obj, js_mkstr(js, "cos", 3), js_mkfun(builtin_Math_cos)); 12277 - js_setprop(js, math_obj, js_mkstr(js, "cosh", 4), js_mkfun(builtin_Math_cosh)); 12278 - js_setprop(js, math_obj, js_mkstr(js, "exp", 3), js_mkfun(builtin_Math_exp)); 12279 - js_setprop(js, math_obj, js_mkstr(js, "expm1", 5), js_mkfun(builtin_Math_expm1)); 12280 - js_setprop(js, math_obj, js_mkstr(js, "floor", 5), js_mkfun(builtin_Math_floor)); 12281 - js_setprop(js, math_obj, js_mkstr(js, "fround", 6), js_mkfun(builtin_Math_fround)); 12282 - js_setprop(js, math_obj, js_mkstr(js, "hypot", 5), js_mkfun(builtin_Math_hypot)); 12283 - js_setprop(js, math_obj, js_mkstr(js, "imul", 4), js_mkfun(builtin_Math_imul)); 12284 - js_setprop(js, math_obj, js_mkstr(js, "log", 3), js_mkfun(builtin_Math_log)); 12285 - js_setprop(js, math_obj, js_mkstr(js, "log1p", 5), js_mkfun(builtin_Math_log1p)); 12286 - js_setprop(js, math_obj, js_mkstr(js, "log10", 5), js_mkfun(builtin_Math_log10)); 12287 - js_setprop(js, math_obj, js_mkstr(js, "log2", 4), js_mkfun(builtin_Math_log2)); 12288 - js_setprop(js, math_obj, js_mkstr(js, "max", 3), js_mkfun(builtin_Math_max)); 12289 - js_setprop(js, math_obj, js_mkstr(js, "min", 3), js_mkfun(builtin_Math_min)); 12290 - js_setprop(js, math_obj, js_mkstr(js, "pow", 3), js_mkfun(builtin_Math_pow)); 12291 - js_setprop(js, math_obj, js_mkstr(js, "random", 6), js_mkfun(builtin_Math_random)); 12292 - js_setprop(js, math_obj, js_mkstr(js, "round", 5), js_mkfun(builtin_Math_round)); 12293 - js_setprop(js, math_obj, js_mkstr(js, "sign", 4), js_mkfun(builtin_Math_sign)); 12294 - js_setprop(js, math_obj, js_mkstr(js, "sin", 3), js_mkfun(builtin_Math_sin)); 12295 - js_setprop(js, math_obj, js_mkstr(js, "sinh", 4), js_mkfun(builtin_Math_sinh)); 12296 - js_setprop(js, math_obj, js_mkstr(js, "sqrt", 4), js_mkfun(builtin_Math_sqrt)); 12297 - js_setprop(js, math_obj, js_mkstr(js, "tan", 3), js_mkfun(builtin_Math_tan)); 12298 - js_setprop(js, math_obj, js_mkstr(js, "tanh", 4), js_mkfun(builtin_Math_tanh)); 12299 - js_setprop(js, math_obj, js_mkstr(js, "trunc", 5), js_mkfun(builtin_Math_trunc)); 12300 - js_setprop(js, glob, js_mkstr(js, "Math", 4), math_obj); 12301 11427 12302 11428 ant_value_t import_obj = mkobj(js, 0); 12303 11429 set_proto(js, import_obj, function_proto);
+4
src/main.c
··· 52 52 #include "modules/reflect.h" 53 53 #include "modules/symbol.h" 54 54 #include "modules/date.h" 55 + #include "modules/math.h" 56 + #include "modules/bigint.h" 55 57 #include "modules/regex.h" 56 58 #include "modules/textcodec.h" 57 59 #include "modules/sessionstorage.h" ··· 568 570 proc_argv = build_process_argv(argc, argv, module_file, script_tail); 569 571 ant_runtime_init(js, proc_argv.argc, proc_argv.argv, localstorage_file); 570 572 573 + init_math_module(); 574 + init_bigint_module(); 571 575 init_symbol_module(); 572 576 init_date_module(); 573 577 init_regex_module();
+779
src/modules/bigint.c
··· 1 + #include <stdlib.h> 2 + #include <string.h> 3 + 4 + #include "ant.h" 5 + #include "internal.h" 6 + #include "errors.h" 7 + #include "arena.h" 8 + #include "runtime.h" 9 + 10 + static inline bool is_decimal_digit(char c) { 11 + return c >= '0' && c <= '9'; 12 + } 13 + 14 + bool bigint_is_negative(ant_t *js, ant_value_t v) { 15 + ant_offset_t ofs = (ant_offset_t)vdata(v); 16 + return js->mem[ofs + sizeof(ant_offset_t)] == 1; 17 + } 18 + 19 + size_t bigint_digits_len(ant_t *js, ant_value_t v) { 20 + ant_offset_t ofs = (ant_offset_t)vdata(v); 21 + ant_offset_t header = loadoff(js, ofs); 22 + return (size_t)((header >> 4) - 2); 23 + } 24 + 25 + static const char *bigint_digits(ant_t *js, ant_value_t v, size_t *len) { 26 + ant_offset_t ofs = (ant_offset_t)vdata(v); 27 + size_t total = bigint_digits_len(js, v); 28 + if (len) *len = total; 29 + return (const char *)&js->mem[ofs + sizeof(ant_offset_t) + 1]; 30 + } 31 + 32 + static ant_value_t bigint_from_u64(ant_t *js, uint64_t value) { 33 + char buf[32]; 34 + size_t len = uint_to_str(buf, sizeof(buf), value); 35 + return js_mkbigint(js, buf, len, false); 36 + } 37 + 38 + static bool bigint_parse_abs_u64(ant_t *js, ant_value_t value, uint64_t *out) { 39 + size_t len = 0; 40 + const char *digits = bigint_digits(js, value, &len); 41 + uint64_t acc = 0; 42 + 43 + for (size_t i = 0; i < len; i++) { 44 + char c = digits[i]; 45 + if (!is_decimal_digit(c)) return false; 46 + uint64_t digit = (uint64_t)(c - '0'); 47 + if (acc > UINT64_MAX / 10 || (acc == UINT64_MAX / 10 && digit > (UINT64_MAX % 10))) { 48 + return false; 49 + } 50 + acc = acc * 10 + digit; 51 + } 52 + 53 + *out = acc; 54 + return true; 55 + } 56 + 57 + static bool bigint_parse_u64(ant_t *js, ant_value_t value, uint64_t *out) { 58 + if (bigint_is_negative(js, value)) return false; 59 + return bigint_parse_abs_u64(js, value, out); 60 + } 61 + 62 + ant_value_t js_mkbigint(ant_t *js, const char *digits, size_t len, bool negative) { 63 + size_t total = len + 2; 64 + ant_offset_t ofs = js_alloc(js, total + sizeof(ant_offset_t)); 65 + if (ofs == (ant_offset_t)~0) return js_mkerr(js, "oom"); 66 + 67 + ant_offset_t header = (ant_offset_t)(total << 4); 68 + memcpy(&js->mem[ofs], &header, sizeof(header)); 69 + js->mem[ofs + sizeof(header)] = negative ? 1 : 0; 70 + if (digits) memcpy(&js->mem[ofs + sizeof(header) + 1], digits, len); 71 + js->mem[ofs + sizeof(header) + 1 + len] = 0; 72 + return mkval(T_BIGINT, ofs); 73 + } 74 + 75 + static int bigint_cmp_abs(const char *a, size_t alen, const char *b, size_t blen) { 76 + while (alen > 1 && a[0] == '0') { a++; alen--; } 77 + while (blen > 1 && b[0] == '0') { b++; blen--; } 78 + if (alen != blen) return alen > blen ? 1 : -1; 79 + for (size_t i = 0; i < alen; i++) { 80 + if (a[i] != b[i]) return a[i] > b[i] ? 1 : -1; 81 + } 82 + return 0; 83 + } 84 + 85 + static char *bigint_add_abs(const char *a, size_t alen, const char *b, size_t blen, size_t *rlen) { 86 + size_t maxlen = (alen > blen ? alen : blen) + 1; 87 + char *result = (char *)malloc(maxlen + 1); 88 + if (!result) return NULL; 89 + 90 + int carry = 0; 91 + size_t ri = 0; 92 + for (size_t i = 0; i < maxlen; i++) { 93 + int da = (i < alen) ? (a[alen - 1 - i] - '0') : 0; 94 + int db = (i < blen) ? (b[blen - 1 - i] - '0') : 0; 95 + int sum = da + db + carry; 96 + carry = sum / 10; 97 + result[ri++] = (char)('0' + (sum % 10)); 98 + } 99 + 100 + while (ri > 1 && result[ri - 1] == '0') ri--; 101 + for (size_t i = 0; i < ri / 2; i++) { 102 + char tmp = result[i]; 103 + result[i] = result[ri - 1 - i]; 104 + result[ri - 1 - i] = tmp; 105 + } 106 + 107 + result[ri] = 0; 108 + *rlen = ri; 109 + return result; 110 + } 111 + 112 + static char *bigint_sub_abs(const char *a, size_t alen, const char *b, size_t blen, size_t *rlen) { 113 + char *result = (char *)malloc(alen + 1); 114 + if (!result) return NULL; 115 + 116 + int borrow = 0; 117 + size_t ri = 0; 118 + for (size_t i = 0; i < alen; i++) { 119 + int da = a[alen - 1 - i] - '0'; 120 + int db = (i < blen) ? (b[blen - 1 - i] - '0') : 0; 121 + int diff = da - db - borrow; 122 + if (diff < 0) { 123 + diff += 10; 124 + borrow = 1; 125 + } else { 126 + borrow = 0; 127 + } 128 + result[ri++] = (char)('0' + diff); 129 + } 130 + 131 + while (ri > 1 && result[ri - 1] == '0') ri--; 132 + for (size_t i = 0; i < ri / 2; i++) { 133 + char tmp = result[i]; 134 + result[i] = result[ri - 1 - i]; 135 + result[ri - 1 - i] = tmp; 136 + } 137 + 138 + result[ri] = 0; 139 + *rlen = ri; 140 + return result; 141 + } 142 + 143 + static char *bigint_mul_abs(const char *a, size_t alen, const char *b, size_t blen, size_t *rlen) { 144 + size_t reslen = alen + blen; 145 + int *temp = (int *)calloc(reslen, sizeof(int)); 146 + if (!temp) return NULL; 147 + 148 + for (size_t i = 0; i < alen; i++) { 149 + for (size_t j = 0; j < blen; j++) { 150 + temp[i + j] += (a[alen - 1 - i] - '0') * (b[blen - 1 - j] - '0'); 151 + } 152 + } 153 + 154 + for (size_t i = 0; i < reslen - 1; i++) { 155 + temp[i + 1] += temp[i] / 10; 156 + temp[i] %= 10; 157 + } 158 + 159 + size_t start = reslen - 1; 160 + while (start > 0 && temp[start] == 0) start--; 161 + 162 + char *result = (char *)malloc(start + 2); 163 + if (!result) { 164 + free(temp); 165 + return NULL; 166 + } 167 + 168 + for (size_t i = 0; i <= start; i++) result[i] = (char)('0' + temp[start - i]); 169 + result[start + 1] = 0; 170 + *rlen = start + 1; 171 + 172 + free(temp); 173 + return result; 174 + } 175 + 176 + static char *bigint_div_abs( 177 + const char *a, 178 + size_t alen, 179 + const char *b, 180 + size_t blen, 181 + size_t *rlen, 182 + char **rem, 183 + size_t *remlen 184 + ) { 185 + if (blen == 1 && b[0] == '0') return NULL; 186 + 187 + if (bigint_cmp_abs(a, alen, b, blen) < 0) { 188 + char *result = (char *)malloc(2); 189 + result[0] = '0'; 190 + result[1] = 0; 191 + *rlen = 1; 192 + if (rem) { 193 + *rem = (char *)malloc(alen + 1); 194 + memcpy(*rem, a, alen); 195 + (*rem)[alen] = 0; 196 + *remlen = alen; 197 + } 198 + return result; 199 + } 200 + 201 + char *current = (char *)calloc(alen + 1, 1); 202 + char *result = (char *)calloc(alen + 1, 1); 203 + if (!current || !result) { 204 + free(current); 205 + free(result); 206 + return NULL; 207 + } 208 + 209 + size_t curlen = 0, reslen = 0; 210 + for (size_t i = 0; i < alen; i++) { 211 + if (curlen == 1 && current[0] == '0') curlen = 0; 212 + current[curlen++] = a[i]; 213 + current[curlen] = 0; 214 + 215 + int count = 0; 216 + while (bigint_cmp_abs(current, curlen, b, blen) >= 0) { 217 + size_t sublen; 218 + char *sub = bigint_sub_abs(current, curlen, b, blen, &sublen); 219 + if (!sub) break; 220 + memcpy(current, sub, sublen + 1); 221 + curlen = sublen; 222 + free(sub); 223 + count++; 224 + } 225 + 226 + result[reslen++] = (char)('0' + count); 227 + } 228 + 229 + size_t start = 0; 230 + while (start < reslen - 1 && result[start] == '0') start++; 231 + memmove(result, result + start, reslen - start + 1); 232 + 233 + *rlen = reslen - start; 234 + if (rem) { 235 + *rem = current; 236 + *remlen = curlen; 237 + } else { 238 + free(current); 239 + } 240 + 241 + return result; 242 + } 243 + 244 + ant_value_t bigint_add(ant_t *js, ant_value_t a, ant_value_t b) { 245 + bool aneg = bigint_is_negative(js, a); 246 + bool bneg = bigint_is_negative(js, b); 247 + size_t alen, blen; 248 + const char *ad = bigint_digits(js, a, &alen); 249 + const char *bd = bigint_digits(js, b, &blen); 250 + 251 + char *result; 252 + size_t rlen; 253 + bool rneg; 254 + 255 + if (aneg == bneg) { 256 + result = bigint_add_abs(ad, alen, bd, blen, &rlen); 257 + rneg = aneg; 258 + } else { 259 + int cmp = bigint_cmp_abs(ad, alen, bd, blen); 260 + if (cmp >= 0) { 261 + result = bigint_sub_abs(ad, alen, bd, blen, &rlen); 262 + rneg = aneg; 263 + } else { 264 + result = bigint_sub_abs(bd, blen, ad, alen, &rlen); 265 + rneg = bneg; 266 + } 267 + } 268 + 269 + if (!result) return js_mkerr(js, "oom"); 270 + if (rlen == 1 && result[0] == '0') rneg = false; 271 + 272 + ant_value_t r = js_mkbigint(js, result, rlen, rneg); 273 + free(result); 274 + return r; 275 + } 276 + 277 + ant_value_t bigint_sub(ant_t *js, ant_value_t a, ant_value_t b) { 278 + bool aneg = bigint_is_negative(js, a); 279 + bool bneg = bigint_is_negative(js, b); 280 + size_t alen, blen; 281 + const char *ad = bigint_digits(js, a, &alen); 282 + const char *bd = bigint_digits(js, b, &blen); 283 + 284 + char *result; 285 + size_t rlen; 286 + bool rneg; 287 + 288 + if (aneg != bneg) { 289 + result = bigint_add_abs(ad, alen, bd, blen, &rlen); 290 + rneg = aneg; 291 + } else { 292 + int cmp = bigint_cmp_abs(ad, alen, bd, blen); 293 + if (cmp >= 0) { 294 + result = bigint_sub_abs(ad, alen, bd, blen, &rlen); 295 + rneg = aneg; 296 + } else { 297 + result = bigint_sub_abs(bd, blen, ad, alen, &rlen); 298 + rneg = !aneg; 299 + } 300 + } 301 + 302 + if (!result) return js_mkerr(js, "oom"); 303 + if (rlen == 1 && result[0] == '0') rneg = false; 304 + 305 + ant_value_t r = js_mkbigint(js, result, rlen, rneg); 306 + free(result); 307 + return r; 308 + } 309 + 310 + ant_value_t bigint_mul(ant_t *js, ant_value_t a, ant_value_t b) { 311 + bool aneg = bigint_is_negative(js, a); 312 + bool bneg = bigint_is_negative(js, b); 313 + size_t alen, blen; 314 + const char *ad = bigint_digits(js, a, &alen); 315 + const char *bd = bigint_digits(js, b, &blen); 316 + 317 + size_t rlen; 318 + char *result = bigint_mul_abs(ad, alen, bd, blen, &rlen); 319 + if (!result) return js_mkerr(js, "oom"); 320 + 321 + bool rneg = (aneg != bneg) && !(rlen == 1 && result[0] == '0'); 322 + ant_value_t r = js_mkbigint(js, result, rlen, rneg); 323 + free(result); 324 + return r; 325 + } 326 + 327 + ant_value_t bigint_div(ant_t *js, ant_value_t a, ant_value_t b) { 328 + bool aneg = bigint_is_negative(js, a); 329 + bool bneg = bigint_is_negative(js, b); 330 + size_t alen, blen; 331 + const char *ad = bigint_digits(js, a, &alen); 332 + const char *bd = bigint_digits(js, b, &blen); 333 + 334 + if (blen == 1 && bd[0] == '0') return js_mkerr(js, "Division by zero"); 335 + 336 + size_t rlen; 337 + char *result = bigint_div_abs(ad, alen, bd, blen, &rlen, NULL, NULL); 338 + if (!result) return js_mkerr(js, "oom"); 339 + 340 + bool rneg = (aneg != bneg) && !(rlen == 1 && result[0] == '0'); 341 + ant_value_t r = js_mkbigint(js, result, rlen, rneg); 342 + free(result); 343 + return r; 344 + } 345 + 346 + ant_value_t bigint_mod(ant_t *js, ant_value_t a, ant_value_t b) { 347 + bool aneg = bigint_is_negative(js, a); 348 + size_t alen, blen; 349 + const char *ad = bigint_digits(js, a, &alen); 350 + const char *bd = bigint_digits(js, b, &blen); 351 + 352 + if (blen == 1 && bd[0] == '0') return js_mkerr(js, "Division by zero"); 353 + 354 + size_t rlen, remlen; 355 + char *rem; 356 + char *result = bigint_div_abs(ad, alen, bd, blen, &rlen, &rem, &remlen); 357 + if (!result) return js_mkerr(js, "oom"); 358 + free(result); 359 + 360 + bool rneg = aneg && !(remlen == 1 && rem[0] == '0'); 361 + ant_value_t r = js_mkbigint(js, rem, remlen, rneg); 362 + free(rem); 363 + return r; 364 + } 365 + 366 + ant_value_t bigint_neg(ant_t *js, ant_value_t a) { 367 + size_t len; 368 + const char *digits = bigint_digits(js, a, &len); 369 + bool neg = bigint_is_negative(js, a); 370 + if (len == 1 && digits[0] == '0') return js_mkbigint(js, digits, len, false); 371 + return js_mkbigint(js, digits, len, !neg); 372 + } 373 + 374 + ant_value_t bigint_exp(ant_t *js, ant_value_t base, ant_value_t exp) { 375 + if (bigint_is_negative(js, exp)) return js_mkerr(js, "Exponent must be positive"); 376 + 377 + size_t explen; 378 + const char *expd = bigint_digits(js, exp, &explen); 379 + if (explen == 1 && expd[0] == '0') return js_mkbigint(js, "1", 1, false); 380 + 381 + ant_value_t result = js_mkbigint(js, "1", 1, false); 382 + ant_value_t b = base; 383 + ant_value_t e = exp; 384 + ant_value_t two = js_mkbigint(js, "2", 1, false); 385 + 386 + while (true) { 387 + size_t elen; 388 + const char *ed = bigint_digits(js, e, &elen); 389 + if (elen == 1 && ed[0] == '0') break; 390 + 391 + int last_digit = ed[elen - 1] - '0'; 392 + if (last_digit % 2 == 1) { 393 + result = bigint_mul(js, result, b); 394 + if (is_err(result)) return result; 395 + } 396 + 397 + b = bigint_mul(js, b, b); 398 + if (is_err(b)) return b; 399 + 400 + e = bigint_div(js, e, two); 401 + if (is_err(e)) return e; 402 + } 403 + 404 + return result; 405 + } 406 + 407 + static inline ant_value_t bigint_pow2(ant_t *js, uint64_t bits) { 408 + ant_value_t two = js_mkbigint(js, "2", 1, false); 409 + if (is_err(two)) return two; 410 + 411 + ant_value_t exp = bigint_from_u64(js, bits); 412 + if (is_err(exp)) return exp; 413 + 414 + return bigint_exp(js, two, exp); 415 + } 416 + 417 + ant_value_t bigint_shift_left(ant_t *js, ant_value_t value, uint64_t shift) { 418 + if (shift == 0) return value; 419 + if (shift > 18446744073709551615ULL) return js_mkerr(js, "Shift count too large"); 420 + 421 + size_t digits_len; 422 + const char *digits = bigint_digits(js, value, &digits_len); 423 + if (digits_len == 1 && digits[0] == '0') return js_mkbigint(js, "0", 1, false); 424 + 425 + uint64_t u64 = 0; 426 + if (!bigint_is_negative(js, value) && shift < 64 && bigint_parse_u64(js, value, &u64)) { 427 + if (u64 <= (UINT64_MAX >> shift)) return bigint_from_u64(js, u64 << shift); 428 + } 429 + 430 + ant_value_t pow = bigint_pow2(js, shift); 431 + if (is_err(pow)) return pow; 432 + return bigint_mul(js, value, pow); 433 + } 434 + 435 + ant_value_t bigint_shift_right(ant_t *js, ant_value_t value, uint64_t shift) { 436 + if (shift == 0) return value; 437 + if (shift > 18446744073709551615ULL) return js_mkerr(js, "Shift count too large"); 438 + 439 + size_t digits_len; 440 + const char *digits = bigint_digits(js, value, &digits_len); 441 + if (digits_len == 1 && digits[0] == '0') return js_mkbigint(js, "0", 1, false); 442 + 443 + uint64_t u64 = 0; 444 + if (!bigint_is_negative(js, value) && bigint_parse_u64(js, value, &u64)) { 445 + if (shift >= 64) return js_mkbigint(js, "0", 1, false); 446 + return bigint_from_u64(js, u64 >> shift); 447 + } 448 + 449 + if (bigint_parse_abs_u64(js, value, &u64)) { 450 + if (shift >= 64) { 451 + return js_mkbigint(js, bigint_is_negative(js, value) ? "1" : "0", 1, bigint_is_negative(js, value)); 452 + } 453 + 454 + uint64_t shifted = u64 >> shift; 455 + if (bigint_is_negative(js, value)) { 456 + if ((u64 & ((1ULL << shift) - 1)) != 0) shifted += 1; 457 + ant_value_t pos = bigint_from_u64(js, shifted); 458 + if (is_err(pos)) return pos; 459 + return bigint_neg(js, pos); 460 + } 461 + 462 + return bigint_from_u64(js, shifted); 463 + } 464 + 465 + ant_value_t pow = bigint_pow2(js, shift); 466 + if (is_err(pow)) return pow; 467 + return bigint_div(js, value, pow); 468 + } 469 + 470 + ant_value_t bigint_shift_right_logical(ant_t *js, ant_value_t value, uint64_t shift) { 471 + return js_mkerr_typed(js, JS_ERR_TYPE, "BigInts have no unsigned right shift, use >> instead"); 472 + } 473 + 474 + size_t bigint_compare(ant_t *js, ant_value_t a, ant_value_t b) { 475 + bool aneg = bigint_is_negative(js, a); 476 + bool bneg = bigint_is_negative(js, b); 477 + 478 + size_t alen, blen; 479 + const char *ad = bigint_digits(js, a, &alen); 480 + const char *bd = bigint_digits(js, b, &blen); 481 + 482 + if (aneg && !bneg) return -1; 483 + if (!aneg && bneg) return 1; 484 + 485 + int cmp = bigint_cmp_abs(ad, alen, bd, blen); 486 + return aneg ? -cmp : cmp; 487 + } 488 + 489 + bool bigint_is_zero(ant_t *js, ant_value_t v) { 490 + size_t len; 491 + const char *digits = bigint_digits(js, v, &len); 492 + return len == 1 && digits[0] == '0'; 493 + } 494 + 495 + size_t strbigint(ant_t *js, ant_value_t value, char *buf, size_t len) { 496 + bool neg = bigint_is_negative(js, value); 497 + size_t dlen; 498 + const char *digits = bigint_digits(js, value, &dlen); 499 + size_t total = dlen + (neg ? 1 : 0); 500 + 501 + if (len == 0) return total; 502 + 503 + size_t n = 0; 504 + if (neg && n < len - 1) buf[n] = '-'; 505 + if (neg) n++; 506 + 507 + size_t avail = n < len ? len - n - 1 : 0; 508 + size_t copy_len = dlen < avail ? dlen : avail; 509 + if (copy_len > 0) memcpy(buf + n, digits, copy_len); 510 + 511 + size_t term = n + copy_len; 512 + if (term >= len) term = len - 1; 513 + buf[term] = '\0'; 514 + return total; 515 + } 516 + 517 + static ant_value_t builtin_BigInt(ant_t *js, ant_value_t *args, int nargs) { 518 + if (vtype(js->new_target) != T_UNDEF) return js_mkerr_typed(js, JS_ERR_TYPE, "BigInt is not a constructor"); 519 + if (nargs < 1) return js_mkbigint(js, "0", 1, false); 520 + 521 + ant_value_t arg = args[0]; 522 + if (vtype(arg) == T_BIGINT) return arg; 523 + 524 + if (vtype(arg) == T_NUM) { 525 + double d = tod(arg); 526 + if (!isfinite(d)) return js_mkerr(js, "Cannot convert Infinity or NaN to BigInt"); 527 + if (d != trunc(d)) return js_mkerr(js, "Cannot convert non-integer to BigInt"); 528 + 529 + bool neg = d < 0; 530 + if (neg) d = -d; 531 + 532 + char buf[64]; 533 + snprintf(buf, sizeof(buf), "%.0f", d); 534 + return js_mkbigint(js, buf, strlen(buf), neg); 535 + } 536 + 537 + if (vtype(arg) == T_STR) { 538 + ant_offset_t slen; 539 + ant_offset_t off = vstr(js, arg, &slen); 540 + const char *str = (const char *)&js->mem[off]; 541 + 542 + bool neg = false; 543 + size_t i = 0; 544 + if (slen > 0 && str[0] == '-') { 545 + neg = true; 546 + i++; 547 + } else if (slen > 0 && str[0] == '+') { 548 + i++; 549 + } 550 + 551 + while (i < slen && str[i] == '0') i++; 552 + if (i >= slen) return js_mkbigint(js, "0", 1, false); 553 + 554 + for (size_t j = i; j < slen; j++) { 555 + if (!is_decimal_digit(str[j])) return js_mkerr(js, "Cannot convert string to BigInt"); 556 + } 557 + 558 + return js_mkbigint(js, str + i, slen - i, neg); 559 + } 560 + 561 + if (vtype(arg) == T_BOOL) return js_mkbigint(js, vdata(arg) ? "1" : "0", 1, false); 562 + 563 + return js_mkerr(js, "Cannot convert to BigInt"); 564 + } 565 + 566 + static ant_value_t bigint_to_u64(ant_t *js, ant_value_t value, uint64_t *out) { 567 + if (!bigint_parse_u64(js, value, out)) { 568 + return js_mkerr_typed(js, JS_ERR_RANGE, "Invalid bits"); 569 + } 570 + return js_mkundef(); 571 + } 572 + 573 + ant_value_t bigint_asint_bits(ant_t *js, ant_value_t arg, uint64_t *bits_out) { 574 + if (vtype(arg) == T_BIGINT) return bigint_to_u64(js, arg, bits_out); 575 + 576 + double bits = js_to_number(js, arg); 577 + if (!isfinite(bits) || bits < 0 || bits != floor(bits)) { 578 + return js_mkerr_typed(js, JS_ERR_RANGE, "Invalid bits"); 579 + } 580 + 581 + if (bits > 18446744073709551615.0) { 582 + return js_mkerr_typed(js, JS_ERR_RANGE, "Invalid bits"); 583 + } 584 + 585 + *bits_out = (uint64_t)bits; 586 + return js_mkundef(); 587 + } 588 + 589 + static ant_value_t builtin_BigInt_asIntN(ant_t *js, ant_value_t *args, int nargs) { 590 + if (nargs < 2) return js_mkerr(js, "BigInt.asIntN requires 2 arguments"); 591 + 592 + uint64_t bits = 0; 593 + ant_value_t err = bigint_asint_bits(js, args[0], &bits); 594 + if (is_err(err)) return err; 595 + 596 + if (vtype(args[1]) != T_BIGINT) return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert to BigInt"); 597 + if (bits == 0) return js_mkbigint(js, "0", 1, false); 598 + 599 + ant_value_t mod = bigint_pow2(js, bits); 600 + if (is_err(mod)) return mod; 601 + 602 + ant_value_t res = bigint_mod(js, args[1], mod); 603 + if (is_err(res)) return res; 604 + 605 + if (bigint_is_negative(js, res)) { 606 + ant_value_t adj = bigint_add(js, res, mod); 607 + if (is_err(adj)) return adj; 608 + res = adj; 609 + } 610 + 611 + ant_value_t threshold = bigint_pow2(js, bits - 1); 612 + if (is_err(threshold)) return threshold; 613 + 614 + if (bigint_compare(js, res, threshold) >= 0) { 615 + ant_value_t adj = bigint_sub(js, res, mod); 616 + if (is_err(adj)) return adj; 617 + res = adj; 618 + } 619 + 620 + return res; 621 + } 622 + 623 + static ant_value_t builtin_BigInt_asUintN(ant_t *js, ant_value_t *args, int nargs) { 624 + if (nargs < 2) return js_mkerr(js, "BigInt.asUintN requires 2 arguments"); 625 + 626 + uint64_t bits = 0; 627 + ant_value_t err = bigint_asint_bits(js, args[0], &bits); 628 + if (is_err(err)) return err; 629 + 630 + if (vtype(args[1]) != T_BIGINT) return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert to BigInt"); 631 + if (bits == 0) return js_mkbigint(js, "0", 1, false); 632 + 633 + ant_value_t mod = bigint_pow2(js, bits); 634 + if (is_err(mod)) return mod; 635 + 636 + ant_value_t res = bigint_mod(js, args[1], mod); 637 + if (is_err(res)) return res; 638 + 639 + if (bigint_is_negative(js, res)) { 640 + ant_value_t adj = bigint_add(js, res, mod); 641 + if (is_err(adj)) return adj; 642 + res = adj; 643 + } 644 + 645 + return res; 646 + } 647 + 648 + static ant_value_t builtin_bigint_toString(ant_t *js, ant_value_t *args, int nargs) { 649 + ant_value_t val = js->this_val; 650 + if (vtype(val) != T_BIGINT) return js_mkerr(js, "toString called on non-BigInt"); 651 + 652 + int radix = 10; 653 + if (nargs >= 1 && vtype(args[0]) == T_NUM) { 654 + radix = (int)tod(args[0]); 655 + if (radix < 2 || radix > 36) return js_mkerr(js, "radix must be between 2 and 36"); 656 + } 657 + 658 + bool neg = bigint_is_negative(js, val); 659 + size_t dlen; 660 + const char *digits = bigint_digits(js, val, &dlen); 661 + 662 + if (radix == 10) { 663 + size_t buflen = dlen + 2; 664 + char *buf = (char *)ant_calloc(buflen); 665 + if (!buf) return js_mkerr(js, "oom"); 666 + 667 + size_t n = 0; 668 + if (neg) buf[n++] = '-'; 669 + memcpy(buf + n, digits, dlen); 670 + n += dlen; 671 + 672 + ant_value_t ret = js_mkstr(js, buf, n); 673 + free(buf); 674 + return ret; 675 + } 676 + 677 + const uint32_t base = 1000000000U; 678 + size_t result_cap = dlen * 4 + 16; 679 + char *result = (char *)ant_calloc(result_cap); 680 + if (!result) return js_mkerr(js, "oom"); 681 + 682 + size_t rpos = result_cap - 1; 683 + result[rpos] = '\0'; 684 + 685 + size_t limb_cap = (dlen + 8) / 9 + 1; 686 + uint32_t *limbs = (uint32_t *)ant_calloc(limb_cap * sizeof(uint32_t)); 687 + if (!limbs) { 688 + free(result); 689 + return js_mkerr(js, "oom"); 690 + } 691 + size_t limb_len = 1; 692 + 693 + for (size_t i = 0; i < dlen; i++) { 694 + uint64_t carry = (uint64_t)(digits[i] - '0'); 695 + for (size_t j = 0; j < limb_len; j++) { 696 + uint64_t cur = (uint64_t)limbs[j] * 10 + carry; 697 + limbs[j] = (uint32_t)(cur % base); 698 + carry = cur / base; 699 + } 700 + 701 + if (carry != 0) { 702 + if (limb_len == limb_cap) { 703 + size_t new_cap = limb_cap * 2; 704 + uint32_t *new_limbs = (uint32_t *)ant_realloc(limbs, new_cap * sizeof(uint32_t)); 705 + if (!new_limbs) { 706 + free(limbs); 707 + free(result); 708 + return js_mkerr(js, "oom"); 709 + } 710 + limbs = new_limbs; 711 + limb_cap = new_cap; 712 + } 713 + limbs[limb_len++] = (uint32_t)carry; 714 + } 715 + } 716 + 717 + static const char digit_map[] = "0123456789abcdefghijklmnopqrstuvwxyz"; 718 + while (limb_len > 0 && !(limb_len == 1 && limbs[0] == 0)) { 719 + uint64_t remainder = 0; 720 + for (size_t i = limb_len; i-- > 0;) { 721 + uint64_t cur = (uint64_t)limbs[i] + remainder * base; 722 + limbs[i] = (uint32_t)(cur / (uint64_t)radix); 723 + remainder = cur % (uint64_t)radix; 724 + } 725 + 726 + while (limb_len > 0 && limbs[limb_len - 1] == 0) limb_len--; 727 + 728 + if (rpos == 0) { 729 + size_t new_cap = result_cap * 2; 730 + char *new_result = (char *)ant_calloc(new_cap); 731 + if (!new_result) { 732 + free(limbs); 733 + free(result); 734 + return js_mkerr(js, "oom"); 735 + } 736 + 737 + size_t used = result_cap - rpos; 738 + memcpy(new_result + new_cap - used, result + rpos, used); 739 + free(result); 740 + 741 + result = new_result; 742 + rpos = new_cap - used; 743 + result_cap = new_cap; 744 + } 745 + 746 + result[--rpos] = digit_map[remainder]; 747 + } 748 + 749 + free(limbs); 750 + 751 + if (rpos == result_cap - 1) result[--rpos] = '0'; 752 + if (neg) result[--rpos] = '-'; 753 + 754 + ant_value_t ret = js_mkstr(js, result + rpos, result_cap - 1 - rpos); 755 + free(result); 756 + return ret; 757 + } 758 + 759 + void init_bigint_module(void) { 760 + ant_t *js = rt->js; 761 + 762 + ant_value_t glob = js_glob(js); 763 + ant_value_t object_proto = js->object; 764 + ant_value_t function_proto = js_get_slot(js, glob, SLOT_FUNC_PROTO); 765 + if (vtype(function_proto) == T_UNDEF) function_proto = js_get_ctor_proto(js, "Function", 8); 766 + 767 + ant_value_t bigint_proto = js_mkobj(js); 768 + js_set_proto(js, bigint_proto, object_proto); 769 + js_setprop(js, bigint_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_bigint_toString)); 770 + 771 + ant_value_t bigint_ctor_obj = mkobj(js, 0); 772 + js_set_proto(js, bigint_ctor_obj, function_proto); 773 + js_set_slot(js, bigint_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_BigInt)); 774 + js_setprop(js, bigint_ctor_obj, js_mkstr(js, "asIntN", 6), js_mkfun(builtin_BigInt_asIntN)); 775 + js_setprop(js, bigint_ctor_obj, js_mkstr(js, "asUintN", 7), js_mkfun(builtin_BigInt_asUintN)); 776 + js_setprop_nonconfigurable(js, bigint_ctor_obj, "prototype", 9, bigint_proto); 777 + js_setprop(js, bigint_ctor_obj, ANT_STRING("name"), ANT_STRING("BigInt")); 778 + js_setprop(js, glob, js_mkstr(js, "BigInt", 6), js_obj_to_func(bigint_ctor_obj)); 779 + }
+313
src/modules/math.c
··· 1 + #include <stdlib.h> 2 + #include <time.h> 3 + 4 + #include "ant.h" 5 + #include "internal.h" 6 + #include "runtime.h" 7 + 8 + static ant_value_t builtin_Math_abs(ant_t *js, ant_value_t *args, int nargs) { 9 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 10 + if (isnan(x)) return tov(JS_NAN); 11 + return tov(fabs(x)); 12 + } 13 + 14 + static ant_value_t builtin_Math_acos(ant_t *js, ant_value_t *args, int nargs) { 15 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 16 + if (isnan(x)) return tov(JS_NAN); 17 + return tov(acos(x)); 18 + } 19 + 20 + static ant_value_t builtin_Math_acosh(ant_t *js, ant_value_t *args, int nargs) { 21 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 22 + if (isnan(x)) return tov(JS_NAN); 23 + return tov(acosh(x)); 24 + } 25 + 26 + static ant_value_t builtin_Math_asin(ant_t *js, ant_value_t *args, int nargs) { 27 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 28 + if (isnan(x)) return tov(JS_NAN); 29 + return tov(asin(x)); 30 + } 31 + 32 + static ant_value_t builtin_Math_asinh(ant_t *js, ant_value_t *args, int nargs) { 33 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 34 + if (isnan(x)) return tov(JS_NAN); 35 + return tov(asinh(x)); 36 + } 37 + 38 + static ant_value_t builtin_Math_atan(ant_t *js, ant_value_t *args, int nargs) { 39 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 40 + if (isnan(x)) return tov(JS_NAN); 41 + return tov(atan(x)); 42 + } 43 + 44 + static ant_value_t builtin_Math_atanh(ant_t *js, ant_value_t *args, int nargs) { 45 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 46 + if (isnan(x)) return tov(JS_NAN); 47 + return tov(atanh(x)); 48 + } 49 + 50 + static ant_value_t builtin_Math_atan2(ant_t *js, ant_value_t *args, int nargs) { 51 + double y = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 52 + double x = (nargs < 2) ? JS_NAN : js_to_number(js, args[1]); 53 + if (isnan(y) || isnan(x)) return tov(JS_NAN); 54 + return tov(atan2(y, x)); 55 + } 56 + 57 + static ant_value_t builtin_Math_cbrt(ant_t *js, ant_value_t *args, int nargs) { 58 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 59 + if (isnan(x)) return tov(JS_NAN); 60 + return tov(cbrt(x)); 61 + } 62 + 63 + static ant_value_t builtin_Math_ceil(ant_t *js, ant_value_t *args, int nargs) { 64 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 65 + if (isnan(x)) return tov(JS_NAN); 66 + return tov(ceil(x)); 67 + } 68 + 69 + static ant_value_t builtin_Math_clz32(ant_t *js, ant_value_t *args, int nargs) { 70 + if (nargs < 1) return tov(32); 71 + double x = js_to_number(js, args[0]); 72 + if (isnan(x) || isinf(x)) return tov(32); 73 + uint32_t n = (uint32_t)x; 74 + if (n == 0) return tov(32); 75 + int count = 0; 76 + while ((n & 0x80000000U) == 0) { count++; n <<= 1; } 77 + return tov((double)count); 78 + } 79 + 80 + static ant_value_t builtin_Math_cos(ant_t *js, ant_value_t *args, int nargs) { 81 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 82 + if (isnan(x)) return tov(JS_NAN); 83 + return tov(cos(x)); 84 + } 85 + 86 + static ant_value_t builtin_Math_cosh(ant_t *js, ant_value_t *args, int nargs) { 87 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 88 + if (isnan(x)) return tov(JS_NAN); 89 + return tov(cosh(x)); 90 + } 91 + 92 + static ant_value_t builtin_Math_exp(ant_t *js, ant_value_t *args, int nargs) { 93 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 94 + if (isnan(x)) return tov(JS_NAN); 95 + return tov(exp(x)); 96 + } 97 + 98 + static ant_value_t builtin_Math_expm1(ant_t *js, ant_value_t *args, int nargs) { 99 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 100 + if (isnan(x)) return tov(JS_NAN); 101 + return tov(expm1(x)); 102 + } 103 + 104 + static ant_value_t builtin_Math_floor(ant_t *js, ant_value_t *args, int nargs) { 105 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 106 + if (isnan(x)) return tov(JS_NAN); 107 + return tov(floor(x)); 108 + } 109 + 110 + static ant_value_t builtin_Math_fround(ant_t *js, ant_value_t *args, int nargs) { 111 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 112 + if (isnan(x)) return tov(JS_NAN); 113 + return tov((double)(float)x); 114 + } 115 + 116 + static ant_value_t builtin_Math_hypot(ant_t *js, ant_value_t *args, int nargs) { 117 + if (nargs == 0) return tov(0.0); 118 + double sum = 0.0; 119 + for (int i = 0; i < nargs; i++) { 120 + double v = js_to_number(js, args[i]); 121 + if (isnan(v)) return tov(JS_NAN); 122 + sum += v * v; 123 + } 124 + return tov(sqrt(sum)); 125 + } 126 + 127 + static int32_t toInt32(double d) { 128 + if (isnan(d) || isinf(d) || d == 0) return 0; 129 + double int_val = trunc(d); 130 + double two32 = (double)(1ULL << 32); 131 + double two31 = (double)(1ULL << 31); 132 + double mod_val = fmod(int_val, two32); 133 + if (mod_val < 0) mod_val += two32; 134 + if (mod_val >= two31) mod_val -= two32; 135 + return (int32_t)mod_val; 136 + } 137 + 138 + static ant_value_t builtin_Math_imul(ant_t *js, ant_value_t *args, int nargs) { 139 + if (nargs < 2) return tov(0); 140 + int32_t a = toInt32(js_to_number(js, args[0])); 141 + int32_t b = toInt32(js_to_number(js, args[1])); 142 + return tov((double)((int32_t)((uint32_t)a * (uint32_t)b))); 143 + } 144 + 145 + static ant_value_t builtin_Math_log(ant_t *js, ant_value_t *args, int nargs) { 146 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 147 + if (isnan(x)) return tov(JS_NAN); 148 + return tov(log(x)); 149 + } 150 + 151 + static ant_value_t builtin_Math_log1p(ant_t *js, ant_value_t *args, int nargs) { 152 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 153 + if (isnan(x)) return tov(JS_NAN); 154 + return tov(log1p(x)); 155 + } 156 + 157 + static ant_value_t builtin_Math_log10(ant_t *js, ant_value_t *args, int nargs) { 158 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 159 + if (isnan(x)) return tov(JS_NAN); 160 + return tov(log10(x)); 161 + } 162 + 163 + static ant_value_t builtin_Math_log2(ant_t *js, ant_value_t *args, int nargs) { 164 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 165 + if (isnan(x)) return tov(JS_NAN); 166 + return tov(log2(x)); 167 + } 168 + 169 + static ant_value_t builtin_Math_max(ant_t *js, ant_value_t *args, int nargs) { 170 + if (nargs == 0) return tov(JS_NEG_INF); 171 + double max_val = JS_NEG_INF; 172 + for (int i = 0; i < nargs; i++) { 173 + double v = js_to_number(js, args[i]); 174 + if (isnan(v)) return tov(JS_NAN); 175 + if (v > max_val) max_val = v; 176 + } 177 + return tov(max_val); 178 + } 179 + 180 + static ant_value_t builtin_Math_min(ant_t *js, ant_value_t *args, int nargs) { 181 + if (nargs == 0) return tov(JS_INF); 182 + double min_val = JS_INF; 183 + for (int i = 0; i < nargs; i++) { 184 + double v = js_to_number(js, args[i]); 185 + if (isnan(v)) return tov(JS_NAN); 186 + if (v < min_val) min_val = v; 187 + } 188 + return tov(min_val); 189 + } 190 + 191 + static ant_value_t builtin_Math_pow(ant_t *js, ant_value_t *args, int nargs) { 192 + double base = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 193 + double exp = (nargs < 2) ? JS_NAN : js_to_number(js, args[1]); 194 + if (isnan(base) || isnan(exp)) return tov(JS_NAN); 195 + return tov(pow(base, exp)); 196 + } 197 + 198 + static bool random_seeded = false; 199 + 200 + static ant_value_t builtin_Math_random(ant_t *js, ant_value_t *args, int nargs) { 201 + (void)js; 202 + (void)args; 203 + (void)nargs; 204 + if (!random_seeded) { 205 + srand((unsigned int)time(NULL)); 206 + random_seeded = true; 207 + } 208 + return tov((double)rand() / ((double)RAND_MAX + 1.0)); 209 + } 210 + 211 + static ant_value_t builtin_Math_round(ant_t *js, ant_value_t *args, int nargs) { 212 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 213 + if (isnan(x) || isinf(x)) return tov(x); 214 + return tov(floor(x + 0.5)); 215 + } 216 + 217 + static ant_value_t builtin_Math_sign(ant_t *js, ant_value_t *args, int nargs) { 218 + double v = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 219 + if (isnan(v)) return tov(JS_NAN); 220 + if (v > 0) return tov(1.0); 221 + if (v < 0) return tov(-1.0); 222 + return tov(v); 223 + } 224 + 225 + static ant_value_t builtin_Math_sin(ant_t *js, ant_value_t *args, int nargs) { 226 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 227 + if (isnan(x)) return tov(JS_NAN); 228 + return tov(sin(x)); 229 + } 230 + 231 + static ant_value_t builtin_Math_sinh(ant_t *js, ant_value_t *args, int nargs) { 232 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 233 + if (isnan(x)) return tov(JS_NAN); 234 + return tov(sinh(x)); 235 + } 236 + 237 + static ant_value_t builtin_Math_sqrt(ant_t *js, ant_value_t *args, int nargs) { 238 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 239 + if (isnan(x)) return tov(JS_NAN); 240 + return tov(sqrt(x)); 241 + } 242 + 243 + static ant_value_t builtin_Math_tan(ant_t *js, ant_value_t *args, int nargs) { 244 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 245 + if (isnan(x)) return tov(JS_NAN); 246 + return tov(tan(x)); 247 + } 248 + 249 + static ant_value_t builtin_Math_tanh(ant_t *js, ant_value_t *args, int nargs) { 250 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 251 + if (isnan(x)) return tov(JS_NAN); 252 + return tov(tanh(x)); 253 + } 254 + 255 + static ant_value_t builtin_Math_trunc(ant_t *js, ant_value_t *args, int nargs) { 256 + double x = (nargs < 1) ? JS_NAN : js_to_number(js, args[0]); 257 + if (isnan(x)) return tov(JS_NAN); 258 + return tov(trunc(x)); 259 + } 260 + 261 + void init_math_module(void) { 262 + ant_t *js = rt->js; 263 + 264 + ant_value_t glob = js_glob(js); 265 + ant_value_t object_proto = js->object; 266 + ant_value_t math_obj = mkobj(js, 0); 267 + 268 + js_set_proto(js, math_obj, object_proto); 269 + js_setprop(js, math_obj, js_mkstr(js, "E", 1), tov(M_E)); 270 + js_setprop(js, math_obj, js_mkstr(js, "LN10", 4), tov(M_LN10)); 271 + js_setprop(js, math_obj, js_mkstr(js, "LN2", 3), tov(M_LN2)); 272 + js_setprop(js, math_obj, js_mkstr(js, "LOG10E", 6), tov(M_LOG10E)); 273 + js_setprop(js, math_obj, js_mkstr(js, "LOG2E", 5), tov(M_LOG2E)); 274 + js_setprop(js, math_obj, js_mkstr(js, "PI", 2), tov(M_PI)); 275 + js_setprop(js, math_obj, js_mkstr(js, "SQRT1_2", 7), tov(M_SQRT1_2)); 276 + js_setprop(js, math_obj, js_mkstr(js, "SQRT2", 5), tov(M_SQRT2)); 277 + js_setprop(js, math_obj, js_mkstr(js, "abs", 3), js_mkfun(builtin_Math_abs)); 278 + js_setprop(js, math_obj, js_mkstr(js, "acos", 4), js_mkfun(builtin_Math_acos)); 279 + js_setprop(js, math_obj, js_mkstr(js, "acosh", 5), js_mkfun(builtin_Math_acosh)); 280 + js_setprop(js, math_obj, js_mkstr(js, "asin", 4), js_mkfun(builtin_Math_asin)); 281 + js_setprop(js, math_obj, js_mkstr(js, "asinh", 5), js_mkfun(builtin_Math_asinh)); 282 + js_setprop(js, math_obj, js_mkstr(js, "atan", 4), js_mkfun(builtin_Math_atan)); 283 + js_setprop(js, math_obj, js_mkstr(js, "atanh", 5), js_mkfun(builtin_Math_atanh)); 284 + js_setprop(js, math_obj, js_mkstr(js, "atan2", 5), js_mkfun(builtin_Math_atan2)); 285 + js_setprop(js, math_obj, js_mkstr(js, "cbrt", 4), js_mkfun(builtin_Math_cbrt)); 286 + js_setprop(js, math_obj, js_mkstr(js, "ceil", 4), js_mkfun(builtin_Math_ceil)); 287 + js_setprop(js, math_obj, js_mkstr(js, "clz32", 5), js_mkfun(builtin_Math_clz32)); 288 + js_setprop(js, math_obj, js_mkstr(js, "cos", 3), js_mkfun(builtin_Math_cos)); 289 + js_setprop(js, math_obj, js_mkstr(js, "cosh", 4), js_mkfun(builtin_Math_cosh)); 290 + js_setprop(js, math_obj, js_mkstr(js, "exp", 3), js_mkfun(builtin_Math_exp)); 291 + js_setprop(js, math_obj, js_mkstr(js, "expm1", 5), js_mkfun(builtin_Math_expm1)); 292 + js_setprop(js, math_obj, js_mkstr(js, "floor", 5), js_mkfun(builtin_Math_floor)); 293 + js_setprop(js, math_obj, js_mkstr(js, "fround", 6), js_mkfun(builtin_Math_fround)); 294 + js_setprop(js, math_obj, js_mkstr(js, "hypot", 5), js_mkfun(builtin_Math_hypot)); 295 + js_setprop(js, math_obj, js_mkstr(js, "imul", 4), js_mkfun(builtin_Math_imul)); 296 + js_setprop(js, math_obj, js_mkstr(js, "log", 3), js_mkfun(builtin_Math_log)); 297 + js_setprop(js, math_obj, js_mkstr(js, "log1p", 5), js_mkfun(builtin_Math_log1p)); 298 + js_setprop(js, math_obj, js_mkstr(js, "log10", 5), js_mkfun(builtin_Math_log10)); 299 + js_setprop(js, math_obj, js_mkstr(js, "log2", 4), js_mkfun(builtin_Math_log2)); 300 + js_setprop(js, math_obj, js_mkstr(js, "max", 3), js_mkfun(builtin_Math_max)); 301 + js_setprop(js, math_obj, js_mkstr(js, "min", 3), js_mkfun(builtin_Math_min)); 302 + js_setprop(js, math_obj, js_mkstr(js, "pow", 3), js_mkfun(builtin_Math_pow)); 303 + js_setprop(js, math_obj, js_mkstr(js, "random", 6), js_mkfun(builtin_Math_random)); 304 + js_setprop(js, math_obj, js_mkstr(js, "round", 5), js_mkfun(builtin_Math_round)); 305 + js_setprop(js, math_obj, js_mkstr(js, "sign", 4), js_mkfun(builtin_Math_sign)); 306 + js_setprop(js, math_obj, js_mkstr(js, "sin", 3), js_mkfun(builtin_Math_sin)); 307 + js_setprop(js, math_obj, js_mkstr(js, "sinh", 4), js_mkfun(builtin_Math_sinh)); 308 + js_setprop(js, math_obj, js_mkstr(js, "sqrt", 4), js_mkfun(builtin_Math_sqrt)); 309 + js_setprop(js, math_obj, js_mkstr(js, "tan", 3), js_mkfun(builtin_Math_tan)); 310 + js_setprop(js, math_obj, js_mkstr(js, "tanh", 4), js_mkfun(builtin_Math_tanh)); 311 + js_setprop(js, math_obj, js_mkstr(js, "trunc", 5), js_mkfun(builtin_Math_trunc)); 312 + js_setprop(js, glob, js_mkstr(js, "Math", 4), math_obj); 313 + }
+2
src/silver/ops/arithmetic.h
··· 4 4 #include <math.h> 5 5 #include "tokens.h" 6 6 #include "errors.h" 7 + 7 8 #include "silver/engine.h" 9 + #include "modules/bigint.h" 8 10 9 11 static inline ant_value_t sv_op_add(sv_vm_t *vm, ant_t *js) { 10 12 ant_value_t r = vm->stack[--vm->sp];
+1
src/silver/ops/bitwise.h
··· 3 3 4 4 #include "errors.h" 5 5 #include "silver/engine.h" 6 + #include "modules/bigint.h" 6 7 7 8 static inline ant_value_t sv_op_band(sv_vm_t *vm, ant_t *js) { 8 9 ant_value_t r = vm->stack[--vm->sp];
+1
src/silver/ops/comparison.h
··· 2 2 #define SV_COMPARISON_H 3 3 4 4 #include "silver/engine.h" 5 + #include "modules/bigint.h" 5 6 6 7 static inline void sv_op_seq(sv_vm_t *vm, ant_t *js) { 7 8 ant_value_t r = vm->stack[--vm->sp];