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.

reduce internal slot lookup

+107 -106
+2 -1
include/ant.h
··· 67 67 ant_value_t js_mkundef(void); 68 68 ant_value_t js_mknull(void); 69 69 ant_value_t js_mknum(double); 70 + ant_value_t js_mkpromise(ant_t *js); 70 71 71 72 ant_value_t js_getthis(ant_t *); 72 73 void js_setthis(ant_t *, ant_value_t); ··· 146 147 void js_prop_iter_end(ant_iter_t *iter); 147 148 148 149 ant_value_t js_obj_to_func(ant_value_t obj); 149 - ant_value_t js_mkpromise(ant_t *js); 150 + ant_value_t js_obj_to_func_ex(ant_value_t obj, uint8_t flags); 150 151 151 152 ant_value_t js_mktypedarray(void *data); 152 153 void *js_gettypedarray(ant_value_t val);
-5
include/common.h
··· 14 14 SLOT_WITH, 15 15 SLOT_THIS, 16 16 SLOT_NEW_TARGET, 17 - SLOT_BOUND_THIS, 18 - SLOT_BOUND_ARGS, 19 17 SLOT_FIELD_COUNT, 20 18 SLOT_FIELDS, 21 19 SLOT_STRICT, ··· 23 21 SLOT_CODE_LEN, 24 22 SLOT_CFUNC, 25 23 SLOT_CORO, 26 - SLOT_ARROW, 27 24 SLOT_PROTO, 28 25 SLOT_FUNC_PROTO, 29 26 SLOT_ASYNC_PROTO, ··· 40 37 SLOT_BUILTIN, 41 38 SLOT_DATA, 42 39 SLOT_CTOR, 43 - SLOT_SUPER, 44 - SLOT_DEFAULT_CTOR, 45 40 SLOT_DEFAULT, 46 41 SLOT_ERROR_BRAND, 47 42 SLOT_ERR_TYPE,
+38 -30
include/silver/engine.h
··· 165 165 uint32_t gc_epoch; 166 166 }; 167 167 168 - #define SV_CALL_HAS_BOUND_ARGS (1u << 0) 169 - #define SV_CALL_HAS_SUPER (1u << 1) 168 + #define SV_CALL_HAS_BOUND_ARGS (1u << 0) 169 + #define SV_CALL_HAS_SUPER (1u << 1) 170 + #define SV_CALL_IS_ARROW (1u << 2) 171 + #define SV_CALL_IS_DEFAULT_CTOR (1u << 3) 170 172 171 173 typedef struct sv_closure { 172 174 sv_func_t *func; 173 175 sv_upvalue_t **upvalues; 174 176 ant_value_t bound_this; 177 + ant_value_t *bound_argv; 178 + int bound_argc; 179 + ant_value_t bound_args; 180 + ant_value_t super_val; 175 181 ant_value_t func_obj; 176 182 uint32_t gc_epoch; 177 183 uint8_t call_flags; ··· 356 362 return js_as_cfunc(func)(js, args, argc); 357 363 } 358 364 359 - static inline ant_value_t sv_call_resolve_bound(ant_t *js, ant_value_t func_obj, sv_call_ctx_t *ctx) { 360 - ant_value_t bound_this = js_get_slot(js, func_obj, SLOT_BOUND_THIS); 361 - if (js_get_slot(js, func_obj, SLOT_ARROW) == js_true) { 362 - ctx->this_val = bound_this; 363 - } else if (vtype(bound_this) != T_UNDEF) ctx->this_val = bound_this; 365 + static inline ant_value_t *sv_prepend_bound_args( 366 + sv_closure_t *closure, ant_value_t *args, int argc, int *out_total 367 + ) { 368 + int total = closure->bound_argc + argc; 369 + ant_value_t *combined = malloc(sizeof(ant_value_t) * (size_t)total); 370 + if (!combined) { *out_total = argc; return NULL; } 371 + memcpy(combined, closure->bound_argv, sizeof(ant_value_t) * (size_t)closure->bound_argc); 372 + memcpy(combined + closure->bound_argc, args, sizeof(ant_value_t) * (size_t)argc); 373 + *out_total = total; 374 + return combined; 375 + } 364 376 365 - ant_value_t bound_arr = js_get_slot(js, func_obj, SLOT_BOUND_ARGS); 366 - if (vtype(bound_arr) == T_ARR) { 367 - int bound_argc = (int)js_arr_len(js, bound_arr); 368 - if (bound_argc > 0) { 369 - int total = bound_argc + ctx->argc; 370 - ant_value_t *combined = malloc(sizeof(ant_value_t) * (size_t)total); 371 - if (!combined) return js_mkerr(js, "out of memory"); 372 - for (int i = 0; i < bound_argc; i++) 373 - combined[i] = js_arr_get(js, bound_arr, (ant_offset_t)i); 374 - for (int i = 0; i < ctx->argc; i++) 375 - combined[bound_argc + i] = ctx->args[i]; 376 - ctx->args = combined; 377 - ctx->argc = total; 378 - ctx->alloc = combined; 379 - } 377 + static inline ant_value_t sv_call_resolve_bound(ant_t *js, sv_closure_t *closure, sv_call_ctx_t *ctx) { 378 + uint8_t flags = closure->call_flags; 379 + 380 + if (flags & SV_CALL_IS_ARROW) ctx->this_val = closure->bound_this; 381 + else if (vtype(closure->bound_this) != T_UNDEF) ctx->this_val = closure->bound_this; 382 + 383 + if ((flags & SV_CALL_HAS_BOUND_ARGS) && closure->bound_argc > 0) { 384 + int total; 385 + ant_value_t *combined = sv_prepend_bound_args(closure, ctx->args, ctx->argc, &total); 386 + if (!combined) return js_mkerr(js, "out of memory"); 387 + ctx->args = combined; 388 + ctx->argc = total; 389 + ctx->alloc = combined; 380 390 } 381 391 382 - ant_value_t func_super = js_get_slot(js, func_obj, SLOT_SUPER); 383 - if (vtype(func_super) != T_UNDEF) ctx->super_val = func_super; 392 + if (flags & SV_CALL_HAS_SUPER) ctx->super_val = closure->super_val; 384 393 385 394 return js_mkundef(); 386 395 } ··· 390 399 } 391 400 392 401 static inline ant_value_t sv_call_default_ctor( 393 - sv_vm_t *vm, ant_t *js, ant_value_t func_obj, 402 + sv_vm_t *vm, ant_t *js, sv_closure_t *closure, 394 403 sv_call_ctx_t *ctx, ant_value_t *out_this 395 404 ) { 396 405 if (vtype(js->new_target) == T_UNDEF) { ··· 401 410 ); 402 411 } 403 412 404 - ant_value_t super_ctor = js_get_slot(js, func_obj, SLOT_SUPER); 413 + ant_value_t super_ctor = closure->super_val; 405 414 uint8_t st = vtype(super_ctor); 406 415 if (st == T_FUNC || st == T_CFUNC) { 407 416 ant_value_t super_this = ctx->this_val; ··· 574 583 return sv_call_native(js, func, this_val, args, argc); 575 584 576 585 sv_closure_t *closure = js_func_closure(func); 577 - ant_value_t func_obj = closure->func_obj; 578 586 579 587 sv_call_ctx_t ctx = { 580 588 .this_val = this_val, .super_val = js_mkundef(), 581 589 .args = args, .argc = argc, .alloc = NULL, 582 590 }; 583 591 584 - ant_value_t err = sv_call_resolve_bound(js, func_obj, &ctx); 592 + ant_value_t err = sv_call_resolve_bound(js, closure, &ctx); 585 593 if (is_err(err)) return err; 586 594 587 595 if (is_construct_call) ctx.this_val = this_val; 588 596 if (out_this) *out_this = ctx.this_val; 589 597 590 - if (js_get_slot(js, func_obj, SLOT_DEFAULT_CTOR) == js_true) 591 - return sv_call_default_ctor(vm, js, func_obj, &ctx, out_this); 598 + if (closure->call_flags & SV_CALL_IS_DEFAULT_CTOR) 599 + return sv_call_default_ctor(vm, js, closure, &ctx, out_this); 592 600 593 601 if (closure->func != NULL) 594 602 return sv_call_resolve_closure(vm, js, closure, func, &ctx, out_this);
+36 -38
src/ant.c
··· 232 232 | (data & NANBOX_DATA_MASK); 233 233 } 234 234 235 - ant_value_t js_obj_to_func(ant_value_t obj) { 235 + ant_value_t js_obj_to_func_ex(ant_value_t obj, uint8_t flags) { 236 236 sv_closure_t *closure = calloc(1, sizeof(sv_closure_t)); 237 237 closure->func_obj = (vtype(obj) == T_OBJ) ? obj : mkval(T_OBJ, vdata(obj)); 238 + closure->bound_this = js_mkundef(); 239 + closure->bound_args = js_mkundef(); 240 + closure->super_val = js_mkundef(); 241 + closure->call_flags = flags; 238 242 return mkval(T_FUNC, (uintptr_t)closure); 243 + } 244 + 245 + ant_value_t js_obj_to_func(ant_value_t obj) { 246 + return js_obj_to_func_ex(obj, 0); 239 247 } 240 248 241 249 ant_value_t js_mktypedarray(void *data) { ··· 3225 3233 return 0; 3226 3234 } 3227 3235 3228 - static ant_value_t *resolve_bound_args(ant_t *js, ant_value_t func_obj, ant_value_t *args, int nargs, int *out_nargs) { 3229 - *out_nargs = nargs; 3230 - 3231 - ant_value_t bound_arr = get_slot(js, func_obj, SLOT_BOUND_ARGS); 3232 - int bound_argc = 0; 3233 - 3234 - if (vtype(bound_arr) == T_ARR) { 3235 - bound_argc = (int)get_array_length(js, bound_arr); 3236 - } if (bound_argc <= 0) return NULL; 3237 - 3238 - *out_nargs = bound_argc + nargs; 3239 - ant_value_t *combined = (ant_value_t *)ant_calloc(sizeof(ant_value_t) * (*out_nargs)); 3240 - if (!combined) return NULL; 3241 - 3242 - for (int i = 0; i < bound_argc; i++) combined[i] = arr_get(js, bound_arr, (ant_offset_t)i); 3243 - for (int i = 0; i < nargs; i++) combined[bound_argc + i] = args[i]; 3244 - 3245 - return combined; 3246 - } 3247 3236 3248 3237 static ant_offset_t lkp_with_getter(ant_t *js, ant_value_t obj, const char *buf, size_t len, ant_value_t *getter_out, bool *has_getter_out) { 3249 3238 *has_getter_out = false; ··· 4305 4294 4306 4295 if (code && code_len > 0) { 4307 4296 ant_value_t async_slot = get_slot(js, func_obj, SLOT_ASYNC); 4308 - ant_value_t arrow_slot = get_slot(js, func_obj, SLOT_ARROW); 4297 + sv_closure_t *closure = js_func_closure(func); 4309 4298 4310 4299 bool is_async = (async_slot == js_true); 4311 - bool is_arrow = (arrow_slot == js_true); 4300 + bool is_arrow = (closure->call_flags & SV_CALL_IS_ARROW) != 0; 4312 4301 4313 4302 if (is_arrow) { 4314 4303 const char *paren_end = memchr(code, ')', code_len); ··· 4411 4400 if (is_err(bound_func)) return bound_func; 4412 4401 4413 4402 set_slot(js, bound_func, SLOT_CFUNC, func); 4414 - set_slot(js, bound_func, SLOT_BOUND_THIS, this_arg); 4415 - 4416 - if (bound_argc > 0) { 4417 - ant_value_t bound_arr = mkarr(js); 4418 - for (int i = 0; i < bound_argc; i++) arr_set(js, bound_arr, (ant_offset_t)i, bound_args[i]); 4419 - set_slot(js, bound_func, SLOT_BOUND_ARGS, bound_arr); 4420 - } 4421 4403 4422 4404 ant_value_t func_proto = get_slot(js, js_glob(js), SLOT_FUNC_PROTO); 4423 4405 if (vtype(func_proto) == T_FUNC) set_proto(js, bound_func, func_proto); 4424 4406 4425 - ant_value_t bound = js_obj_to_func(bound_func); 4407 + ant_value_t bound = js_obj_to_func_ex(bound_func, bound_argc > 0 ? SV_CALL_HAS_BOUND_ARGS : 0); 4408 + sv_closure_t *bc = js_func_closure(bound); 4409 + bc->bound_this = this_arg; 4410 + if (bound_argc > 0) { 4411 + bc->bound_argv = malloc(sizeof(ant_value_t) * (size_t)bound_argc); 4412 + memcpy(bc->bound_argv, bound_args, sizeof(ant_value_t) * (size_t)bound_argc); 4413 + bc->bound_argc = bound_argc; 4414 + } 4426 4415 js_setprop(js, bound_func, js->length_str, tov((double) bound_length)); 4427 4416 4428 4417 ant_value_t proto_setup = setup_func_prototype(js, bound); ··· 4446 4435 bound_closure->func = orig->func; 4447 4436 bound_closure->upvalues = orig->upvalues; 4448 4437 bound_closure->bound_this = this_arg; 4438 + bound_closure->bound_args = js_mkundef(); 4439 + bound_closure->super_val = orig->super_val; 4449 4440 bound_closure->func_obj = bound_func; 4450 4441 bound_closure->call_flags = orig->call_flags; 4451 4442 if (bound_argc > 0) ··· 4473 4464 } 4474 4465 4475 4466 set_slot(js, bound_func, SLOT_TARGET_FUNC, func); 4476 - set_slot(js, bound_func, SLOT_BOUND_THIS, this_arg); 4477 4467 4478 4468 if (bound_argc > 0) { 4479 4469 ant_value_t bound_arr = mkarr(js); 4480 4470 for (int i = 0; i < bound_argc; i++) arr_set(js, bound_arr, (ant_offset_t)i, bound_args[i]); 4481 - set_slot(js, bound_func, SLOT_BOUND_ARGS, bound_arr); 4471 + bound_closure->bound_args = bound_arr; 4472 + bound_closure->bound_argv = malloc(sizeof(ant_value_t) * (size_t)bound_argc); 4473 + memcpy(bound_closure->bound_argv, bound_args, sizeof(ant_value_t) * (size_t)bound_argc); 4474 + bound_closure->bound_argc = bound_argc; 4482 4475 } 4483 4476 4484 4477 ant_value_t cfunc_slot = get_slot(js, func_obj, SLOT_CFUNC); ··· 12310 12303 } 12311 12304 12312 12305 if (vtype(func) == T_FUNC) { 12313 - ant_value_t func_obj = js_func_obj(func); 12306 + sv_closure_t *closure = js_func_closure(func); 12307 + ant_value_t func_obj = closure->func_obj; 12314 12308 12315 12309 ant_value_t cfunc_slot = get_slot(js, func_obj, SLOT_CFUNC); 12316 12310 if (vtype(cfunc_slot) == T_CFUNC) { 12317 - ant_value_t slot_bound_this = get_slot(js, func_obj, SLOT_BOUND_THIS); 12318 - int final_nargs; 12319 - ant_value_t *combined = resolve_bound_args(js, func_obj, args, nargs, &final_nargs); 12320 - ant_value_t *final_args = combined ? combined : args; 12311 + ant_value_t resolve_this = (vtype(closure->bound_this) != T_UNDEF) ? closure->bound_this : this_val; 12312 + int final_nargs = nargs; 12313 + ant_value_t *final_args = args; 12314 + ant_value_t *combined = NULL; 12315 + if ((closure->call_flags & SV_CALL_HAS_BOUND_ARGS) && closure->bound_argc > 0) { 12316 + combined = sv_prepend_bound_args(closure, args, nargs, &final_nargs); 12317 + if (combined) final_args = combined; 12318 + } 12321 12319 ant_value_t saved_func = js->current_func; 12322 12320 ant_value_t saved_this = js->this_val; 12323 12321 js->current_func = func; 12324 - js->this_val = (vtype(slot_bound_this) != T_UNDEF) ? slot_bound_this : this_val; 12322 + js->this_val = resolve_this; 12325 12323 ant_value_t (*fn)(ant_t *, ant_value_t *, int) = (ant_value_t(*)(ant_t *, ant_value_t *, int))vdata(cfunc_slot); 12326 12324 ant_value_t res = fn(js, final_args, final_nargs); 12327 12325 js->current_func = saved_func;
+8 -1
src/gc.c
··· 163 163 closure->gc_epoch = gc_epoch_counter; 164 164 closure->func_obj = gc_update_val(ctx, closure->func_obj); 165 165 closure->bound_this = gc_update_val(ctx, closure->bound_this); 166 - 166 + closure->bound_args = gc_update_val(ctx, closure->bound_args); 167 + closure->super_val = gc_update_val(ctx, closure->super_val); 168 + 169 + if (closure->bound_argv && closure->bound_argc > 0) { 170 + for (int i = 0; i < closure->bound_argc; i++) 171 + closure->bound_argv[i] = gc_update_val(ctx, closure->bound_argv[i]); 172 + } 173 + 167 174 if (!closure->func) return; 168 175 gc_update_func_constants(ctx, closure->func, 0); 169 176
+2 -4
src/modules/async_hooks.c
··· 155 155 js_set(js, als_proto, "getStore", js_mkfun(async_local_storage_getStore)); 156 156 js_set(js, als_proto, "disable", js_mkfun(async_local_storage_disable)); 157 157 js_set_sym(js, als_proto, get_toStringTag_sym(), ANT_STRING("AsyncLocalStorage")); 158 - js_set_slot(js, als_ctor, SLOT_DEFAULT_CTOR, js_true); 159 158 js_mkprop_fast(js, als_ctor, "prototype", 9, als_proto); 160 159 js_mkprop_fast(js, als_ctor, "name", 4, ANT_STRING("AsyncLocalStorage")); 161 160 js_set_descriptor(js, als_ctor, "name", 4, 0); 162 - js_set(js, lib, "AsyncLocalStorage", js_obj_to_func(als_ctor)); 161 + js_set(js, lib, "AsyncLocalStorage", js_obj_to_func_ex(als_ctor, SV_CALL_IS_DEFAULT_CTOR)); 163 162 164 163 ant_value_t resource_ctor = js_mkobj(js); 165 164 ant_value_t resource_proto = js_mkobj(js); ··· 168 167 js_set(js, resource_proto, "asyncId", js_mkfun(async_resource_asyncId)); 169 168 js_set(js, resource_proto, "triggerAsyncId", js_mkfun(async_resource_triggerAsyncId)); 170 169 js_set_sym(js, resource_proto, get_toStringTag_sym(), ANT_STRING("AsyncResource")); 171 - js_set_slot(js, resource_ctor, SLOT_DEFAULT_CTOR, js_true); 172 170 js_mkprop_fast(js, resource_ctor, "prototype", 9, resource_proto); 173 171 js_mkprop_fast(js, resource_ctor, "name", 4, ANT_STRING("AsyncResource")); 174 172 js_set_descriptor(js, resource_ctor, "name", 4, 0); 175 - js_set(js, lib, "AsyncResource", js_obj_to_func(resource_ctor)); 173 + js_set(js, lib, "AsyncResource", js_obj_to_func_ex(resource_ctor, SV_CALL_IS_DEFAULT_CTOR)); 176 174 177 175 js_set(js, lib, "createHook", js_mkfun(async_hooks_createHook)); 178 176 js_set(js, lib, "executionAsyncId", js_mkfun(async_hooks_executionAsyncId));
+2 -4
src/modules/events.c
··· 553 553 js_set(js, eventemitter_proto, "eventNames", js_mkfun(js_eventemitter_eventNames)); 554 554 js_set_sym(js, eventemitter_proto, get_toStringTag_sym(), js_mkstr(js, "EventEmitter", 12)); 555 555 556 - js_set_slot(js, eventemitter_ctor, SLOT_DEFAULT_CTOR, js_true); 557 556 js_mkprop_fast(js, eventemitter_ctor, "prototype", 9, eventemitter_proto); 558 557 js_mkprop_fast(js, eventemitter_ctor, "name", 4, ANT_STRING("EventEmitter")); 559 558 js_set_descriptor(js, eventemitter_ctor, "name", 4, 0); 560 559 561 - ant_value_t ctor_fn = js_obj_to_func(eventemitter_ctor); 560 + ant_value_t ctor_fn = js_obj_to_func_ex(eventemitter_ctor, SV_CALL_IS_DEFAULT_CTOR); 562 561 js_set(js, lib, "EventEmitter", ctor_fn); 563 562 js_set(js, lib, "default", ctor_fn); 564 563 js_set_sym(js, lib, get_toStringTag_sym(), js_mkstr(js, "events", 6)); ··· 578 577 js_set(js, eventtarget_proto, "dispatchEvent", js_mkfun(js_dispatch_event_method)); 579 578 js_set_sym(js, eventtarget_proto, get_toStringTag_sym(), js_mkstr(js, "EventTarget", 11)); 580 579 581 - js_set_slot(js, eventtarget_ctor, SLOT_DEFAULT_CTOR, js_true); 582 580 js_mkprop_fast(js, eventtarget_ctor, "prototype", 9, eventtarget_proto); 583 581 js_mkprop_fast(js, eventtarget_ctor, "name", 4, ANT_STRING("EventTarget")); 584 582 js_set_descriptor(js, eventtarget_ctor, "name", 4, 0); ··· 587 585 js_set(js, global, "removeEventListener", js_mkfun(js_remove_event_listener)); 588 586 js_set(js, global, "dispatchEvent", js_mkfun(js_dispatch_event)); 589 587 js_set(js, global, "getEventListeners", js_mkfun(js_get_event_listeners)); 590 - js_set(js, global, "EventTarget", js_obj_to_func(eventtarget_ctor)); 588 + js_set(js, global, "EventTarget", js_obj_to_func_ex(eventtarget_ctor, SV_CALL_IS_DEFAULT_CTOR)); 591 589 } 592 590 593 591 void events_gc_update_roots(void (*op_val)(void *, ant_value_t *), void *ctx) {
-5
src/modules/io.c
··· 491 491 [SLOT_WITH] = "WITH", 492 492 [SLOT_THIS] = "THIS", 493 493 [SLOT_NEW_TARGET] = "NEW_TARGET", 494 - [SLOT_BOUND_THIS] = "BOUND_THIS", 495 - [SLOT_BOUND_ARGS] = "BOUND_ARGS", 496 494 [SLOT_FIELD_COUNT] = "FIELD_COUNT", 497 495 [SLOT_FIELDS] = "FIELDS", 498 496 [SLOT_STRICT] = "STRICT", ··· 500 498 [SLOT_CODE_LEN] = "CODE_LEN", 501 499 [SLOT_CFUNC] = "CFUNC", 502 500 [SLOT_CORO] = "CORO", 503 - [SLOT_ARROW] = "ARROW", 504 501 [SLOT_PROTO] = "PROTO", 505 502 [SLOT_FUNC_PROTO] = "FUNC_PROTO", 506 503 [SLOT_ASYNC_PROTO] = "ASYNC_PROTO", ··· 517 514 [SLOT_BUILTIN] = "BUILTIN", 518 515 [SLOT_DATA] = "DATA", 519 516 [SLOT_CTOR] = "CTOR", 520 - [SLOT_SUPER] = "SUPER", 521 - [SLOT_DEFAULT_CTOR] = "DEFAULT_CTOR", 522 517 [SLOT_DEFAULT] = "DEFAULT", 523 518 [SLOT_ERROR_BRAND] = "ERROR_BRAND", 524 519 [SLOT_ERR_TYPE] = "ERR_TYPE",
+4 -5
src/silver/glue.c
··· 157 157 158 158 closure->func = child; 159 159 closure->bound_this = child->is_arrow ? this_val : js_mkundef(); 160 - closure->call_flags = 0; 160 + closure->bound_args = js_mkundef(); 161 + closure->super_val = js_mkundef(); 162 + closure->call_flags = child->is_arrow ? SV_CALL_IS_ARROW : 0; 161 163 162 164 // TODO: reduce nesting 163 165 if (child->upvalue_count > 0) { ··· 197 199 198 200 if (child->is_strict) 199 201 js_set_slot(js, func_obj, SLOT_STRICT, js_true); 200 - if (child->is_arrow) { 201 - js_set_slot(js, func_obj, SLOT_ARROW, js_true); 202 - js_set_slot(js, func_obj, SLOT_BOUND_THIS, this_val); 203 - } 202 + 204 203 if (child->is_async) { 205 204 js_set_slot(js, func_obj, SLOT_ASYNC, js_true); 206 205 ant_value_t async_proto = js_get_slot(js, js->global, SLOT_ASYNC_PROTO);
+11 -8
src/silver/ops/objects.h
··· 91 91 static inline void sv_op_set_home_obj(sv_vm_t *vm, ant_t *js) { 92 92 ant_value_t home = vm->stack[vm->sp - 1]; 93 93 ant_value_t fn = vm->stack[vm->sp - 2]; 94 - ant_value_t fn_obj = js_func_obj(fn); 95 - js_set_slot(js, fn_obj, SLOT_SUPER, home); 96 94 sv_closure_t *c = js_func_closure(fn); 97 - if (c->func != NULL) 98 - c->call_flags |= SV_CALL_HAS_SUPER; 95 + c->super_val = home; 96 + c->call_flags |= SV_CALL_HAS_SUPER; 99 97 } 100 98 101 99 static inline void sv_op_append(sv_vm_t *vm, ant_t *js) { ··· 223 221 224 222 if (vtype(ctor) == T_UNDEF) { 225 223 ant_value_t ctor_obj = mkobj(js, 0); 226 - ctor = js_obj_to_func(ctor_obj); 227 - js_set_slot(js, ctor_obj, SLOT_DEFAULT_CTOR, js_true); 224 + ctor = js_obj_to_func_ex(ctor_obj, SV_CALL_IS_DEFAULT_CTOR); 228 225 ant_value_t func_proto = js_get_slot(js, js->global, SLOT_FUNC_PROTO); 229 226 if (vtype(func_proto) == T_FUNC) 230 227 js_set_proto(js, ctor_obj, func_proto); ··· 252 249 js_set_proto(js, js_deref(js, hp), object_proto); 253 250 } 254 251 } 255 - if (parent_is_callable) 256 - js_set_slot(js, js_deref(js, hc), SLOT_SUPER, parent); 252 + if (parent_is_callable) { 253 + ctor = js_deref(js, hc); 254 + if (vtype(ctor) == T_FUNC) { 255 + sv_closure_t *c = js_func_closure(ctor); 256 + c->super_val = parent; 257 + c->call_flags |= SV_CALL_HAS_SUPER; 258 + } 259 + } 257 260 258 261 ctor = js_deref(js, hc); 259 262 proto = js_deref(js, hp);
+4 -5
src/silver/ops/upvalues.h
··· 111 111 sv_closure_t *closure = calloc(1, sizeof(sv_closure_t)); 112 112 closure->func = child; 113 113 closure->bound_this = child->is_arrow ? frame->this : js_mkundef(); 114 - closure->call_flags = 0; 114 + closure->bound_args = js_mkundef(); 115 + closure->super_val = js_mkundef(); 116 + closure->call_flags = child->is_arrow ? SV_CALL_IS_ARROW : 0; 115 117 116 118 if (child->upvalue_count > 0) { 117 119 closure->upvalues = calloc((size_t)child->upvalue_count, sizeof(sv_upvalue_t *)); ··· 137 139 138 140 if (child->is_strict) 139 141 js_set_slot(js, func_obj, SLOT_STRICT, js_true); 140 - if (child->is_arrow) { 141 - js_set_slot(js, func_obj, SLOT_ARROW, js_true); 142 - js_set_slot(js, func_obj, SLOT_BOUND_THIS, frame->this); 143 - } 142 + 144 143 if (child->is_async) { 145 144 js_set_slot(js, func_obj, SLOT_ASYNC, js_true); 146 145 ant_value_t async_proto = js_get_slot(js, js->global, SLOT_ASYNC_PROTO);