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.

optional chaining fixes

+56 -12
+44 -10
src/silver/compiler.c
··· 2005 2005 emit_op(c, OP_TYPEOF); 2006 2006 } 2007 2007 2008 + static bool sv_node_has_optional_base(sv_ast_t *n) { 2009 + while (n) { 2010 + if (n->type == N_OPTIONAL) return true; 2011 + if (n->type == N_MEMBER || n->type == N_CALL) n = n->left; 2012 + else break; 2013 + } 2014 + return false; 2015 + } 2016 + 2017 + static void compile_delete_optional(sv_compiler_t *c, sv_ast_t *arg) { 2018 + compile_expr(c, arg->left); 2019 + int ok_jump = emit_jump(c, OP_JMP_NOT_NULLISH); 2020 + emit_op(c, OP_POP); 2021 + emit_op(c, OP_TRUE); 2022 + int end_jump = emit_jump(c, OP_JMP); 2023 + patch_jump(c, ok_jump); 2024 + if (arg->flags & 1) { 2025 + compile_expr(c, arg->right); 2026 + } else { 2027 + ant_value_t key = js_mkstr_permanent(c->js, arg->right->str, arg->right->len); 2028 + emit_constant(c, key); 2029 + } 2030 + emit_op(c, OP_DELETE); 2031 + patch_jump(c, end_jump); 2032 + } 2033 + 2008 2034 static void compile_delete(sv_compiler_t *c, sv_ast_t *node) { 2009 2035 sv_ast_t *arg = node->right; 2010 - if (arg->type == N_MEMBER && !(arg->flags & 1)) { 2036 + if (arg->type == N_OPTIONAL) { 2037 + compile_delete_optional(c, arg); 2038 + } else if (arg->type == N_MEMBER && sv_node_has_optional_base(arg->left)) { 2039 + compile_delete_optional(c, arg); 2040 + } else if (arg->type == N_MEMBER && !(arg->flags & 1)) { 2011 2041 compile_expr(c, arg->left); 2012 2042 ant_value_t key = js_mkstr_permanent(c->js, arg->right->str, arg->right->len); 2013 2043 emit_constant(c, key); ··· 2258 2288 return; 2259 2289 } 2260 2290 2291 + if (callee->type == N_MEMBER && sv_node_has_optional_base(callee->left)) { 2292 + compile_expr(c, callee->left); 2293 + int ok_jump = emit_jump(c, OP_JMP_NOT_NULLISH); 2294 + emit_op(c, OP_POP); 2295 + emit_op(c, OP_UNDEF); 2296 + int end_jump = emit_jump(c, OP_JMP); 2297 + patch_jump(c, ok_jump); 2298 + compile_receiver_property_get(c, callee); 2299 + compile_call_emit_invoke(c, node, SV_CALL_METHOD, has_spread); 2300 + patch_jump(c, end_jump); 2301 + return; 2302 + } 2303 + 2261 2304 sv_call_kind_t kind = compile_call_setup_non_optional(c, callee); 2262 2305 compile_call_emit_invoke(c, node, kind, has_spread); 2263 2306 } ··· 2276 2319 emit_op(c, OP_NEW); 2277 2320 emit_u16(c, (uint16_t)argc); 2278 2321 } 2279 - } 2280 - 2281 - static bool sv_node_has_optional_base(sv_ast_t *n) { 2282 - while (n) { 2283 - if (n->type == N_OPTIONAL) return true; 2284 - if (n->type == N_MEMBER || n->type == N_CALL) n = n->left; 2285 - else break; 2286 - } 2287 - return false; 2288 2322 } 2289 2323 2290 2324 static void compile_member(sv_compiler_t *c, sv_ast_t *node) {
+12 -2
src/silver/ops/globals.h
··· 7 7 8 8 static inline ant_value_t sv_global_get(ant_t *js, const char *str, uint32_t len) { 9 9 if (!str) return js_mkundef(); 10 + 10 11 const char *interned = intern_string(str, len); 11 12 if (!interned) return js_mkundef(); 12 - return lkp_interned_val(js, js->global, interned); 13 + 14 + ant_value_t val = lkp_interned_val(js, js->global, interned); 15 + if (is_undefined(val)) val = js_getprop_fallback(js, js->global, interned); 16 + 17 + return val; 13 18 } 14 19 15 20 static inline sv_ic_entry_t *sv_global_ic_slot_for_ip(sv_func_t *func, uint8_t *ip) { ··· 85 90 ) { 86 91 ant_value_t out = js_mkundef(); 87 92 sv_ic_entry_t *ic = sv_global_ic_slot_for_ip(func, ip); 93 + 88 94 if (sv_global_ic_try_get_hit(js, ic, interned, &out)) return out; 89 95 if (sv_global_ic_try_fill(js, ic, interned, &out)) return out; 90 - return lkp_interned_val(js, js->global, interned); 96 + 97 + ant_value_t val = lkp_interned_val(js, js->global, interned); 98 + if (is_undefined(val)) val = js_getprop_fallback(js, js->global, interned); 99 + 100 + return val; 91 101 } 92 102 93 103 static inline ant_value_t sv_op_get_global(