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.

add new built-in regexp symbol methods for pattern matching and manipulation

+314 -50
+5
include/internal.h
··· 161 161 162 162 jsval_t coerce_to_str(struct js *js, jsval_t v); 163 163 jsval_t coerce_to_str_concat(struct js *js, jsval_t v); 164 + 164 165 jsval_t builtin_regexp_symbol_split(struct js *js, jsval_t *args, int nargs); 166 + jsval_t builtin_regexp_symbol_match(struct js *js, jsval_t *args, int nargs); 167 + jsval_t builtin_regexp_symbol_replace(struct js *js, jsval_t *args, int nargs); 168 + jsval_t builtin_regexp_symbol_search(struct js *js, jsval_t *args, int nargs); 169 + jsval_t builtin_regexp_flags_getter(struct js *js, jsval_t *args, int nargs); 165 170 166 171 js_intern_stats_t js_intern_stats(void); 167 172 js_cstr_t js_to_cstr(struct js *js, jsval_t value, char *stack_buf, size_t stack_size);
+255 -48
src/ant.c
··· 9335 9335 return arr; 9336 9336 } 9337 9337 9338 + static void regexp_init_flags(struct js *js, jsval_t obj, const char *fstr, jsoff_t flen) { 9339 + bool g = false, i = false, m = false, s = false, y = false; 9340 + for (jsoff_t k = 0; k < flen; k++) { 9341 + if (fstr[k] == 'g') g = true; 9342 + if (fstr[k] == 'i') i = true; 9343 + if (fstr[k] == 'm') m = true; 9344 + if (fstr[k] == 's') s = true; 9345 + if (fstr[k] == 'y') y = true; 9346 + } 9347 + 9348 + char sorted[8]; int si = 0; 9349 + if (g) sorted[si++] = 'g'; 9350 + if (i) sorted[si++] = 'i'; 9351 + if (m) sorted[si++] = 'm'; 9352 + if (s) sorted[si++] = 's'; 9353 + if (y) sorted[si++] = 'y'; 9354 + 9355 + js_setprop(js, obj, js_mkstr(js, "flags", 5), js_mkstr(js, sorted, si)); 9356 + js_setprop(js, obj, js_mkstr(js, "global", 6), mkval(T_BOOL, g ? 1 : 0)); 9357 + js_setprop(js, obj, js_mkstr(js, "ignoreCase", 10), mkval(T_BOOL, i ? 1 : 0)); 9358 + js_setprop(js, obj, js_mkstr(js, "multiline", 9), mkval(T_BOOL, m ? 1 : 0)); 9359 + js_setprop(js, obj, js_mkstr(js, "dotAll", 6), mkval(T_BOOL, s ? 1 : 0)); 9360 + js_setprop(js, obj, js_mkstr(js, "sticky", 6), mkval(T_BOOL, y ? 1 : 0)); 9361 + js_setprop(js, obj, js_mkstr(js, "lastIndex", 9), tov(0)); 9362 + } 9363 + 9338 9364 static jsval_t js_regex_literal(struct js *js) { 9339 9365 jsoff_t start = js->pos; 9340 9366 jsoff_t pattern_start = start; ··· 9364 9390 char c = js->code[js->pos]; 9365 9391 if (c == 'g' || c == 'i' || c == 'm' || c == 's' || c == 'u' || c == 'y') { 9366 9392 js->pos++; 9367 - } else { 9368 - break; 9369 - } 9393 + } else break; 9370 9394 } 9371 - jsoff_t flags_end = js->pos; 9372 9395 9396 + jsoff_t flags_end = js->pos; 9373 9397 if (js->flags & F_NOEXEC) return js_mkundef(); 9374 9398 9375 9399 jsval_t pattern = js_mkstr(js, &js->code[pattern_start], pattern_end - pattern_start); 9376 - jsval_t flags = js_mkstr(js, &js->code[flags_start], flags_end - flags_start); 9400 + jsval_t regexp_obj = mkobj(js, 0); 9377 9401 9378 - jsval_t regexp_obj = mkobj(js, 0); 9379 9402 jsval_t regexp_proto = get_ctor_proto(js, "RegExp", 6); 9380 9403 if (vtype(regexp_proto) == T_OBJ) set_proto(js, regexp_obj, regexp_proto); 9381 9404 9382 9405 js_setprop(js, regexp_obj, js_mkstr(js, "source", 6), pattern); 9383 - js_setprop(js, regexp_obj, js_mkstr(js, "flags", 5), flags); 9384 - 9385 - jsoff_t flen = flags_end - flags_start; 9386 - const char *fstr = &js->code[flags_start]; 9387 - bool global = false, ignoreCase = false, multiline = false, dotAll = false, sticky = false; 9388 - for (jsoff_t i = 0; i < flen; i++) { 9389 - if (fstr[i] == 'g') global = true; 9390 - if (fstr[i] == 'i') ignoreCase = true; 9391 - if (fstr[i] == 'm') multiline = true; 9392 - if (fstr[i] == 's') dotAll = true; 9393 - if (fstr[i] == 'y') sticky = true; 9394 - } 9395 - 9396 - js_setprop(js, regexp_obj, js_mkstr(js, "global", 6), mkval(T_BOOL, global ? 1 : 0)); 9397 - js_setprop(js, regexp_obj, js_mkstr(js, "ignoreCase", 10), mkval(T_BOOL, ignoreCase ? 1 : 0)); 9398 - js_setprop(js, regexp_obj, js_mkstr(js, "multiline", 9), mkval(T_BOOL, multiline ? 1 : 0)); 9399 - js_setprop(js, regexp_obj, js_mkstr(js, "dotAll", 6), mkval(T_BOOL, dotAll ? 1 : 0)); 9400 - js_setprop(js, regexp_obj, js_mkstr(js, "sticky", 6), mkval(T_BOOL, sticky ? 1 : 0)); 9401 - js_setprop(js, regexp_obj, js_mkstr(js, "lastIndex", 9), tov(0)); 9406 + regexp_init_flags(js, regexp_obj, &js->code[flags_start], flags_end - flags_start); 9402 9407 9403 9408 return regexp_obj; 9404 9409 } ··· 15141 15146 } 15142 15147 } 15143 15148 15144 - jsval_t source_key = js_mkstr(js, "source", 6); 15145 - js_setprop(js, regexp_obj, source_key, pattern); 15146 - 15147 - jsval_t flags_key = js_mkstr(js, "flags", 5); 15148 - js_setprop(js, regexp_obj, flags_key, flags); 15149 - 15149 + js_setprop(js, regexp_obj, js_mkstr(js, "source", 6), pattern); 15150 15150 jsoff_t flags_len, flags_off = vstr(js, flags, &flags_len); 15151 - const char *flags_str = (char *) &js->mem[flags_off]; 15152 - 15153 - bool global = false, ignoreCase = false, multiline = false, dotAll = false, sticky = false; 15154 - for (jsoff_t i = 0; i < flags_len; i++) { 15155 - if (flags_str[i] == 'g') global = true; 15156 - if (flags_str[i] == 'i') ignoreCase = true; 15157 - if (flags_str[i] == 'm') multiline = true; 15158 - if (flags_str[i] == 's') dotAll = true; 15159 - if (flags_str[i] == 'y') sticky = true; 15160 - } 15161 - 15162 - js_setprop(js, regexp_obj, js_mkstr(js, "global", 6), mkval(T_BOOL, global ? 1 : 0)); 15163 - js_setprop(js, regexp_obj, js_mkstr(js, "ignoreCase", 10), mkval(T_BOOL, ignoreCase ? 1 : 0)); 15164 - js_setprop(js, regexp_obj, js_mkstr(js, "multiline", 9), mkval(T_BOOL, multiline ? 1 : 0)); 15165 - js_setprop(js, regexp_obj, js_mkstr(js, "dotAll", 6), mkval(T_BOOL, dotAll ? 1 : 0)); 15166 - js_setprop(js, regexp_obj, js_mkstr(js, "sticky", 6), mkval(T_BOOL, sticky ? 1 : 0)); 15167 - js_setprop(js, regexp_obj, js_mkstr(js, "lastIndex", 9), tov(0)); 15151 + regexp_init_flags(js, regexp_obj, (const char *)&js->mem[flags_off], flags_len); 15168 15152 15169 15153 return regexp_obj; 15170 15154 } ··· 15419 15403 jsval_t result = regexp_exec_abstract(js, regexp, str_arg); 15420 15404 if (is_err(result)) return result; 15421 15405 return mkval(T_BOOL, vtype(result) != T_NULL ? 1 : 0); 15406 + } 15407 + 15408 + jsval_t builtin_regexp_flags_getter(struct js *js, jsval_t *args, int nargs) { 15409 + jsval_t rx = js->this_val; 15410 + if (!is_object_type(rx)) 15411 + return js_mkerr_typed(js, JS_ERR_TYPE, "RegExp.prototype.flags called on non-object"); 15412 + 15413 + char static_buf[16]; string_builder_t sb; 15414 + string_builder_init(&sb, static_buf, sizeof(static_buf)); 15415 + 15416 + static const struct { const char *name; size_t len; char flag; } flag_props[] = { 15417 + {"hasIndices", 10, 'd'}, {"global", 6, 'g'}, {"ignoreCase", 10, 'i'}, 15418 + {"multiline", 9, 'm'}, {"dotAll", 6, 's'}, {"unicode", 7, 'u'}, 15419 + {"unicodeSets", 11, 'v'}, {"sticky", 6, 'y'}, 15420 + }; 15421 + 15422 + for (int i = 0; i < 8; i++) { 15423 + jsval_t v = js_getprop_fallback(js, rx, flag_props[i].name); 15424 + if (is_err(v)) { if (sb.is_dynamic) free(sb.buffer); return v; } 15425 + if (js_truthy(js, v)) string_builder_append(&sb, &flag_props[i].flag, 1); 15426 + } 15427 + 15428 + return string_builder_finalize(js, &sb); 15429 + } 15430 + 15431 + jsval_t builtin_regexp_symbol_match(struct js *js, jsval_t *args, int nargs) { 15432 + jsval_t rx = js->this_val; 15433 + if (!is_object_type(rx)) 15434 + return js_mkerr_typed(js, JS_ERR_TYPE, "RegExp.prototype[@@match] called on non-object"); 15435 + 15436 + jsval_t str = nargs > 0 ? js_tostring_val(js, args[0]) : js_mkstr(js, "undefined", 9); 15437 + if (is_err(str)) return str; 15438 + 15439 + jsval_t global_val = js_getprop_fallback(js, rx, "global"); 15440 + if (is_err(global_val)) return global_val; 15441 + 15442 + if (!js_truthy(js, global_val)) 15443 + return regexp_exec_abstract(js, rx, str); 15444 + 15445 + jsval_t unicode_val = js_getprop_fallback(js, rx, "unicode"); 15446 + if (is_err(unicode_val)) return unicode_val; 15447 + 15448 + bool full_unicode = js_truthy(js, unicode_val); 15449 + js_setprop(js, rx, js_mkstr(js, "lastIndex", 9), tov(0)); 15450 + 15451 + jsval_t A = mkarr(js); 15452 + if (is_err(A)) return A; 15453 + jsoff_t n = 0; 15454 + 15455 + for (;;) { 15456 + jsval_t result = regexp_exec_abstract(js, rx, str); 15457 + if (is_err(result)) return result; 15458 + if (vtype(result) == T_NULL) return n == 0 ? js_mknull() : mkval(T_ARR, vdata(A)); 15459 + 15460 + jsval_t match_str = js_tostring_val(js, arr_get(js, result, 0)); 15461 + if (is_err(match_str)) return match_str; 15462 + arr_set(js, A, n++, match_str); 15463 + 15464 + jsoff_t mlen; 15465 + vstr(js, match_str, &mlen); 15466 + if (mlen == 0) { 15467 + jsval_t li_val = js_getprop_fallback(js, rx, "lastIndex"); 15468 + if (is_err(li_val)) return li_val; 15469 + double li = vtype(li_val) == T_NUM ? tod(li_val) : 0; 15470 + jsoff_t str_len, str_off = vstr(js, str, &str_len); 15471 + double advance = 1; 15472 + if (full_unicode && li < (double)str_len) { 15473 + advance = (double)utf8_char_len_at((const char *)&js->mem[str_off], str_len, (jsoff_t)li); 15474 + } js_setprop(js, rx, js_mkstr(js, "lastIndex", 9), tov(li + advance)); 15475 + } 15476 + } 15477 + } 15478 + 15479 + jsval_t builtin_regexp_symbol_replace(struct js *js, jsval_t *args, int nargs) { 15480 + jsval_t rx = js->this_val; 15481 + if (!is_object_type(rx)) 15482 + return js_mkerr_typed(js, JS_ERR_TYPE, "RegExp.prototype[@@replace] called on non-object"); 15483 + 15484 + jsval_t str = nargs > 0 ? js_tostring_val(js, args[0]) : js_mkstr(js, "undefined", 9); 15485 + if (is_err(str)) return str; 15486 + jsval_t replace_value = nargs > 1 ? args[1] : js_mkundef(); 15487 + bool func_replace = (vtype(replace_value) == T_FUNC || vtype(replace_value) == T_CFUNC); 15488 + jsval_t replace_str = js_mkundef(); 15489 + if (!func_replace) { 15490 + replace_str = js_tostring_val(js, replace_value); 15491 + if (is_err(replace_str)) return replace_str; 15492 + } 15493 + 15494 + jsval_t global_val = js_getprop_fallback(js, rx, "global"); 15495 + if (is_err(global_val)) return global_val; 15496 + bool global = js_truthy(js, global_val); 15497 + 15498 + bool full_unicode = false; 15499 + if (global) { 15500 + jsval_t unicode_val = js_getprop_fallback(js, rx, "unicode"); 15501 + if (is_err(unicode_val)) return unicode_val; 15502 + full_unicode = js_truthy(js, unicode_val); 15503 + js_setprop(js, rx, js_mkstr(js, "lastIndex", 9), tov(0)); 15504 + } 15505 + 15506 + jsval_t results = mkarr(js); 15507 + if (is_err(results)) return results; 15508 + jsoff_t nresults = 0; 15509 + 15510 + for (;;) { 15511 + jsval_t result = regexp_exec_abstract(js, rx, str); 15512 + if (is_err(result)) return result; 15513 + if (vtype(result) == T_NULL) break; 15514 + arr_set(js, results, nresults++, result); 15515 + if (!global) break; 15516 + 15517 + jsval_t match_str = js_tostring_val(js, arr_get(js, result, 0)); 15518 + if (is_err(match_str)) return match_str; 15519 + jsoff_t mlen; vstr(js, match_str, &mlen); 15520 + if (mlen == 0) { 15521 + jsval_t li_val = js_getprop_fallback(js, rx, "lastIndex"); 15522 + if (is_err(li_val)) return li_val; 15523 + double li = vtype(li_val) == T_NUM ? tod(li_val) : 0; 15524 + jsoff_t sl, so = vstr(js, str, &sl); 15525 + double advance = 1; 15526 + if (full_unicode && li < (double)sl) { 15527 + advance = (double)utf8_char_len_at((const char *)&js->mem[so], sl, (jsoff_t)li); 15528 + } 15529 + js_setprop(js, rx, js_mkstr(js, "lastIndex", 9), tov(li + advance)); 15530 + } 15531 + } 15532 + 15533 + jsoff_t str_len, str_off = vstr(js, str, &str_len); 15534 + char static_buf[256]; 15535 + string_builder_t sb; 15536 + string_builder_init(&sb, static_buf, sizeof(static_buf)); 15537 + jsoff_t next_src_pos = 0; 15538 + 15539 + for (jsoff_t i = 0; i < nresults; i++) { 15540 + jsval_t result = arr_get(js, results, i); 15541 + jsval_t matched = js_tostring_val(js, arr_get(js, result, 0)); 15542 + if (is_err(matched)) { if (sb.is_dynamic) free(sb.buffer); return matched; } 15543 + jsoff_t matched_len; vstr(js, matched, &matched_len); 15544 + 15545 + jsval_t pos_val = js_getprop_fallback(js, result, "index"); 15546 + jsoff_t position = 0; 15547 + if (!is_err(pos_val) && vtype(pos_val) == T_NUM) { 15548 + double d = tod(pos_val); 15549 + position = d < 0 ? 0 : (jsoff_t)d; 15550 + } 15551 + if (position > str_len) position = str_len; 15552 + 15553 + jsval_t replacement; 15554 + if (func_replace) { 15555 + jsoff_t ncaptures = get_array_length(js, result); 15556 + jsval_t call_args[32]; 15557 + int ca = 0; 15558 + for (jsoff_t c = 0; c < ncaptures && ca < 30; c++) 15559 + call_args[ca++] = arr_get(js, result, c); 15560 + call_args[ca++] = tov((double)position); 15561 + call_args[ca++] = str; 15562 + replacement = js_call_with_this(js, replace_value, js_mkundef(), call_args, ca); 15563 + } else { 15564 + replacement = replace_str; 15565 + } 15566 + if (is_err(replacement)) { if (sb.is_dynamic) free(sb.buffer); return replacement; } 15567 + jsval_t rep_str = js_tostring_val(js, replacement); 15568 + if (is_err(rep_str)) { if (sb.is_dynamic) free(sb.buffer); return rep_str; } 15569 + 15570 + if (position >= next_src_pos) { 15571 + str_off = vstr(js, str, &str_len); 15572 + if (position > next_src_pos) 15573 + string_builder_append(&sb, (const char *)&js->mem[str_off + next_src_pos], position - next_src_pos); 15574 + jsoff_t rep_len, rep_off = vstr(js, rep_str, &rep_len); 15575 + string_builder_append(&sb, (const char *)&js->mem[rep_off], rep_len); 15576 + next_src_pos = position + matched_len; 15577 + } 15578 + } 15579 + 15580 + str_off = vstr(js, str, &str_len); 15581 + if (next_src_pos < str_len) 15582 + string_builder_append(&sb, (const char *)&js->mem[str_off + next_src_pos], str_len - next_src_pos); 15583 + 15584 + return string_builder_finalize(js, &sb); 15585 + } 15586 + 15587 + jsval_t builtin_regexp_symbol_search(struct js *js, jsval_t *args, int nargs) { 15588 + jsval_t rx = js->this_val; 15589 + if (!is_object_type(rx)) 15590 + return js_mkerr_typed(js, JS_ERR_TYPE, "RegExp.prototype[@@search] called on non-object"); 15591 + 15592 + jsval_t str = nargs > 0 ? js_tostring_val(js, args[0]) : js_mkstr(js, "undefined", 9); 15593 + if (is_err(str)) return str; 15594 + 15595 + jsval_t prev_li = js_getprop_fallback(js, rx, "lastIndex"); 15596 + if (is_err(prev_li)) return prev_li; 15597 + js_setprop(js, rx, js_mkstr(js, "lastIndex", 9), tov(0)); 15598 + 15599 + jsval_t result = regexp_exec_abstract(js, rx, str); 15600 + if (is_err(result)) return result; 15601 + 15602 + jsval_t cur_li = js_getprop_fallback(js, rx, "lastIndex"); 15603 + if (is_err(cur_li)) return cur_li; 15604 + js_setprop(js, rx, js_mkstr(js, "lastIndex", 9), prev_li); 15605 + 15606 + if (vtype(result) == T_NULL) return tov(-1); 15607 + 15608 + jsval_t idx = js_getprop_fallback(js, result, "index"); 15609 + if (is_err(idx)) return idx; 15610 + return vtype(idx) == T_NUM ? idx : tov(-1); 15422 15611 } 15423 15612 15424 15613 jsval_t builtin_regexp_symbol_split(struct js *js, jsval_t *args, int nargs) { ··· 23742 23931 js_setprop(js, regexp_proto, js_mkstr(js, "exec", 4), js_mkfun(builtin_regexp_exec)); 23743 23932 js_setprop(js, regexp_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_regexp_toString)); 23744 23933 23934 + js_mkprop_fast(js, regexp_proto, "global", 6, js_false); 23935 + js_mkprop_fast(js, regexp_proto, "ignoreCase", 10, js_false); 23936 + js_mkprop_fast(js, regexp_proto, "multiline", 9, js_false); 23937 + js_mkprop_fast(js, regexp_proto, "dotAll", 6, js_false); 23938 + js_mkprop_fast(js, regexp_proto, "unicode", 7, js_false); 23939 + js_mkprop_fast(js, regexp_proto, "sticky", 6, js_false); 23940 + js_mkprop_fast(js, regexp_proto, "hasIndices", 10, js_false); 23941 + js_mkprop_fast(js, regexp_proto, "unicodeSets", 11, js_false); 23942 + 23745 23943 jsval_t promise_proto = js_mkobj(js); 23746 23944 set_proto(js, promise_proto, object_proto); 23747 23945 js_setprop(js, promise_proto, js_mkstr(js, "then", 4), js_mkfun(builtin_promise_then)); ··· 24733 24931 js->this_val = saved_this; 24734 24932 24735 24933 if (combined_args) free(combined_args); 24934 + return res; 24935 + } 24936 + 24937 + jsval_t builtin_slot = get_slot(js, func_obj, SLOT_BUILTIN); 24938 + if (vtype(builtin_slot) == T_NUM && (int)tod(builtin_slot) == BUILTIN_OBJECT) { 24939 + jsval_t saved_this = js->this_val; 24940 + if (use_bound_this) js->this_val = bound_this; 24941 + jsval_t res = builtin_Object(js, args, nargs); 24942 + js->this_val = saved_this; 24736 24943 return res; 24737 24944 } 24738 24945
+50 -2
src/main.c
··· 120 120 print_flag(stdout, (flag_help_t){ .l = "no-color", .g = "disable colored output" }); 121 121 } 122 122 123 + typedef struct { 124 + int argc; 125 + char **argv; 126 + } argv_split_t; 127 + 128 + static bool is_valued_flag(const char *arg) { 129 + return 130 + strcmp(arg, "-e") == 0 || 131 + strcmp(arg, "--eval") == 0 || 132 + strcmp(arg, "--localstorage-file") == 0; 133 + } 134 + 123 135 static int find_argv_token_index(int argc, char **argv, const char *token) { 124 136 if (!token) return -1; 125 137 for (int i = 1; i < argc; i++) if (argv[i] == token) return i; 126 138 return -1; 127 139 } 128 140 141 + static argv_split_t split_script_args(int *argc, char **argv) { 142 + for (int i = 1; i < *argc; i++) { 143 + if (strcmp(argv[i], "--") == 0) { 144 + argv_split_t tail = { *argc - i - 1, argv + i + 1 }; 145 + *argc = i; 146 + return tail; 147 + } 148 + if (argv[i][0] == '-') { 149 + if (is_valued_flag(argv[i]) && i + 1 < *argc) i++; 150 + continue; 151 + } 152 + argv_split_t tail = { *argc - i - 1, argv + i + 1 }; 153 + *argc = i + 1; 154 + return tail; 155 + } 156 + return (argv_split_t){ 0, NULL }; 157 + } 158 + 159 + static argv_split_t build_process_argv(int argc, char **argv, const char *module, argv_split_t script) { 160 + if (!module || script.argc == 0) return (argv_split_t){ argc, argv }; 161 + 162 + int total = 2 + script.argc; 163 + char **out = try_oom(sizeof(char*) * (total + 1)); 164 + 165 + out[0] = argv[0]; out[1] = (char *)module; 166 + for (int i = 0; i < script.argc; i++) out[2 + i] = script.argv[i]; 167 + out[total] = NULL; 168 + 169 + return (argv_split_t){ total, out }; 170 + } 171 + 129 172 static char *read_stdin(size_t *len) { 130 173 size_t cap = 4096; 131 174 *len = 0; ··· 286 329 else filtered_argv[filtered_argc++] = argv[i]; 287 330 } 288 331 289 - argc = filtered_argc; 332 + argc = filtered_argc; 290 333 argv = filtered_argv; 334 + 335 + argv_split_t script_tail = split_script_args(&argc, argv); 336 + argv_split_t proc_argv = { 0, NULL }; 291 337 292 338 #define ARG_ITEMS(X) \ 293 339 X(struct arg_str *, eval, arg_str0("e", "eval", "<script>", "evaluate script")) \ ··· 311 357 #undef REF 312 358 313 359 #define CLEANUP_ARGS_AND_ARGV() ({ \ 360 + if (proc_argv.argv != argv) free(proc_argv.argv); \ 314 361 arg_freetable(argtable, ARGTABLE_COUNT); \ 315 362 free(filtered_argv); \ 316 363 }) ··· 440 487 } 441 488 442 489 js_setstackbase(js, (void *)&stack_base); 443 - ant_runtime_init(js, argc, argv, localstorage_file); 490 + proc_argv = build_process_argv(argc, argv, module_file, script_tail); 491 + ant_runtime_init(js, proc_argv.argc, proc_argv.argv, localstorage_file); 444 492 445 493 init_symbol_module(); 446 494 init_collections_module();
+4
src/modules/symbol.c
··· 384 384 jsval_t regexp_ctor = js_get(js, js_glob(js), "RegExp"); 385 385 jsval_t regexp_proto = js_get(js, regexp_ctor, "prototype"); 386 386 js_set(js, regexp_proto, g_split.key, js_mkfun(builtin_regexp_symbol_split)); 387 + js_set(js, regexp_proto, g_match.key, js_mkfun(builtin_regexp_symbol_match)); 388 + js_set(js, regexp_proto, g_replace.key, js_mkfun(builtin_regexp_symbol_replace)); 389 + js_set(js, regexp_proto, g_search.key, js_mkfun(builtin_regexp_symbol_search)); 390 + js_set_getter_desc(js, regexp_proto, "flags", 5, js_mkfun(builtin_regexp_flags_getter), JS_DESC_C); 387 391 388 392 jsval_t promise_ctor = js_get(js, js_glob(js), "Promise"); 389 393 jsval_t promise_proto = js_get(js, promise_ctor, "prototype");