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.

rewrite import system to properly emit SPECIAL_OP(3) metadata

+104 -57
+4 -2
include/internal.h
··· 318 318 ant_value_t js_define_property(ant_t *js, ant_value_t obj, ant_value_t prop, ant_value_t descriptor, bool reflect_mode); 319 319 320 320 ant_value_t js_define_own_prop(ant_t *js, ant_value_t obj, const char *key, size_t klen, ant_value_t v); 321 + ant_value_t js_instance_proto_from_new_target(ant_t *js, ant_value_t fallback_proto); 322 + 323 + ant_value_t js_get_module_import_binding(ant_t *js); 324 + ant_value_t js_builtin_import(ant_t *js, ant_value_t *args, int nargs); 321 325 ant_value_t js_create_import_meta(ant_t *js, const char *filename, bool is_main); 322 326 ant_value_t js_create_module_context(ant_t *js, const char *filename, bool is_main); 323 - ant_value_t js_get_module_import_binding(ant_t *js); 324 - ant_value_t js_instance_proto_from_new_target(ant_t *js, ant_value_t fallback_proto); 325 327 326 328 ant_value_t coerce_to_str(ant_t *js, ant_value_t v); 327 329 ant_value_t coerce_to_str_concat(ant_t *js, ant_value_t v);
+49 -48
src/ant.c
··· 11604 11604 return js_getstr(js, filename, NULL); 11605 11605 } 11606 11606 11607 - static ant_value_t js_get_current_module_ctx(ant_t *js) { 11608 - ant_value_t me = js_getcurrentfunc(js); 11609 - if (vtype(me) == T_FUNC) { 11610 - ant_value_t module_ctx = get_slot(me, SLOT_MODULE_CTX); 11611 - if (is_object_type(module_ctx)) return module_ctx; 11612 - } 11613 - 11614 - return js_module_eval_active_ctx(js); 11615 - } 11616 - 11617 11607 static sv_vm_t *js_get_active_vm(ant_t *js) { 11618 11608 if (!js) return NULL; 11619 11609 if (js->active_async_coro && js->active_async_coro->sv_vm) ··· 11621 11611 return js->vm; 11622 11612 } 11623 11613 11624 - static ant_value_t js_get_caller_module_ctx(ant_t *js) { 11614 + static ant_value_t js_get_func_module_ctx(ant_value_t func) { 11615 + if (vtype(func) != T_FUNC) return js_mkundef(); 11616 + 11617 + ant_value_t func_obj = js_func_obj(func); 11618 + ant_value_t cfunc = get_slot(func_obj, SLOT_CFUNC); 11619 + if (vtype(cfunc) == T_CFUNC && js_as_cfunc(cfunc) == js_builtin_import) 11620 + return js_mkundef(); 11621 + 11622 + ant_value_t module_ctx = get_slot(func_obj, SLOT_MODULE_CTX); 11623 + return is_object_type(module_ctx) ? module_ctx : js_mkundef(); 11624 + } 11625 + 11626 + static ant_value_t js_get_active_frame_module_ctx(ant_t *js) { 11625 11627 sv_vm_t *vm = js_get_active_vm(js); 11626 - if (!vm || vm->fp < 0) return js_module_eval_active_ctx(js); 11628 + if (!vm || vm->fp < 0) return js_mkundef(); 11629 + return js_get_func_module_ctx(vm->frames[vm->fp].callee); 11630 + } 11627 11631 11628 - for (int i = vm->fp; i >= 0; i--) { 11629 - ant_value_t callee = vm->frames[i].callee; 11630 - if (vtype(callee) != T_FUNC) continue; 11632 + static ant_value_t js_get_active_script_or_module_ctx(ant_t *js) { 11633 + ant_value_t module_ctx = js_get_func_module_ctx(js_getcurrentfunc(js)); 11634 + if (is_object_type(module_ctx)) return module_ctx; 11631 11635 11632 - ant_value_t module_ctx = get_slot(js_func_obj(callee), SLOT_MODULE_CTX); 11633 - if (is_object_type(module_ctx)) return module_ctx; 11634 - } 11636 + module_ctx = js_get_active_frame_module_ctx(js); 11637 + if (is_object_type(module_ctx)) return module_ctx; 11635 11638 11636 11639 return js_module_eval_active_ctx(js); 11637 11640 } 11638 11641 11639 - static const char *js_get_current_module_filename(ant_t *js) { 11640 - const char *filename = js_get_module_ctx_filename(js, js_get_current_module_ctx(js)); 11642 + static const char *js_get_current_execution_owner_filename(ant_t *js) { 11643 + const char *filename = js_get_module_ctx_filename( 11644 + js, 11645 + js_get_active_script_or_module_ctx(js) 11646 + ); 11641 11647 if (js_has_module_filename(filename)) return filename; 11642 11648 return js->filename; 11643 11649 } 11644 11650 11645 - static ant_value_t builtin_import(ant_t *js, ant_value_t *args, int nargs) { 11651 + ant_value_t js_builtin_import(ant_t *js, ant_value_t *args, int nargs) { 11646 11652 if (nargs < 1) return js_mkerr(js, "import() requires a string specifier"); 11647 - const char *base_path = NULL; 11648 11653 11649 - ant_value_t me = js_getcurrentfunc(js); 11650 - ant_value_t global_import = js_get_import_func(js); 11651 - ant_value_t module_ctx = js_mkundef(); 11652 - 11653 - if (vtype(me) == T_FUNC) { 11654 - module_ctx = (me == global_import) 11655 - ? js_get_caller_module_ctx(js) 11656 - : get_slot(me, SLOT_MODULE_CTX); 11657 - 11658 - if (!is_object_type(module_ctx)) module_ctx = js_get_caller_module_ctx(js); 11659 - base_path = js_get_module_ctx_filename(js, module_ctx); 11660 - } 11654 + ant_value_t module_ctx = js_get_active_script_or_module_ctx(js); 11655 + const char *base_path = js_get_module_ctx_filename(js, module_ctx); 11661 11656 11662 - if (!js_has_module_filename(base_path)) 11663 - base_path = js_get_current_module_filename(js); 11657 + if (!js_has_module_filename(base_path)) 11658 + base_path = js_get_current_execution_owner_filename(js); 11664 11659 11665 11660 ant_value_t tla_promise = js_mkundef(); 11666 11661 ant_value_t ns = js_esm_import_dynamic(js, args[0], base_path, &tla_promise); ··· 11704 11699 } 11705 11700 11706 11701 static ant_value_t js_get_current_import_meta(ant_t *js) { 11707 - ant_value_t import_meta = js_get_module_ctx_import_meta(js, js_get_current_module_ctx(js)); 11702 + ant_value_t import_meta = js_get_module_ctx_import_meta( 11703 + js, 11704 + js_get_active_script_or_module_ctx(js) 11705 + ); 11708 11706 if (vtype(import_meta) == T_OBJ) return import_meta; 11709 11707 return js_get_import_meta_prop(js); 11710 11708 } ··· 11717 11715 ant_value_t module_ctx = js_mkundef(); 11718 11716 11719 11717 if (is_object_type(import_meta)) module_ctx = js_get_slot(import_meta, SLOT_MODULE_CTX); 11720 - 11721 - if (!is_object_type(module_ctx)) { 11722 - ant_value_t me = js_getcurrentfunc(js); 11723 - if (vtype(me) == T_FUNC) module_ctx = get_slot(me, SLOT_MODULE_CTX); 11724 - } 11718 + 11719 + if (!is_object_type(module_ctx)) 11720 + module_ctx = js_get_active_script_or_module_ctx(js); 11725 11721 11726 11722 base_path = js_get_module_ctx_filename(js, module_ctx); 11727 - if (!js_has_module_filename(base_path)) base_path = js_get_current_module_filename(js); 11723 + if (!js_has_module_filename(base_path)) 11724 + base_path = js_get_current_execution_owner_filename(js); 11728 11725 11729 11726 return js_esm_resolve_specifier(js, args[0], base_path); 11730 11727 } ··· 11847 11844 11848 11845 ant_value_t js_get_module_import_binding(ant_t *js) { 11849 11846 GC_ROOT_SAVE(root_mark, js); 11850 - ant_value_t module_ctx = js_module_eval_active_ctx(js); 11847 + 11848 + ant_value_t module_ctx = js_get_active_script_or_module_ctx(js); 11851 11849 ant_value_t import_meta = js_get_module_ctx_import_meta(js, module_ctx); 11850 + 11852 11851 GC_ROOT_PIN(js, module_ctx); 11853 11852 GC_ROOT_PIN(js, import_meta); 11854 11853 ··· 11871 11870 GC_ROOT_PIN(js, function_proto); 11872 11871 11873 11872 if (is_object_type(function_proto)) js_set_proto_wb(js, import_obj, function_proto); 11874 - set_slot(import_obj, SLOT_CFUNC, js_mkfun(builtin_import)); 11873 + set_slot(import_obj, SLOT_CFUNC, js_mkfun(js_builtin_import)); 11874 + 11875 11875 js_set_slot_wb(js, import_obj, SLOT_MODULE_CTX, module_ctx); 11876 11876 setprop_cstr(js, import_obj, "meta", 4, import_meta); 11877 11877 11878 11878 ant_value_t import_fn = js_obj_to_func(import_obj); 11879 11879 GC_ROOT_RESTORE(js, root_mark); 11880 + 11880 11881 return import_fn; 11881 11882 } 11882 11883 ··· 12823 12824 ant_value_t import_obj = mkobj(js, 0); 12824 12825 set_proto(js, import_obj, function_proto); 12825 12826 12826 - set_slot(import_obj, SLOT_CFUNC, js_mkfun(builtin_import)); 12827 + set_slot(import_obj, SLOT_CFUNC, js_mkfun(js_builtin_import)); 12827 12828 js_setprop(js, glob, js_mkstr(js, "import", 6), js_obj_to_func(import_obj)); 12828 12829 12829 12830 js_setprop(js, object_proto, js_mkstr(js, "constructor", 11), obj_func); ··· 13055 13056 if (vtype(import_meta) == T_UNDEF) import_meta = js_get_current_import_meta(js); 13056 13057 if (key_len == 4 && memcmp(key, "meta", 4) == 0 && vtype(import_meta) != T_UNDEF) { 13057 13058 ant_value_t cfunc = js_get_slot(func_obj, SLOT_CFUNC); 13058 - if (vtype(cfunc) == T_CFUNC && js_as_cfunc(cfunc) == builtin_import) { 13059 + if (vtype(cfunc) == T_CFUNC && js_as_cfunc(cfunc) == js_builtin_import) { 13059 13060 *out = import_meta; 13060 13061 return true; 13061 13062 } ··· 13338 13339 13339 13340 if (sv_dump_bytecode_unlikely) sv_disasm(js, func, js->filename); 13340 13341 if (func->is_tla) result = sv_execute_entry_tla(js, func, js->this_val); 13341 - else result = sv_execute_entry(js->vm, func, js->this_val, NULL, 0); 13342 + else result = sv_execute_entry(js_get_active_vm(js), func, js->this_val, NULL, 0); 13342 13343 13343 13344 js->this_val = saved_this; 13344 13345 return result;
+14 -7
src/silver/compiler.c
··· 910 910 static void emit_put_local(sv_compiler_t *c, int local_idx); 911 911 static void emit_put_local_typed(sv_compiler_t *c, int local_idx, uint8_t type); 912 912 913 + static inline void emit_get_module_import_binding(sv_compiler_t *c) { 914 + emit_op(c, OP_SPECIAL_OBJ); 915 + emit(c, 3); 916 + } 917 + 913 918 static void emit_get_var(sv_compiler_t *c, const char *name, uint32_t len) { 914 919 int local = resolve_local(c, name, len); 915 920 if (local != -1) { ··· 978 983 return; 979 984 } 980 985 } 986 + if (has_module_import_binding(c) && is_ident_str(name, len, "import", 6)) { 987 + emit_get_module_import_binding(c); 988 + return; 989 + } 981 990 if (c->with_depth > 0) 982 991 emit_with_get(c, name, len, WITH_FB_GLOBAL, 0); 983 992 else ··· 1029 1038 } 1030 1039 emit_op(c, keep ? OP_SET_UPVAL : OP_PUT_UPVAL); 1031 1040 emit_u16(c, (uint16_t)upval); 1041 + return; 1042 + } 1043 + if (has_module_import_binding(c) && is_ident_str(name, len, "import", 6)) { 1044 + emit_const_assign_error(c, name, len); 1032 1045 return; 1033 1046 } 1034 1047 if (c->with_depth > 0) { ··· 1592 1605 case N_IMPORT: 1593 1606 compile_expr(c, node->right); 1594 1607 if (has_module_import_binding(c)) { 1595 - emit_get_var(c, "import", 6); 1608 + emit_get_module_import_binding(c); 1596 1609 emit_op(c, OP_SWAP); 1597 1610 emit_op(c, OP_CALL); 1598 1611 emit_u16(c, 1); ··· 4253 4266 } 4254 4267 4255 4268 bool repl_top = is_repl_top_level(&comp); 4256 - if (mode == SV_COMPILE_MODULE && comp.enclosing && !comp.enclosing->enclosing) { 4257 - int import_local = add_local(&comp, "import", 6, true, comp.scope_depth); 4258 - emit_op(&comp, OP_SPECIAL_OBJ); 4259 - emit(&comp, 3); 4260 - emit_put_local(&comp, import_local); 4261 - } 4262 4269 if (!has_non_simple_params && node->body) { 4263 4270 if (node->body->type == N_BLOCK) { 4264 4271 if (!repl_top) {
+23
tests/import_meta_dirname_capture_runner.mjs
··· 1 + function assert(condition, message) { 2 + if (!condition) throw new Error(message); 3 + } 4 + 5 + const mod = await import('./nested/import_meta_dirname_capture_child.mjs'); 6 + 7 + const expectedDir = '/tests/nested'; 8 + 9 + assert( 10 + mod.topDirname.endsWith(expectedDir), 11 + `top-level import.meta.dirname drifted: ${mod.topDirname}` 12 + ); 13 + assert( 14 + mod.nestedDirname.endsWith(expectedDir), 15 + `nested import.meta.dirname drifted: ${mod.nestedDirname}` 16 + ); 17 + const asyncDirname = await mod.readAsyncDirname(); 18 + assert( 19 + asyncDirname.endsWith(expectedDir), 20 + `async import.meta.dirname drifted: ${asyncDirname}` 21 + ); 22 + 23 + console.log(`import.meta.dirname.capture:${mod.topDirname}`);
+14
tests/nested/import_meta_dirname_capture_child.mjs
··· 1 + const topDirname = import.meta.dirname; 2 + 3 + function readNestedDirname() { 4 + return import.meta.dirname; 5 + } 6 + 7 + async function readAsyncDirname() { 8 + await 0; 9 + return import.meta.dirname; 10 + } 11 + 12 + export { topDirname }; 13 + export const nestedDirname = readNestedDirname(); 14 + export { readAsyncDirname };