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.

improve function name support es6

+322 -77
+10 -10
examples/results.txt
··· 514 514 compat-table/es6/Array.prototype.splice.js: failed 515 515 compat-table/es6/Array.prototype.values.js: OK 516 516 compat-table/es6/Date.prototype.Symbol.toPrimitive.js: OK 517 - compat-table/es6/Function.name.accessor.js: failed 518 - compat-table/es6/Function.name.bound.js: failed 517 + compat-table/es6/Function.name.accessor.js: OK 518 + compat-table/es6/Function.name.bound.js: OK 519 519 compat-table/es6/Function.name.class-expression.js: OK 520 - compat-table/es6/Function.name.class-object-method.js: failed 521 - compat-table/es6/Function.name.class-prototype.js: failed 520 + compat-table/es6/Function.name.class-object-method.js: OK 521 + compat-table/es6/Function.name.class-prototype.js: OK 522 522 compat-table/es6/Function.name.class-statement.js: OK 523 - compat-table/es6/Function.name.class-static.js: failed 524 - compat-table/es6/Function.name.class-variable.js: failed 525 - compat-table/es6/Function.name.configurable.js: failed 523 + compat-table/es6/Function.name.class-static.js: OK 524 + compat-table/es6/Function.name.class-variable.js: OK 525 + compat-table/es6/Function.name.configurable.js: OK 526 526 compat-table/es6/Function.name.expression.js: OK 527 - compat-table/es6/Function.name.new-Function.js: failed 527 + compat-table/es6/Function.name.new-Function.js: OK 528 528 compat-table/es6/Function.name.object-method.js: OK 529 529 compat-table/es6/Function.name.shorthand.js: OK 530 530 compat-table/es6/Function.name.shorthand.no-lexical.js: OK 531 531 compat-table/es6/Function.name.statement.js: OK 532 - compat-table/es6/Function.name.symbol-keyed.js: failed 533 - compat-table/es6/Function.name.variable.js: failed 532 + compat-table/es6/Function.name.symbol-keyed.js: OK 533 + compat-table/es6/Function.name.variable.js: OK 534 534 compat-table/es6/Map.Symbol.species.js: OK 535 535 compat-table/es6/Map.constructor-accepts-null.js: OK 536 536 compat-table/es6/Map.constructor-arguments.js: OK
+22 -3
include/internal.h
··· 451 451 ant_value_t js_delete_prop(ant_t *js, ant_value_t obj, const char *key, size_t len); 452 452 ant_value_t js_delete_sym_prop(ant_t *js, ant_value_t obj, ant_value_t sym); 453 453 454 + ant_value_t js_cfunc_promote(ant_t *js, ant_value_t cfunc); 455 + ant_value_t js_cfunc_expose_named(ant_t *js, ant_value_t cfunc, const char *name, size_t name_len); 456 + ant_value_t js_set_function_name(ant_t *js, ant_value_t fn, const char *name, size_t name_len); 457 + 458 + ant_value_t js_set_function_name_prefixed( 459 + ant_t *js, ant_value_t fn, 460 + const char *prefix, size_t prefix_len, 461 + const char *name, size_t name_len 462 + ); 463 + 464 + ant_value_t js_set_function_name_from_key( 465 + ant_t *js, ant_value_t fn, 466 + ant_value_t key, 467 + const char *prefix, size_t prefix_len 468 + ); 469 + 470 + ant_value_t js_maybe_set_function_name_from_key( 471 + ant_t *js, ant_value_t fn, 472 + ant_value_t key, 473 + const char *prefix, size_t prefix_len 474 + ); 475 + 454 476 bool is_proxy(ant_value_t obj); 455 477 bool strict_eq_values(ant_t *js, ant_value_t l, ant_value_t r); 456 478 bool js_deep_equal(ant_t *js, ant_value_t a, ant_value_t b, bool strict); ··· 627 649 js_set(js, ctor_fn, "default", ctor_fn); 628 650 js_set_slot_wb(js, lib, SLOT_DEFAULT, ctor_fn); 629 651 } 630 - 631 - ant_value_t js_cfunc_promote(ant_t *js, ant_value_t cfunc); 632 - ant_value_t js_cfunc_expose_named(ant_t *js, ant_value_t cfunc, const char *name, size_t name_len); 633 652 634 653 static inline ant_value_t js_cfunc_lookup_promoted(ant_t *js, ant_value_t cfunc) { 635 654 uintptr_t ptr = vdata(cfunc);
+6
include/silver/engine.h
··· 16 16 #include <stdio.h> 17 17 18 18 typedef enum { 19 + SV_DEFINE_METHOD_GETTER = 1u << 0, 20 + SV_DEFINE_METHOD_SETTER = 1u << 1, 21 + SV_DEFINE_METHOD_SET_NAME = 1u << 2, 22 + } sv_define_method_flags_t; 23 + 24 + typedef enum { 19 25 #define OP_DEF(name, size, n_pop, n_push, f) OP_##name, 20 26 #include "silver/opcode.h" 21 27 OP__COUNT
+1 -1
include/silver/glue.h
··· 128 128 ); 129 129 130 130 void jit_helper_set_name( 131 - sv_vm_t *vm, ant_t *js, ant_value_t fn, 131 + ant_t *js, ant_value_t fn, 132 132 const char *str, uint32_t len 133 133 ); 134 134
+155
src/ant.c
··· 5306 5306 } 5307 5307 5308 5308 set_slot(func_obj, SLOT_CFUNC, js_mkfun(builtin_function_empty)); 5309 + ant_value_t name_result = js_set_function_name(js, func_obj, "anonymous", 9); 5310 + 5311 + if (is_err(name_result)) return name_result; 5309 5312 ant_value_t func = js_obj_to_func(func_obj); 5310 5313 5311 5314 if (!is_async || is_generator) { ··· 5396 5399 5397 5400 display[n] = '\0'; 5398 5401 set_func_code(js, func_obj, display, display_len); 5402 + 5403 + ant_value_t name_result = js_set_function_name(js, func_obj, "anonymous", 9); 5404 + if (is_err(name_result)) { 5405 + free(display); 5406 + free(code_buf); 5407 + return name_result; 5408 + } 5399 5409 5400 5410 free(display); 5401 5411 free(code_buf); ··· 5652 5662 int bound_length = orig_length - bound_argc; 5653 5663 if (bound_length < 0) bound_length = 0; 5654 5664 5665 + const char *target_name = ""; 5666 + size_t target_name_len = 0; 5667 + ant_value_t target_name_val = js_mkundef(); 5668 + if (vtype(func) == T_CFUNC) { 5669 + const ant_cfunc_meta_t *meta = js_as_cfunc_meta(func); 5670 + if (meta && meta->name) { 5671 + target_name = meta->name; 5672 + target_name_len = strlen(meta->name); 5673 + } 5674 + } else { 5675 + target_name_val = js_getprop_fallback(js, func, "name"); 5676 + } 5677 + if (vtype(target_name_val) == T_STR) { 5678 + ant_offset_t nlen = 0; 5679 + ant_offset_t noff = vstr(js, target_name_val, &nlen); 5680 + target_name = (const char *)(uintptr_t)noff; 5681 + target_name_len = (size_t)nlen; 5682 + } 5683 + 5655 5684 if (vtype(func) == T_CFUNC) { 5656 5685 ant_value_t bound_func = mkobj(js, 0); 5657 5686 if (is_err(bound_func)) return bound_func; ··· 5671 5700 } 5672 5701 5673 5702 js_setprop(js, bound_func, js->length_str, tov((double) bound_length)); 5703 + ant_value_t name_result = js_set_function_name_prefixed( 5704 + js, bound_func, "bound ", 6, target_name, target_name_len 5705 + ); 5706 + if (is_err(name_result)) return name_result; 5674 5707 ant_value_t proto_setup = setup_func_prototype(js, bound); 5675 5708 5676 5709 if (is_err(proto_setup)) return proto_setup; ··· 5749 5782 } 5750 5783 5751 5784 js_setprop(js, bound_func, js->length_str, tov((double) bound_length)); 5785 + ant_value_t name_result = js_set_function_name_prefixed( 5786 + js, bound_func, "bound ", 6, 5787 + target_name, target_name_len 5788 + ); 5752 5789 5790 + if (is_err(name_result)) return name_result; 5753 5791 ant_value_t bound = mkval(T_FUNC, (uintptr_t)bound_closure); 5754 5792 ant_value_t proto_setup = setup_func_prototype(js, bound); 5755 5793 ··· 15062 15100 15063 15101 static ant_value_t js_cfunc_length_value(ant_value_t cfunc) { 15064 15102 return tov((double)js_cfunc_length(cfunc)); 15103 + } 15104 + 15105 + ant_value_t js_set_function_name(ant_t *js, ant_value_t fn, const char *name, size_t name_len) { 15106 + ant_value_t fn_obj = js_as_obj(fn); 15107 + ant_object_t *ptr = js_obj_ptr(fn_obj); 15108 + 15109 + if (!ptr) return js_mkundef(); 15110 + if (!name) { 15111 + name = ""; 15112 + name_len = 0; 15113 + } 15114 + 15115 + const char *name_key = js->intern.name ? js->intern.name : intern_string("name", 4); 15116 + if (!name_key) return js_mkerr(js, "oom"); 15117 + 15118 + ant_value_t name_val = js_mkstr(js, name, name_len); 15119 + if (is_err(name_val)) return name_val; 15120 + 15121 + return mkprop_interned_exact( 15122 + js, fn_obj, name_key, name_val, 15123 + ANT_PROP_ATTR_CONFIGURABLE 15124 + ); 15125 + } 15126 + 15127 + ant_value_t js_set_function_name_prefixed( 15128 + ant_t *js, ant_value_t fn, 15129 + const char *prefix, size_t prefix_len, 15130 + const char *name, size_t name_len 15131 + ) { 15132 + if (!prefix || prefix_len == 0) 15133 + return js_set_function_name(js, fn, name, name_len); 15134 + 15135 + if (!name) { 15136 + name = ""; 15137 + name_len = 0; 15138 + } 15139 + 15140 + char stack_buf[128]; 15141 + size_t total = prefix_len + name_len; 15142 + 15143 + char *buf = (total + 1 <= sizeof(stack_buf)) ? stack_buf : malloc(total + 1); 15144 + if (!buf) return js_mkerr(js, "oom"); 15145 + 15146 + memcpy(buf, prefix, prefix_len); 15147 + memcpy(buf + prefix_len, name, name_len); 15148 + buf[total] = '\0'; 15149 + 15150 + ant_value_t result = js_set_function_name(js, fn, buf, total); 15151 + if (buf != stack_buf) free(buf); 15152 + 15153 + return result; 15154 + } 15155 + 15156 + ant_value_t js_set_function_name_from_key( 15157 + ant_t *js, ant_value_t fn, 15158 + ant_value_t key, 15159 + const char *prefix, size_t prefix_len 15160 + ) { 15161 + if (vtype(key) == T_SYMBOL) { 15162 + const char *desc = js_sym_desc(key); 15163 + if (!desc) return js_set_function_name_prefixed(js, fn, prefix, prefix_len, "", 0); 15164 + 15165 + size_t desc_len = strlen(desc); 15166 + char stack_buf[128]; 15167 + 15168 + size_t bracketed_len = desc_len + 2; 15169 + char *buf = (bracketed_len + 1 <= sizeof(stack_buf)) ? stack_buf : malloc(bracketed_len + 1); 15170 + if (!buf) return js_mkerr(js, "oom"); 15171 + 15172 + buf[0] = '['; 15173 + memcpy(buf + 1, desc, desc_len); 15174 + buf[bracketed_len - 1] = ']'; 15175 + buf[bracketed_len] = '\0'; 15176 + 15177 + ant_value_t result = js_set_function_name_prefixed( 15178 + js, fn, prefix, prefix_len, 15179 + buf, bracketed_len 15180 + ); 15181 + 15182 + if (buf != stack_buf) free(buf); 15183 + return result; 15184 + } 15185 + 15186 + ant_value_t key_str = coerce_to_str(js, key); 15187 + if (is_err(key_str)) return key_str; 15188 + if (vtype(key_str) != T_STR) 15189 + return js_set_function_name_prefixed(js, fn, prefix, prefix_len, "", 0); 15190 + 15191 + ant_offset_t key_len = 0; 15192 + ant_offset_t key_off = vstr(js, key_str, &key_len); 15193 + 15194 + const char *key_ptr = (const char *)(uintptr_t)key_off; 15195 + return js_set_function_name_prefixed(js, fn, prefix, prefix_len, key_ptr, (size_t)key_len); 15196 + } 15197 + 15198 + static bool js_function_name_is_inferable(ant_t *js, ant_value_t fn) { 15199 + if (vtype(fn) != T_FUNC) return false; 15200 + 15201 + ant_value_t fn_obj = js_func_obj(fn); 15202 + ant_value_t existing = lkp_interned_val(js, fn_obj, js->intern.name); 15203 + 15204 + if (vtype(existing) == T_UNDEF) return true; 15205 + if (vtype(existing) != T_STR) return false; 15206 + 15207 + ant_offset_t len = 0; 15208 + vstr(js, existing, &len); 15209 + 15210 + return len == 0; 15211 + } 15212 + 15213 + ant_value_t js_maybe_set_function_name_from_key( 15214 + ant_t *js, ant_value_t fn, 15215 + ant_value_t key, 15216 + const char *prefix, size_t prefix_len 15217 + ) { 15218 + if (!js_function_name_is_inferable(js, fn)) return js_mkundef(); 15219 + return js_set_function_name_from_key(js, fn, key, prefix, prefix_len); 15065 15220 } 15066 15221 15067 15222 static bool js_cfunc_has_prototype(ant_value_t cfunc) {
+69 -31
src/silver/compiler.c
··· 482 482 emit_atom_op(c, OP_SET_NAME, name, len); 483 483 } 484 484 485 + static inline bool node_needs_inferred_function_name(const sv_ast_t *node) { 486 + return node && 487 + (node->type == N_FUNC || node->type == N_CLASS) && 488 + (!node->str || node->len == 0); 489 + } 490 + 491 + static void compile_expr_with_inferred_name( 492 + sv_compiler_t *c, sv_ast_t *node, 493 + const char *name, uint32_t len 494 + ) { 495 + if (!node_needs_inferred_function_name(node) || !name) { 496 + compile_expr(c, node); 497 + return; 498 + } 499 + 500 + const char *saved_name = c->inferred_name; 501 + uint32_t saved_len = c->inferred_name_len; 502 + 503 + c->inferred_name = name; 504 + c->inferred_name_len = len; 505 + compile_expr(c, node); 506 + 507 + c->inferred_name = saved_name; 508 + c->inferred_name_len = saved_len; 509 + } 510 + 485 511 static void emit_const_assign_error(sv_compiler_t *c, const char *name, uint32_t len) { 486 512 static const char prefix[] = "Assignment to constant variable '"; 487 513 static const char suffix[] = "'"; ··· 2778 2804 if (prop->flags & FN_GETTER || prop->flags & FN_SETTER) { 2779 2805 compile_expr(c, prop->right); 2780 2806 uint8_t flags = 0; 2781 - if (prop->flags & FN_GETTER) flags |= 1; 2782 - if (prop->flags & FN_SETTER) flags |= 2; 2807 + if (prop->flags & FN_GETTER) flags |= SV_DEFINE_METHOD_GETTER; 2808 + if (prop->flags & FN_SETTER) flags |= SV_DEFINE_METHOD_SETTER; 2809 + flags |= SV_DEFINE_METHOD_SET_NAME; 2783 2810 if (prop->flags & FN_COMPUTED) compile_expr(c, prop->left); 2784 2811 else compile_static_property_key(c, prop->left); 2785 2812 emit_op(c, OP_SWAP); ··· 2789 2816 compile_expr(c, prop->left); 2790 2817 compile_expr(c, prop->right); 2791 2818 emit_op(c, OP_DEFINE_METHOD_COMP); 2792 - emit(c, 0); 2819 + emit(c, node_needs_inferred_function_name(prop->right) ? SV_DEFINE_METHOD_SET_NAME : 0); 2793 2820 } else { 2794 - if (prop->right && (prop->right->type == N_FUNC || prop->right->type == N_CLASS) && 2795 - (!prop->right->str || prop->right->len == 0) && 2796 - prop->left && prop->left->type == N_IDENT && !is_quoted_ident_key(prop->left)) { 2797 - c->inferred_name = prop->left->str; 2798 - c->inferred_name_len = prop->left->len; 2799 - } 2800 - compile_expr(c, prop->right); 2821 + if (prop->left && prop->left->type == N_IDENT && !is_quoted_ident_key(prop->left)) 2822 + compile_expr_with_inferred_name(c, prop->right, prop->left->str, prop->left->len); 2823 + else compile_expr(c, prop->right); 2801 2824 if ((prop->flags & FN_COLON) && 2802 2825 prop->left->type == N_IDENT && !is_quoted_ident_key(prop->left) && 2803 2826 is_ident_str(prop->left->str, prop->left->len, "__proto__", 9)) { ··· 3595 3618 3596 3619 void compile_var_decl(sv_compiler_t *c, sv_ast_t *node) { 3597 3620 sv_var_kind_t kind = node->var_kind; 3621 + 3598 3622 bool is_using = (kind == SV_VAR_USING || kind == SV_VAR_AWAIT_USING); 3599 3623 bool is_await_using = (kind == SV_VAR_AWAIT_USING); 3600 3624 bool is_const = (kind == SV_VAR_CONST || is_using); ··· 3608 3632 if (repl_top) { 3609 3633 if (!decl->right && kind == SV_VAR_VAR) continue; 3610 3634 if (decl->right) { 3611 - compile_expr(c, decl->right); 3612 - } else { 3613 - emit_op(c, OP_UNDEF); 3614 - } 3635 + if (target->type == N_IDENT) 3636 + compile_expr_with_inferred_name(c, decl->right, target->str, target->len); 3637 + else compile_expr(c, decl->right); 3638 + } else emit_op(c, OP_UNDEF); 3615 3639 if (target->type == N_IDENT) { 3616 3640 emit_atom_op(c, OP_PUT_GLOBAL, target->str, target->len); 3617 - } else { 3618 - compile_destructure_pattern(c, target, false, true, 3619 - DESTRUCTURE_ASSIGN, kind); 3620 - } 3641 + } else compile_destructure_pattern(c, target, false, true, DESTRUCTURE_ASSIGN, kind); 3621 3642 } else if (kind == SV_VAR_VAR) { 3622 3643 if (decl->right) { 3623 3644 uint8_t init_type = infer_expr_type(c, decl->right); 3624 - compile_expr(c, decl->right); 3645 + if (target->type == N_IDENT) 3646 + compile_expr_with_inferred_name(c, decl->right, target->str, target->len); 3647 + else compile_expr(c, decl->right); 3625 3648 if (target->type == N_IDENT) { 3626 3649 int idx = resolve_local(c, target->str, target->len); 3627 3650 if (idx >= 0 && c->locals[idx].depth != -1) 3628 3651 emit_put_local_typed(c, idx, init_type); 3629 - else 3630 - compile_lhs_set(c, target, false); 3631 - } else { 3632 - compile_lhs_set(c, target, false); 3633 - } 3652 + else compile_lhs_set(c, target, false); 3653 + } else compile_lhs_set(c, target, false); 3634 3654 } 3635 3655 } else { 3636 3656 if (target->type == N_IDENT) { 3637 - int idx = ensure_local_at_depth(c, target->str, target->len, 3638 - is_const, c->scope_depth); 3657 + int idx = ensure_local_at_depth(c, target->str, target->len, is_const, c->scope_depth); 3639 3658 uint8_t init_type = SV_TI_UNKNOWN; 3640 3659 if (decl->right) { 3641 3660 init_type = infer_expr_type(c, decl->right); 3642 - compile_expr(c, decl->right); 3661 + compile_expr_with_inferred_name(c, decl->right, target->str, target->len); 3643 3662 } else if (!is_const) { 3644 3663 emit_op(c, OP_UNDEF); 3645 3664 init_type = SV_TI_UNDEF; ··· 4525 4544 } 4526 4545 4527 4546 uint8_t method_flags = 0; 4528 - if (m->flags & FN_GETTER) method_flags |= 1; 4529 - if (m->flags & FN_SETTER) method_flags |= 2; 4547 + if (m->flags & FN_GETTER) method_flags |= SV_DEFINE_METHOD_GETTER; 4548 + if (m->flags & FN_SETTER) method_flags |= SV_DEFINE_METHOD_SETTER; 4549 + if (is_fn) method_flags |= SV_DEFINE_METHOD_SET_NAME; 4530 4550 4531 4551 if (m->flags & FN_COMPUTED) { 4532 4552 if (preeval_key >= 0) emit_get_local(c, preeval_key); 4533 4553 else compile_expr(c, m->left); 4534 4554 } else compile_static_property_key(c, m->left); 4555 + 4535 4556 emit_op(c, OP_SWAP); 4536 4557 emit_op(c, OP_DEFINE_METHOD_COMP); 4537 4558 emit(c, method_flags); ··· 4756 4777 free(computed_key_locals); 4757 4778 c->computed_key_locals = NULL; 4758 4779 4759 - if (node->str && !has_static_name) { 4760 - int atom = add_atom(c, node->str, node->len); 4780 + const char *class_name = node->str; 4781 + uint32_t class_name_len = node->len; 4782 + bool consumed_inferred_name = false; 4783 + 4784 + if (!class_name && c->inferred_name) { 4785 + class_name = c->inferred_name; 4786 + class_name_len = c->inferred_name_len; 4787 + consumed_inferred_name = true; 4788 + } 4789 + 4790 + if (!has_static_name) { 4791 + int atom = class_name 4792 + ? add_atom(c, class_name, class_name_len) 4793 + : add_atom(c, "", 0); 4761 4794 emit_op(c, OP_DEFINE_CLASS); 4762 4795 emit_u32(c, (uint32_t)atom); 4763 4796 emit(c, 1); ··· 4765 4798 emit_op(c, OP_DEFINE_CLASS); 4766 4799 emit_u32(c, 0); 4767 4800 emit(c, 0); 4801 + } 4802 + 4803 + if (consumed_inferred_name) { 4804 + c->inferred_name = NULL; 4805 + c->inferred_name_len = 0; 4768 4806 } 4769 4807 4770 4808 emit_u32(c, node->src_off);
+23 -11
src/silver/glue.c
··· 207 207 ant_value_t obj, ant_value_t key, ant_value_t fn, uint8_t flags 208 208 ) { 209 209 ant_value_t desc_obj = js_as_obj(obj); 210 - bool is_getter = (flags & 1) != 0; 211 - bool is_setter = (flags & 2) != 0; 210 + 211 + bool is_getter = (flags & SV_DEFINE_METHOD_GETTER) != 0; 212 + bool is_setter = (flags & SV_DEFINE_METHOD_SETTER) != 0; 213 + 214 + if (flags & SV_DEFINE_METHOD_SET_NAME) { 215 + const char *prefix = is_getter ? "get " : is_setter ? "set " : ""; 216 + size_t prefix_len = is_getter || is_setter ? 4 : 0; 217 + ant_value_t named = js_maybe_set_function_name_from_key(js, fn, key, prefix, prefix_len); 218 + if (is_err(named)) return; 219 + } 220 + 212 221 if (vtype(key) == T_SYMBOL) { 213 222 if (is_getter) { js_set_sym_getter_desc(js, desc_obj, key, fn, JS_DESC_E | JS_DESC_C); return; } 214 223 if (is_setter) { js_set_sym_setter_desc(js, desc_obj, key, fn, JS_DESC_E | JS_DESC_C); return; } 215 224 js_set_sym(js, obj, key, fn); 216 225 return; 217 226 } 227 + 218 228 ant_value_t key_str = sv_key_to_propstr(js, key); 219 229 if ((is_getter || is_setter) && vtype(key_str) == T_STR) { 220 230 ant_offset_t klen = 0; ··· 224 234 else js_set_setter_desc(js, desc_obj, kptr, klen, fn, JS_DESC_E | JS_DESC_C); 225 235 return; 226 236 } 237 + 227 238 if (vtype(key_str) == T_STR) { 228 239 ant_offset_t klen = 0; 229 240 ant_offset_t koff = vstr(js, key_str, &klen); ··· 718 729 js_define_own_prop(js, obj, str, len, val); 719 730 } 720 731 721 - 722 732 void jit_helper_set_name( 723 - sv_vm_t *vm, ant_t *js, ant_value_t fn, 733 + ant_t *js, ant_value_t fn, 724 734 const char *str, uint32_t len 725 - ) { 726 - ant_value_t name = js_mkstr(js, str, len); 727 - setprop_cstr(js, fn, "name", 4, name); 735 + ) { 736 + js_set_function_name(js, fn, str, len); 728 737 } 729 738 730 739 ant_value_t jit_helper_get_length(sv_vm_t *vm, ant_t *js, ant_value_t obj) { 731 740 if (vtype(obj) == T_ARR) 732 741 return tov((double)(uint32_t)js_arr_len(js, obj)); 742 + 733 743 if (vtype(obj) == T_STR) { 734 744 ant_flat_string_t *flat = ant_str_flat_ptr(obj); 735 745 if (flat) { 736 746 const char *str_data = flat->bytes; 737 747 ant_offset_t byte_len = flat->len; 738 - return tov((double)(uint32_t)( 739 - str_is_ascii(str_data) 740 - ? byte_len 741 - : utf16_strlen(str_data, byte_len) 748 + return tov((double)(uint32_t)(str_is_ascii(str_data) 749 + ? byte_len 750 + : utf16_strlen(str_data, byte_len) 742 751 )); 743 752 } 753 + 744 754 ant_offset_t byte_len = 0; 745 755 ant_offset_t off = vstr(js, obj, &byte_len); 756 + 746 757 const char *str_data = (const char *)(uintptr_t)(off); 747 758 return tov((double)(uint32_t)utf16_strlen(str_data, byte_len)); 748 759 } 760 + 749 761 return js_getprop_fallback(js, obj, "length"); 750 762 } 751 763
+34 -17
src/silver/ops/objects.h
··· 20 20 ant_value_t obj = vm->stack[vm->sp - 1]; 21 21 ant_value_t desc_obj = js_as_obj(obj); 22 22 23 - bool is_getter = (flags & 1) != 0; 24 - bool is_setter = (flags & 2) != 0; 23 + bool is_getter = (flags & SV_DEFINE_METHOD_GETTER) != 0; 24 + bool is_setter = (flags & SV_DEFINE_METHOD_SETTER) != 0; 25 + 26 + if (flags & SV_DEFINE_METHOD_SET_NAME) { 27 + const char *prefix = is_getter ? "get " : is_setter ? "set " : ""; 28 + size_t prefix_len = is_getter || is_setter ? 4 : 0; 29 + ant_value_t key = js_mkstr(js, a->str, a->len); 30 + ant_value_t named = js_maybe_set_function_name_from_key(js, fn, key, prefix, prefix_len); 31 + if (is_err(named)) return; 32 + } 25 33 26 34 if (is_getter) { 27 35 js_set_getter_desc(js, desc_obj, a->str, a->len, fn, JS_DESC_E | JS_DESC_C); ··· 46 54 ant_value_t key = vm->stack[--vm->sp]; 47 55 ant_value_t obj = vm->stack[vm->sp - 1]; 48 56 ant_value_t desc_obj = js_as_obj(obj); 49 - bool is_getter = (flags & 1) != 0; 50 - bool is_setter = (flags & 2) != 0; 57 + 58 + bool is_getter = (flags & SV_DEFINE_METHOD_GETTER) != 0; 59 + bool is_setter = (flags & SV_DEFINE_METHOD_SETTER) != 0; 60 + 61 + if (flags & SV_DEFINE_METHOD_SET_NAME) { 62 + const char *prefix = is_getter ? "get " : is_setter ? "set " : ""; 63 + size_t prefix_len = is_getter || is_setter ? 4 : 0; 64 + ant_value_t named = js_maybe_set_function_name_from_key(js, fn, key, prefix, prefix_len); 65 + if (is_err(named)) return; 66 + } 67 + 51 68 if (vtype(key) == T_SYMBOL) { 52 69 if (is_getter) { js_set_sym_getter_desc(js, desc_obj, key, fn, JS_DESC_E | JS_DESC_C); return; } 53 70 if (is_setter) { js_set_sym_setter_desc(js, desc_obj, key, fn, JS_DESC_E | JS_DESC_C); return; } 54 71 js_set_sym(js, obj, key, fn); 55 72 return; 56 73 } 74 + 57 75 ant_value_t key_str = sv_key_to_propstr(js, key); 58 76 if ((is_getter || is_setter) && vtype(key_str) == T_STR) { 59 77 ant_offset_t klen = 0; ··· 63 81 else js_set_setter_desc(js, desc_obj, kptr, klen, fn, JS_DESC_E | JS_DESC_C); 64 82 return; 65 83 } 84 + 66 85 if (vtype(key_str) == T_STR) { 67 86 ant_offset_t klen = 0; 68 87 ant_offset_t koff = vstr(js, key_str, &klen); ··· 78 97 uint32_t atom_idx = sv_get_u32(ip + 1); 79 98 sv_atom_t *a = &func->atoms[atom_idx]; 80 99 ant_value_t fn = vm->stack[vm->sp - 1]; 81 - ant_value_t name = js_mkstr(js, a->str, a->len); 82 - setprop_cstr(js, fn, "name", 4, name); 100 + js_set_function_name(js, fn, a->str, a->len); 83 101 } 84 102 85 103 static inline void sv_op_set_name_comp(sv_vm_t *vm, ant_t *js) { 86 104 ant_value_t key = vm->stack[vm->sp - 1]; 87 105 ant_value_t fn = vm->stack[vm->sp - 2]; 88 - ant_value_t name = coerce_to_str(js, key); 89 - setprop_cstr(js, fn, "name", 4, name); 106 + js_set_function_name_from_key(js, fn, key, "", 0); 90 107 } 91 108 92 109 static inline void sv_op_set_proto(sv_vm_t *vm, ant_t *js) { ··· 263 280 if (is_object_type(object_proto)) js_set_proto_init(proto, object_proto); 264 281 } 265 282 } 266 - if (parent_is_callable) { 267 - if (vtype(ctor) == T_FUNC) { 268 - sv_closure_t *c = js_func_closure(ctor); 269 - c->super_val = parent; 270 - c->call_flags |= SV_CALL_HAS_SUPER; 271 - } 283 + 284 + if (parent_is_callable) if (vtype(ctor) == T_FUNC) { 285 + sv_closure_t *c = js_func_closure(ctor); 286 + c->super_val = parent; 287 + c->call_flags |= SV_CALL_HAS_SUPER; 272 288 } 273 289 274 - if (vtype(ctor) == T_FUNC) js_mark_constructor(js_func_obj(ctor), true); 290 + if (vtype(ctor) == T_FUNC) 291 + js_mark_constructor(js_func_obj(ctor), true); 275 292 276 293 if ( 277 294 vtype(ctor) == T_FUNC && func->source && ··· 285 302 ant_value_t ctor_obj = (vtype(ctor) == T_FUNC) ? js_func_obj(ctor) : ctor; 286 303 js_mkprop_fast(js, ctor_obj, "prototype", 9, proto); 287 304 288 - if (a && a->len > 0) 289 - setprop_cstr(js, ctor, "name", 4, js_mkstr(js, a->str, a->len)); 305 + if (has_name) 306 + js_set_function_name(js, ctor, a ? a->str : "", a ? a->len : 0); 290 307 291 308 vm->stack[vm->sp - 2] = ctor; 292 309 vm->stack[vm->sp - 1] = proto;
+2 -4
src/silver/swarm.c
··· 2255 2255 MIR_T_I32, "slot_count"); 2256 2256 2257 2257 MIR_item_t set_name_proto = MIR_new_proto(ctx, "sn_proto", 2258 - 0, NULL, 5, 2259 - MIR_T_I64, "vm", 2258 + 0, NULL, 4, 2260 2259 MIR_T_I64, "js", 2261 2260 MIR_JSVAL, "fn", 2262 2261 MIR_T_P, "str", ··· 8005 8004 sv_atom_t *atom = &func->atoms[atom_idx]; 8006 8005 MIR_reg_t fn_val = vstack_top(&vs); 8007 8006 MIR_append_insn(ctx, jit_func, 8008 - MIR_new_call_insn(ctx, 7, 8007 + MIR_new_call_insn(ctx, 6, 8009 8008 MIR_new_ref_op(ctx, set_name_proto), 8010 8009 MIR_new_ref_op(ctx, imp_set_name), 8011 - MIR_new_reg_op(ctx, r_vm), 8012 8010 MIR_new_reg_op(ctx, r_js), 8013 8011 MIR_new_reg_op(ctx, fn_val), 8014 8012 MIR_new_uint_op(ctx, (uint64_t)(uintptr_t)atom->str),