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.

cleanup ant, add utils, remove unused hoists

+158 -186
+1
README.txt
··· 3 3 4 4 A minimal embedded JavaScript engine with async/await, promises, modules, 5 5 and built-in APIs for HTTP servers, timers, crypto, and JSON. 6 + Check about my blog post about Ant! https://s.tail.so/js-in-one-month 6 7 7 8 BUILD: 8 9 meson setup build && meson compile -C build
+3
include/utils.h
··· 1 + #include <stdlib.h> 2 + 3 + uint64_t hash_key(const char *key, size_t len);
+2 -1
meson.build
··· 16 16 17 17 sources = files( 18 18 'src/main.c', 19 + 'src/utils.c', 19 20 'src/ant.c', 20 21 'src/gc.c', 21 22 'src/repl.c', ··· 95 96 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 96 97 97 98 version_conf = configuration_data() 98 - version_conf.set('ANT_VERSION', '0.3.2.6') 99 + version_conf.set('ANT_VERSION', '0.3.2.7') 99 100 version_conf.set('ANT_GIT_HASH', git_hash) 100 101 version_conf.set('ANT_BUILD_DATE', build_date) 101 102
+128 -184
src/ant.c
··· 5 5 #include "ant.h" 6 6 #include "config.h" 7 7 #include "arena.h" 8 + #include "utils.h" 8 9 #include "runtime.h" 9 10 #include "internal.h" 10 11 ··· 387 388 } 388 389 389 390 enum { 390 - TOK_ERR, TOK_EOF, TOK_IDENTIFIER, TOK_NUMBER, TOK_STRING, TOK_SEMICOLON, TOK_BIGINT, 391 + TOK_ERR, TOK_EOF, TOK_NUMBER, TOK_STRING, TOK_SEMICOLON, TOK_BIGINT, 391 392 TOK_LPAREN, TOK_RPAREN, TOK_LBRACE, TOK_RBRACE, TOK_LBRACKET, TOK_RBRACKET, 392 - TOK_ASYNC = 50, TOK_AWAIT, TOK_BREAK, TOK_CASE, TOK_CATCH, TOK_CLASS, TOK_CONST, TOK_CONTINUE, 393 - TOK_DEFAULT, TOK_DELETE, TOK_DO, TOK_DEBUGGER, TOK_ELSE, TOK_EXPORT, TOK_FINALLY, TOK_FOR, TOK_FROM, TOK_FUNC, 394 - TOK_IF, TOK_IMPORT, TOK_IN, TOK_INSTANCEOF, TOK_LET, TOK_NEW, TOK_OF, TOK_RETURN, TOK_SWITCH, 395 - TOK_THIS, TOK_THROW, TOK_TRY, TOK_VAR, TOK_VOID, TOK_WHILE, TOK_WITH, 396 - TOK_YIELD, TOK_UNDEF, TOK_NULL, TOK_TRUE, TOK_FALSE, TOK_AS, TOK_STATIC, TOK_WINDOW, TOK_GLOBAL_THIS, 393 + 394 + // identifier-like 395 + TOK_IDENTIFIER = 50, 396 + TOK_ASYNC, TOK_AWAIT, TOK_BREAK, TOK_CASE, TOK_CATCH, TOK_CLASS, TOK_CONST, TOK_CONTINUE, 397 + TOK_DEFAULT, TOK_DELETE, TOK_DO, TOK_DEBUGGER, TOK_ELSE, TOK_EXPORT, TOK_FINALLY, TOK_FOR, 398 + TOK_FROM, TOK_FUNC, TOK_IF, TOK_IMPORT, TOK_IN, TOK_INSTANCEOF, TOK_LET, TOK_NEW, TOK_OF, 399 + TOK_RETURN, TOK_SWITCH, TOK_THIS, TOK_THROW, TOK_TRY, TOK_VAR, TOK_VOID, TOK_WHILE, TOK_WITH, 400 + TOK_YIELD, TOK_UNDEF, TOK_NULL, TOK_TRUE, TOK_FALSE, TOK_AS, TOK_STATIC, TOK_TYPEOF, 401 + TOK_WINDOW, TOK_GLOBAL_THIS, 402 + TOK_IDENT_LIKE_END, 403 + 404 + // operators 397 405 TOK_DOT = 100, TOK_CALL, TOK_BRACKET, TOK_POSTINC, TOK_POSTDEC, TOK_NOT, TOK_TILDA, 398 - TOK_TYPEOF, TOK_UPLUS, TOK_UMINUS, TOK_EXP, TOK_MUL, TOK_DIV, TOK_REM, 406 + TOK_UPLUS, TOK_UMINUS, TOK_EXP, TOK_MUL, TOK_DIV, TOK_REM, 399 407 TOK_OPTIONAL_CHAIN, TOK_REST, 400 408 TOK_PLUS, TOK_MINUS, TOK_SHL, TOK_SHR, TOK_ZSHR, TOK_LT, TOK_LE, TOK_GT, 401 409 TOK_GE, TOK_EQ, TOK_NE, TOK_SEQ, TOK_SNE, TOK_AND, TOK_XOR, TOK_OR, TOK_LAND, TOK_LOR, TOK_NULLISH, 402 - TOK_COLON, TOK_Q, TOK_ASSIGN, TOK_PLUS_ASSIGN, TOK_MINUS_ASSIGN, 410 + TOK_COLON, TOK_Q, TOK_ASSIGN, TOK_PLUS_ASSIGN, TOK_MINUS_ASSIGN, 403 411 TOK_MUL_ASSIGN, TOK_DIV_ASSIGN, TOK_REM_ASSIGN, TOK_SHL_ASSIGN, 404 412 TOK_SHR_ASSIGN, TOK_ZSHR_ASSIGN, TOK_AND_ASSIGN, TOK_XOR_ASSIGN, 405 413 TOK_OR_ASSIGN, TOK_LOR_ASSIGN, TOK_LAND_ASSIGN, TOK_NULLISH_ASSIGN, ··· 421 429 [TOK_PLUS] = 12, [TOK_MINUS] = 12, 422 430 [TOK_MUL] = 13, [TOK_DIV] = 13, [TOK_REM] = 13, 423 431 [TOK_EXP] = 14, 432 + }; 433 + 434 + static const uint8_t unary_table[TOK_MAX] = { 435 + [TOK_POSTINC] = 1, [TOK_POSTDEC] = 1, 436 + [TOK_NOT] = 1, [TOK_TILDA] = 1, [TOK_TYPEOF] = 1, 437 + [TOK_UPLUS] = 1, [TOK_UMINUS] = 1, [TOK_VOID] = 1, 424 438 }; 425 439 426 440 enum { ··· 469 483 static jsoff_t coderefoff(jsval_t v) { return v & PROPREF_OFF_MASK; } 470 484 static jsoff_t codereflen(jsval_t v) { return (v >> 24U) & PROPREF_OFF_MASK; } 471 485 486 + static jsval_t get_slot(struct js *js, jsval_t obj, internal_slot_t slot); 487 + static void set_slot(struct js *js, jsval_t obj, internal_slot_t slot, jsval_t value); 488 + 489 + static jsval_t get_proto(struct js *js, jsval_t obj); 490 + static void set_proto(struct js *js, jsval_t obj, jsval_t proto); 491 + 492 + static void clear_break_label(void) { 493 + break_target_label = NULL; 494 + break_target_label_len = 0; 495 + label_flags &= ~F_BREAK_LABEL; 496 + } 497 + 498 + static void clear_continue_label(void) { 499 + continue_target_label = NULL; 500 + continue_target_label_len = 0; 501 + label_flags &= ~F_CONTINUE_LABEL; 502 + } 503 + 472 504 static inline propref_data_t *propref_get_entry(jsval_t v) { 473 505 uint64_t data = v & NANBOX_DATA_MASK; 474 506 if (!(data & PROPREF_STACK_FLAG)) return NULL; ··· 535 567 void *js_gettypedarray(jsval_t val) { 536 568 if (vtype(val) != T_TYPEDARRAY) return NULL; 537 569 return (void *)vdata(val); 570 + } 571 + 572 + jsval_t js_get_slot(struct js *js, jsval_t obj, internal_slot_t slot) { 573 + return get_slot(js, obj, slot); 574 + } 575 + 576 + void js_set_slot(struct js *js, jsval_t obj, internal_slot_t slot, jsval_t value) { 577 + set_slot(js, obj, slot, value); 538 578 } 539 579 540 580 jsval_t js_mkffi(unsigned int index) { ··· 636 676 return c == '_' || c == '$' || is_alpha(c) || is_digit(c) || (c & 0x80); 637 677 } 638 678 639 - static bool is_unary(uint8_t tok) { 640 - return (tok >= TOK_POSTINC && tok <= TOK_UMINUS) || tok == TOK_NOT || tok == TOK_TILDA || tok == TOK_TYPEOF || tok == TOK_VOID; 679 + static bool is_unary(uint8_t tok) { 680 + return unary_table[tok]; 641 681 } 642 682 643 - static bool is_assign(uint8_t tok) { 644 - return (tok >= TOK_ASSIGN && tok <= TOK_OR_ASSIGN) || 645 - tok == TOK_LOR_ASSIGN || tok == TOK_LAND_ASSIGN || tok == TOK_NULLISH_ASSIGN; 683 + static bool is_assign(uint8_t tok) { 684 + return tok >= TOK_ASSIGN && tok <= TOK_NULLISH_ASSIGN; 685 + } 686 + 687 + static bool is_identifier_like(uint8_t tok) { 688 + return tok >= TOK_IDENTIFIER && tok < TOK_IDENT_LIKE_END; 646 689 } 647 690 648 691 static bool is_keyword_propname(uint8_t tok) { ··· 712 755 713 756 static bool is_proxy(struct js *js, jsval_t obj); 714 757 static bool streq(const char *buf, size_t len, const char *p, size_t n); 758 + static bool is_this_loop_continue_target(int depth_at_entry); 759 + static bool parse_func_params(struct js *js, uint8_t *flags, int *out_count); 760 + static bool try_dynamic_setter(struct js *js, jsval_t obj, const char *key, size_t key_len, jsval_t value); 761 + 715 762 static size_t tostr(struct js *js, jsval_t value, char *buf, size_t len); 716 763 static size_t strpromise(struct js *js, jsval_t value, char *buf, size_t len); 717 764 static size_t js_to_pcre2_pattern(const char *src, size_t src_len, char *dst, size_t dst_size); 718 765 719 - static bool continue_targets_innermost_loop(void); 720 - static bool is_continue_target(const char *name, jsoff_t len); 721 - static bool is_this_loop_continue_target(int depth_at_entry); 722 - static void clear_continue_label(void); 723 - static void clear_break_label(void); 724 - 725 766 static jsval_t js_stmt_impl(struct js *js); 726 767 static inline jsoff_t esize(jsoff_t w); 727 - 728 - static bool parse_func_params(struct js *js, uint8_t *flags, int *out_count); 729 - static double js_to_number(struct js *js, jsval_t arg); 730 - static jsval_t js_call_toString(struct js *js, jsval_t value); 731 768 732 769 static jsval_t js_expr(struct js *js); 770 + static jsval_t js_call_toString(struct js *js, jsval_t value); 733 771 static jsval_t js_eval_slice(struct js *js, jsoff_t off, jsoff_t len); 734 772 static jsval_t js_eval_str(struct js *js, const char *code, jsoff_t len); 735 773 static jsval_t js_stmt(struct js *js); 736 774 static jsval_t js_assignment(struct js *js); 737 775 static jsval_t js_arrow_func(struct js *js, jsoff_t params_start, jsoff_t params_end, bool is_async); 738 - static jsval_t js_while(struct js *js); 739 - static jsval_t js_do_while(struct js *js); 740 - static jsval_t js_block_or_stmt(struct js *js); 741 776 static jsval_t js_var_decl(struct js *js); 742 - static jsval_t js_regex_literal(struct js *js); 743 - static jsval_t js_try(struct js *js); 744 - static jsval_t js_switch(struct js *js); 777 + 745 778 static jsval_t do_op(struct js *, uint8_t op, jsval_t l, jsval_t r); 746 779 static jsval_t do_instanceof(struct js *js, jsval_t l, jsval_t r); 747 780 static jsval_t do_in(struct js *js, jsval_t l, jsval_t r); 748 781 static jsval_t resolveprop(struct js *js, jsval_t v); 782 + 749 783 static jsoff_t lkp(struct js *js, jsval_t obj, const char *buf, size_t len); 750 - static jsoff_t lkp_scope(struct js *js, jsval_t scope, const char *buf, size_t len); 751 784 static jsoff_t lkp_interned(struct js *js, jsval_t obj, const char *search_intern, size_t len); 752 - static const char *intern_string(const char *str, size_t len); 753 - static jsval_t get_slot(struct js *js, jsval_t obj, internal_slot_t slot); 754 - static void set_slot(struct js *js, jsval_t obj, internal_slot_t slot, jsval_t value); 785 + 755 786 static inline bool is_slot_prop(jsoff_t header); 756 787 static inline jsoff_t next_prop(jsoff_t header); 757 788 ··· 759 790 static jsval_t js_export_stmt(struct js *js); 760 791 761 792 static jsval_t builtin_Object(struct js *js, jsval_t *args, int nargs); 762 - static jsval_t builtin_Promise(struct js *js, jsval_t *args, int nargs); 763 793 static jsval_t builtin_promise_then(struct js *js, jsval_t *args, int nargs); 764 794 765 795 static jsval_t proxy_get(struct js *js, jsval_t proxy, const char *key, size_t key_len); 766 796 static jsval_t proxy_set(struct js *js, jsval_t proxy, const char *key, size_t key_len, jsval_t value); 767 797 static jsval_t proxy_has(struct js *js, jsval_t proxy, const char *key, size_t key_len); 768 798 static jsval_t proxy_delete(struct js *js, jsval_t proxy, const char *key, size_t key_len); 769 - 770 - static jsval_t builtin_function_call(struct js *js, jsval_t *args, int nargs); 771 - static jsval_t builtin_function_apply(struct js *js, jsval_t *args, int nargs); 772 - static jsval_t builtin_function_bind(struct js *js, jsval_t *args, int nargs); 773 - static bool try_dynamic_setter(struct js *js, jsval_t obj, const char *key, size_t key_len, jsval_t value); 774 - 775 799 static jsval_t call_js(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope); 776 - static jsval_t call_js_internal(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *bound_args, int bound_argc); 777 - static jsval_t call_js_internal_nfe(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *bound_args, int bound_argc, jsval_t func_val); 800 + static jsval_t call_js_internal(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *bound_args, int bound_argc, jsval_t func_val); 778 801 779 802 static jsval_t call_js_with_args(struct js *js, jsval_t fn, jsval_t *args, int nargs); 780 - static jsval_t call_js_code_with_args(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *args, int nargs); 781 - static jsval_t call_js_code_with_args_nfe(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *args, int nargs, jsval_t func_val); 803 + static jsval_t call_js_code_with_args(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *args, int nargs, jsval_t func_val); 782 804 783 805 static inline bool push_this(jsval_t this_value); 784 806 static inline jsval_t pop_this(void); 785 - static inline jsval_t peek_this(void); 786 807 787 - jsval_t js_get_proto(struct js *js, jsval_t obj); 788 - void js_set_proto(struct js *js, jsval_t obj, jsval_t proto); 789 - jsval_t js_setprop(struct js *js, jsval_t obj, jsval_t k, jsval_t v); 790 808 static jsoff_t lkp_proto(struct js *js, jsval_t obj, const char *key, size_t len); 791 - jsval_t js_get_ctor_proto(struct js *js, const char *name, size_t len); 792 809 static jsval_t get_prototype_for_type(struct js *js, uint8_t type); 793 - 794 - static jsval_t get_proto(struct js *js, jsval_t obj); 795 - static void set_proto(struct js *js, jsval_t obj, jsval_t proto); 796 810 static jsval_t get_ctor_proto(struct js *js, const char *name, size_t len); 797 811 static jsval_t setprop(struct js *js, jsval_t obj, jsval_t k, jsval_t v); 798 - static jsval_t setprop_nonconfigurable(struct js *js, jsval_t obj, const char *key, size_t keylen, jsval_t v); 799 - static jsoff_t lkp(struct js *js, jsval_t obj, const char *key, size_t len); 800 - static jsval_t resolveprop(struct js *js, jsval_t v); 801 812 static descriptor_entry_t *lookup_descriptor(jsoff_t obj_off, const char *key, size_t klen); 802 813 803 814 static jsval_t unwrap_primitive(struct js *js, jsval_t val) { ··· 828 839 } 829 840 } 830 841 } 842 + 831 843 const char *s = js_str(js, val); 832 844 return js_mkstr(js, s, strlen(s)); 833 845 } ··· 855 867 jsval_t result; 856 868 857 869 if (coro && coro->nargs > 0 && coro->args) { 858 - result = call_js_code_with_args(js, ctx->code, (jsoff_t)ctx->code_len, ctx->closure_scope, coro->args, coro->nargs); 859 - } else { 860 - result = call_js(js, ctx->code, (jsoff_t)ctx->code_len, ctx->closure_scope); 861 - } 870 + result = call_js_code_with_args(js, ctx->code, (jsoff_t)ctx->code_len, ctx->closure_scope, coro->args, coro->nargs, js_mkundef()); 871 + } else result = call_js(js, ctx->code, (jsoff_t)ctx->code_len, ctx->closure_scope); 862 872 863 873 ctx->result = result; 864 874 ctx->has_error = is_err(result); ··· 1840 1850 return n; 1841 1851 } 1842 1852 1853 + static const char *intern_string(const char *str, size_t len) { 1854 + uint64_t h = hash_key(str, len); 1855 + uint32_t bucket = (uint32_t)(h & (ANT_LIMIT_SIZE_CACHE - 1)); 1856 + 1857 + for (interned_string_t *e = intern_buckets[bucket]; e; e = e->next) { 1858 + if (e->hash == h && e->len == len && memcmp(e->str, str, len) == 0) return e->str; 1859 + } 1860 + 1861 + interned_string_t *entry = (interned_string_t *)malloc(sizeof(interned_string_t)); 1862 + if (!entry) return NULL; 1863 + entry->str = (char *)malloc(len + 1); 1864 + if (!entry->str) { free(entry); return NULL; } 1865 + 1866 + memcpy(entry->str, str, len); 1867 + entry->str[len] = '\0'; 1868 + entry->len = len; 1869 + entry->hash = h; 1870 + entry->next = intern_buckets[bucket]; 1871 + intern_buckets[bucket] = entry; 1872 + 1873 + return entry->str; 1874 + } 1875 + 1843 1876 static bool is_internal_prop(const char *key, jsoff_t klen) { 1844 1877 if (klen < 2) return false; 1845 1878 if (key[0] != '_' || key[1] != '_') return false; ··· 2811 2844 return (v & NONCONFIGMASK) != 0; 2812 2845 } 2813 2846 2814 - static inline uint64_t hash_key(const char *key, size_t len) { 2815 - uint64_t hash = 14695981039346656037ULL; 2816 - size_t i = 0; 2817 - for (; i + 8 <= len; i += 8) { 2818 - uint64_t word; 2819 - memcpy(&word, key + i, 8); 2820 - hash ^= word; 2821 - hash *= 1099511628211ULL; 2822 - } 2823 - for (; i < len; i++) { 2824 - hash ^= (uint8_t)key[i]; 2825 - hash *= 1099511628211ULL; 2826 - } 2827 - return hash; 2828 - } 2829 - 2830 - static const char *intern_string(const char *str, size_t len) { 2831 - uint64_t h = hash_key(str, len); 2832 - uint32_t bucket = (uint32_t)(h & (ANT_LIMIT_SIZE_CACHE - 1)); 2833 - 2834 - for (interned_string_t *e = intern_buckets[bucket]; e; e = e->next) { 2835 - if (e->hash == h && e->len == len && memcmp(e->str, str, len) == 0) return e->str; 2836 - } 2837 - 2838 - interned_string_t *entry = (interned_string_t *)malloc(sizeof(interned_string_t)); 2839 - if (!entry) return NULL; 2840 - entry->str = (char *)malloc(len + 1); 2841 - if (!entry->str) { free(entry); return NULL; } 2842 - 2843 - memcpy(entry->str, str, len); 2844 - entry->str[len] = '\0'; 2845 - entry->len = len; 2846 - entry->hash = h; 2847 - entry->next = intern_buckets[bucket]; 2848 - intern_buckets[bucket] = entry; 2849 - 2850 - return entry->str; 2851 - } 2852 - 2853 2847 static void intern_init(void) { 2854 2848 if (INTERN_LENGTH) return; 2855 2849 INTERN_LENGTH = intern_string("length", 6); ··· 2990 2984 2991 2985 static inline jsoff_t next_prop(jsoff_t header) { 2992 2986 return header & ~(3U | FLAGMASK); 2987 + } 2988 + 2989 + static double js_to_number(struct js *js, jsval_t arg) { 2990 + if (vtype(arg) == T_NUM) return tod(arg); 2991 + if (vtype(arg) == T_BOOL) return vdata(arg) ? 1.0 : 0.0; 2992 + if (vtype(arg) == T_NULL) return 0.0; 2993 + if (vtype(arg) == T_UNDEF) return NAN; 2994 + if (vtype(arg) == T_STR) { 2995 + jsoff_t len; 2996 + jsoff_t off = vstr(js, arg, &len); 2997 + const char *str = (char *) &js->mem[off]; 2998 + while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r') str++; 2999 + if (*str == '\0') return 0.0; 3000 + char *end; 3001 + double val = strtod(str, &end); 3002 + while (*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r') end++; 3003 + if (end == str || *end != '\0') return NAN; 3004 + return val; 3005 + } 3006 + return NAN; 2993 3007 } 2994 3008 2995 3009 static jsval_t setup_func_prototype(struct js *js, jsval_t func) { ··· 5116 5130 setprop_interned(js, scope, INTERN_ARGUMENTS, 9, arguments_obj); 5117 5131 } 5118 5132 5119 - static jsval_t call_js_internal(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *bound_args, int bound_argc) { 5120 - return call_js_internal_nfe(js, fn, fnlen, closure_scope, bound_args, bound_argc, js_mkundef()); 5121 - } 5122 - 5123 - static jsval_t call_js_internal_nfe(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *bound_args, int bound_argc, jsval_t func_val) { 5133 + static jsval_t call_js_internal(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *bound_args, int bound_argc, jsval_t func_val) { 5124 5134 jsval_t saved_scope = js->scope; 5125 5135 jsval_t saved_this_val = js->this_val; 5126 5136 jsval_t target_this = peek_this(); ··· 5275 5285 } 5276 5286 5277 5287 static jsval_t call_js(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope) { 5278 - return call_js_internal(js, fn, fnlen, closure_scope, NULL, 0); 5288 + return call_js_internal(js, fn, fnlen, closure_scope, NULL, 0, js_mkundef()); 5279 5289 } 5280 5290 5281 5291 static jsval_t call_js_with_args(struct js *js, jsval_t func, jsval_t *args, int nargs) { ··· 5365 5375 push_this(bound_this); 5366 5376 } 5367 5377 5368 - jsval_t result = call_js_code_with_args_nfe(js, fn, fnlen, closure_scope, args, nargs, func); 5369 - 5378 + jsval_t result = call_js_code_with_args(js, fn, fnlen, closure_scope, args, nargs, func); 5370 5379 if (combined_args) ANT_GC_FREE(combined_args); 5380 + 5371 5381 return result; 5372 5382 } 5373 5383 5374 - static jsval_t call_js_code_with_args(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *args, int nargs) { 5375 - return call_js_code_with_args_nfe(js, fn, fnlen, closure_scope, args, nargs, js_mkundef()); 5376 - } 5377 - 5378 - static jsval_t call_js_code_with_args_nfe(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *args, int nargs, jsval_t func_val) { 5384 + static jsval_t call_js_code_with_args(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *args, int nargs, jsval_t func_val) { 5379 5385 jsoff_t parent_scope_offset; 5380 5386 if (vtype(closure_scope) == T_OBJ) { 5381 5387 parent_scope_offset = (jsoff_t) vdata(closure_scope); 5382 - } else { 5383 - parent_scope_offset = (jsoff_t) vdata(js->scope); 5384 - } 5388 + } else parent_scope_offset = (jsoff_t) vdata(js->scope); 5385 5389 5386 5390 jsval_t saved_scope = js->scope; 5387 5391 if (global_scope_stack == NULL) utarray_new(global_scope_stack, &jsoff_icd); ··· 5767 5771 res = start_async_in_coroutine(js, code_str, fnlen, closure_scope, bound_args, bound_argc); 5768 5772 pop_call_frame(); 5769 5773 } else { 5770 - res = call_js_internal_nfe(js, code_str, fnlen, closure_scope, bound_args, bound_argc, func); 5774 + res = call_js_internal(js, code_str, fnlen, closure_scope, bound_args, bound_argc, func); 5771 5775 pop_call_frame(); 5772 5776 } 5773 5777 ··· 7330 7334 case TOK_FALSE: return js_mkfalse(); 7331 7335 case TOK_THIS: return js->this_val; 7332 7336 7333 - case TOK_OF: 7334 - case TOK_FOR: 7335 - case TOK_WITH: 7336 - case TOK_TYPEOF: 7337 - case TOK_FROM: 7338 - case TOK_VOID: 7339 - case TOK_DELETE: 7340 - case TOK_IMPORT: 7341 - case TOK_IDENTIFIER: 7342 - case TOK_CATCH: 7343 - case TOK_TRY: 7344 - case TOK_FINALLY: 7345 - case TOK_IF: 7346 - case TOK_ELSE: 7347 - case TOK_WHILE: 7348 - case TOK_DO: 7349 - case TOK_RETURN: 7350 - case TOK_BREAK: 7351 - case TOK_CONTINUE: 7352 - case TOK_VAR: 7353 - case TOK_NEW: 7354 - case TOK_THROW: 7355 - case TOK_SWITCH: 7356 - case TOK_CASE: 7357 - case TOK_DEFAULT: 7358 - case TOK_INSTANCEOF: 7359 - case TOK_IN: 7360 - case TOK_DEBUGGER: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 7361 - 7362 - default: { 7363 - char err_buf[64]; size_t tok_len = js->tlen > 20 ? 20 : js->tlen; 7337 + default: 7338 + if (is_identifier_like(js->tok)) { 7339 + return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 7340 + } 7341 + 7342 + char err_buf[64]; 7343 + size_t tok_len = js->tlen > 20 ? 20 : js->tlen; 7364 7344 snprintf(err_buf, sizeof(err_buf), "Unexpected token '%.*s'", (int)tok_len, &js->code[js->toff]); 7365 7345 return js_mkerr_typed(js, JS_ERR_SYNTAX, err_buf); 7366 - } 7367 7346 } 7368 7347 } 7369 7348 ··· 10881 10860 return memcmp(continue_target_label, name, len) == 0; 10882 10861 } 10883 10862 10884 - static void clear_break_label(void) { 10885 - break_target_label = NULL; 10886 - break_target_label_len = 0; 10887 - label_flags &= ~F_BREAK_LABEL; 10888 - } 10889 - 10890 - static void clear_continue_label(void) { 10891 - continue_target_label = NULL; 10892 - continue_target_label_len = 0; 10893 - label_flags &= ~F_CONTINUE_LABEL; 10894 - } 10895 - 10896 10863 static jsval_t js_labeled_stmt(struct js *js, const char *label, jsoff_t label_len) { 10897 10864 uint8_t flags = js->flags; 10898 10865 jsval_t res = js_mkundef(); ··· 11081 11048 11082 11049 double val = tod(arg); 11083 11050 return mkval(T_BOOL, isfinite(val) ? 1 : 0); 11084 - } 11085 - 11086 - static double js_to_number(struct js *js, jsval_t arg) { 11087 - if (vtype(arg) == T_NUM) return tod(arg); 11088 - if (vtype(arg) == T_BOOL) return vdata(arg) ? 1.0 : 0.0; 11089 - if (vtype(arg) == T_NULL) return 0.0; 11090 - if (vtype(arg) == T_UNDEF) return NAN; 11091 - if (vtype(arg) == T_STR) { 11092 - jsoff_t len; 11093 - jsoff_t off = vstr(js, arg, &len); 11094 - const char *str = (char *) &js->mem[off]; 11095 - while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r') str++; 11096 - if (*str == '\0') return 0.0; 11097 - char *end; 11098 - double val = strtod(str, &end); 11099 - while (*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r') end++; 11100 - if (end == str || *end != '\0') return NAN; 11101 - return val; 11102 - } 11103 - return NAN; 11104 11051 } 11105 11052 11106 11053 static jsval_t builtin_global_isNaN(struct js *js, jsval_t *args, int nargs) { ··· 20524 20471 } 20525 20472 20526 20473 struct js *js_create_dynamic(size_t initial_size, size_t max_size) { 20527 - if (initial_size < sizeof(struct js) + esize(T_OBJ)) initial_size = 1024 * 1024; 20474 + if (initial_size < sizeof(struct js) + esize(T_OBJ)) initial_size = 16 * 1024; 20528 20475 if (max_size == 0 || max_size < initial_size) max_size = 512 * 1024 * 1024; 20529 20476 20530 20477 void *buf = ANT_GC_MALLOC(initial_size); ··· 21267 21214 fprintf(stream, "\x1b[0m)\n"); 21268 21215 } 21269 21216 } 21270 - } 21271 - 21272 - jsval_t js_get_slot(struct js *js, jsval_t obj, internal_slot_t slot) { return get_slot(js, obj, slot); } 21273 - void js_set_slot(struct js *js, jsval_t obj, internal_slot_t slot, jsval_t value) { set_slot(js, obj, slot, value); } 21217 + }
+1 -1
src/main.c
··· 177 177 size_t initial_size = 16 * 1024; 178 178 size_t max_size = 512 * 1024 * 1024; 179 179 180 - if (initial_mem->count > 0) initial_size = (size_t)initial_mem->ival[0] * 1024 * 1024; 180 + if (initial_mem->count > 0) initial_size = (size_t)initial_mem->ival[0] * 16 * 1024; 181 181 if (max_mem->count > 0) max_size = (size_t)max_mem->ival[0] * 1024 * 1024; 182 182 if (no_color->count > 0) io_no_color = true; 183 183
+23
src/utils.c
··· 1 + #include "utils.h" 2 + 3 + #include <string.h> 4 + #include <stdint.h> 5 + 6 + uint64_t hash_key(const char *key, size_t len) { 7 + uint64_t hash = 14695981039346656037ULL; 8 + size_t i = 0; 9 + 10 + for (; i + 8 <= len; i += 8) { 11 + uint64_t word; 12 + memcpy(&word, key + i, 8); 13 + hash ^= word; 14 + hash *= 1099511628211ULL; 15 + } 16 + 17 + for (; i < len; i++) { 18 + hash ^= (uint8_t)key[i]; 19 + hash *= 1099511628211ULL; 20 + } 21 + 22 + return hash; 23 + }