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 loader for circular dependencies

+101
+9
include/esm/exports.h
··· 1 + #ifndef ESM_EXPORTS_H 2 + #define ESM_EXPORTS_H 3 + 4 + #include "types.h" 5 + #include "silver/ast.h" 6 + 7 + void esm_predeclare_exports(ant_t *js, sv_ast_t *program, ant_value_t ns); 8 + 9 + #endif
+6
src/ant.c
··· 24 24 25 25 #include "esm/remote.h" 26 26 #include "esm/loader.h" 27 + #include "esm/exports.h" 27 28 #include "esm/builtin_bundle.h" 28 29 29 30 #include "silver/lexer.h" ··· 13312 13313 if (!program) { 13313 13314 if (js->thrown_exists) return mkval(T_ERR, 0); 13314 13315 return js_mkerr_typed(js, JS_ERR_INTERNAL | JS_ERR_NO_STACK, "Unexpected parse error"); 13316 + } 13317 + 13318 + if (mode == SV_COMPILE_MODULE) { 13319 + ant_value_t ns = js_module_eval_active_ns(js); 13320 + if (is_object_type(ns)) esm_predeclare_exports(js, program, ns); 13315 13321 } 13316 13322 13317 13323 sv_func_t *func = sv_compile(js, program, mode, buf, (ant_offset_t)len);
+86
src/esm/exports.c
··· 1 + #include "esm/exports.h" 2 + #include "internal.h" 3 + 4 + static void collect_binding_names(ant_t *js, sv_ast_t *pat, ant_value_t ns) { 5 + if (!pat) return; 6 + 7 + static const void *dispatch[N__COUNT] = { 8 + [N_IDENT] = &&l_ident, 9 + [N_ASSIGN_PAT] = &&l_left, 10 + [N_REST] = &&l_right, 11 + [N_SPREAD] = &&l_right, 12 + [N_ARRAY] = &&l_list, 13 + [N_ARRAY_PAT] = &&l_list, 14 + [N_OBJECT] = &&l_props, 15 + [N_OBJECT_PAT] = &&l_props, 16 + }; 17 + 18 + if ((unsigned)pat->type < N__COUNT && dispatch[pat->type]) 19 + goto *dispatch[pat->type]; 20 + return; 21 + 22 + l_ident: 23 + setprop_cstr(js, ns, pat->str, pat->len, js_mkundef()); 24 + return; 25 + l_left: 26 + collect_binding_names(js, pat->left, ns); 27 + return; 28 + l_right: 29 + collect_binding_names(js, pat->right, ns); 30 + return; 31 + l_list: 32 + for (int i = 0; i < pat->args.count; i++) 33 + collect_binding_names(js, pat->args.items[i], ns); 34 + return; 35 + l_props: 36 + for (int i = 0; i < pat->args.count; i++) { 37 + sv_ast_t *p = pat->args.items[i]; 38 + if (!p) continue; 39 + collect_binding_names(js, p->type == N_PROPERTY ? p->right : p, ns); 40 + } 41 + return; 42 + } 43 + 44 + static void collect_spec_names(ant_t *js, sv_ast_list_t *specs, ant_value_t ns) { 45 + for (int i = 0; i < specs->count; i++) { 46 + sv_ast_t *spec = specs->items[i]; 47 + if (spec && spec->type == N_IMPORT_SPEC && spec->right && spec->right->type == N_IDENT) 48 + setprop_cstr(js, ns, spec->right->str, spec->right->len, js_mkundef()); 49 + }} 50 + 51 + static void predeclare_decl(ant_t *js, sv_ast_t *decl, ant_value_t ns) { 52 + static const void *dispatch[N__COUNT] = { 53 + [N_VAR] = &&l_var, 54 + [N_FUNC] = &&l_named, 55 + [N_CLASS] = &&l_named, 56 + }; 57 + 58 + if ((unsigned)decl->type < N__COUNT && dispatch[decl->type]) 59 + goto *dispatch[decl->type]; 60 + return; 61 + 62 + l_var: 63 + for (int i = 0; i < decl->args.count; i++) { 64 + sv_ast_t *var = decl->args.items[i]; 65 + if (var && var->type == N_VARDECL) 66 + collect_binding_names(js, var->left, ns); 67 + } 68 + return; 69 + l_named: 70 + if (decl->str && decl->len > 0) 71 + setprop_cstr(js, ns, decl->str, decl->len, js_mkundef()); 72 + return; 73 + } 74 + 75 + void esm_predeclare_exports(ant_t *js, sv_ast_t *program, ant_value_t ns) { 76 + if (!program || !is_object_type(ns)) return; 77 + 78 + for (int i = 0; i < program->args.count; i++) { 79 + sv_ast_t *stmt = program->args.items[i]; 80 + if (!stmt || stmt->type != N_EXPORT) continue; 81 + uint16_t f = stmt->flags; 82 + 83 + if (f & EX_DEFAULT) setprop_cstr(js, ns, "default", 7, js_mkundef()); 84 + else if ((f & EX_DECL) && stmt->left) predeclare_decl(js, stmt->left, ns); 85 + else if ((f & EX_NAMED) || ((f & EX_STAR) && (f & EX_NAMESPACE))) collect_spec_names(js, &stmt->args, ns); 86 + }}