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.

fix accessor support for object properties

+115 -7
+1 -1
meson.build
··· 75 75 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 76 76 77 77 version_conf = configuration_data() 78 - version_conf.set('ANT_VERSION', '0.1.3.11') 78 + version_conf.set('ANT_VERSION', '0.1.3.12') 79 79 version_conf.set('ANT_GIT_HASH', git_hash) 80 80 version_conf.set('ANT_BUILD_DATE', build_date) 81 81
+114 -6
src/ant.c
··· 611 611 static jsval_t call_js_with_args(struct js *js, jsval_t func, jsval_t *args, int nargs); 612 612 static jsval_t call_js_code_with_args(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope, jsval_t *args, int nargs); 613 613 static jsval_t start_async_in_coroutine(struct js *js, const char *code, size_t code_len, jsval_t closure_scope, jsval_t *args, int nargs); 614 + static inline bool push_this(jsval_t this_value); 615 + static inline jsval_t pop_this(void); 616 + static inline jsval_t peek_this(void); 614 617 615 618 jsval_t js_get_proto(struct js *js, jsval_t obj); 616 619 void js_set_proto(struct js *js, jsval_t obj, jsval_t proto); ··· 2722 2725 jsval_t desc_obj = resolveprop(js, mkval(T_PROP, desc_off)); 2723 2726 if (vtype(desc_obj) != T_OBJ) goto do_update; 2724 2727 2728 + jsoff_t set_off = lkp(js, desc_obj, "set", 3); 2729 + if (set_off != 0) { 2730 + jsval_t setter = resolveprop(js, mkval(T_PROP, set_off)); 2731 + if (vtype(setter) == T_FUNC || vtype(setter) == T_CFUNC) { 2732 + js_parse_state_t saved; 2733 + JS_SAVE_STATE(js, saved); 2734 + uint8_t saved_flags = js->flags; 2735 + jsoff_t saved_toff = js->toff; 2736 + jsoff_t saved_tlen = js->tlen; 2737 + 2738 + jsval_t saved_this = js->this_val; 2739 + js->this_val = obj; 2740 + push_this(obj); 2741 + jsval_t result = call_js_with_args(js, setter, &v, 1); 2742 + pop_this(); 2743 + js->this_val = saved_this; 2744 + 2745 + JS_RESTORE_STATE(js, saved); 2746 + js->flags = saved_flags; 2747 + js->toff = saved_toff; 2748 + js->tlen = saved_tlen; 2749 + 2750 + if (is_err(result)) return result; 2751 + return v; 2752 + } 2753 + } 2754 + 2725 2755 jsoff_t writable_off = lkp(js, desc_obj, "writable", 8); 2726 2756 if (writable_off != 0) { 2727 2757 jsval_t writable_val = resolveprop(js, mkval(T_PROP, writable_off)); ··· 4041 4071 return 1; 4042 4072 } 4043 4073 4074 + static bool try_accessor_setter(struct js *js, jsval_t obj, const char *key, size_t key_len, jsval_t val, jsval_t *out) { 4075 + char desc_key[128]; 4076 + snprintf(desc_key, sizeof(desc_key), "__desc_%.*s", (int)key_len, key); 4077 + 4078 + jsoff_t desc_off = lkp(js, obj, desc_key, strlen(desc_key)); 4079 + if (desc_off == 0) return false; 4080 + 4081 + jsval_t desc_obj = loadval(js, desc_off + sizeof(jsoff_t) * 2); 4082 + if (vtype(desc_obj) != T_OBJ) return false; 4083 + 4084 + jsoff_t set_off = lkp(js, desc_obj, "set", 3); 4085 + if (set_off == 0) return false; 4086 + 4087 + jsval_t setter = loadval(js, set_off + sizeof(jsoff_t) * 2); 4088 + if (vtype(setter) != T_FUNC && vtype(setter) != T_CFUNC) return false; 4089 + 4090 + js_parse_state_t saved; 4091 + JS_SAVE_STATE(js, saved); 4092 + uint8_t saved_flags = js->flags; 4093 + jsoff_t saved_toff = js->toff; 4094 + jsoff_t saved_tlen = js->tlen; 4095 + 4096 + jsval_t saved_this = js->this_val; 4097 + js->this_val = obj; 4098 + push_this(obj); 4099 + jsval_t result = call_js_with_args(js, setter, &val, 1); 4100 + pop_this(); 4101 + js->this_val = saved_this; 4102 + 4103 + JS_RESTORE_STATE(js, saved); 4104 + js->flags = saved_flags; 4105 + js->toff = saved_toff; 4106 + js->tlen = saved_tlen; 4107 + 4108 + *out = is_err(result) ? result : val; 4109 + return true; 4110 + } 4111 + 4044 4112 static jsval_t assign(struct js *js, jsval_t lhs, jsval_t val) { 4045 4113 if (vtype(lhs) == T_PROPREF) { 4046 4114 jsoff_t obj_off = propref_obj(lhs); ··· 4051 4119 } 4052 4120 4053 4121 jsoff_t propoff = (jsoff_t) vdata(lhs); 4122 + 4123 + jsoff_t koff = loadoff(js, propoff + sizeof(jsoff_t)); 4124 + jsoff_t klen = offtolen(loadoff(js, koff)); 4125 + const char *key = (char *)&js->mem[koff + sizeof(jsoff_t)]; 4126 + 4127 + for (jsoff_t scan_off = 0; scan_off < propoff; ) { 4128 + jsoff_t header = loadoff(js, scan_off); 4129 + jsoff_t cleaned = header & ~(GCMASK | CONSTMASK | ARRMASK); 4130 + if ((cleaned & 3) == T_OBJ) { 4131 + jsoff_t next = cleaned & ~3U; 4132 + while (next < js->brk && next != 0) { 4133 + if (next == propoff) { 4134 + jsval_t obj = mkval(T_OBJ, scan_off); 4135 + jsval_t setter_result; 4136 + if (try_accessor_setter(js, obj, key, klen, val, &setter_result)) return setter_result; 4137 + break; 4138 + } 4139 + next = loadoff(js, next) & ~(3U | CONSTMASK | ARRMASK); 4140 + } 4141 + } 4142 + scan_off += esize(cleaned); 4143 + } 4144 + 4054 4145 if (is_const_prop(js, propoff)) { 4055 4146 if (js->flags & F_STRICT) return js_mkerr(js, "assignment to constant"); 4056 4147 return mkval(T_PROP, propoff); ··· 4312 4403 return js_mkerr_typed(js, JS_ERR_TYPE, "'%.*s' not allowed on strict arguments", (int)plen, ptr); 4313 4404 } 4314 4405 4315 - jsval_t accessor_result; 4316 - if (try_accessor_getter(js, l, ptr, plen, &accessor_result)) { 4317 - return accessor_result; 4318 - } 4319 - 4320 4406 jsoff_t own_off = lkp(js, l, ptr, plen); 4321 4407 if (own_off != 0) { 4408 + char desc_key[128]; 4409 + snprintf(desc_key, sizeof(desc_key), "__desc_%.*s", (int)plen, ptr); 4410 + jsoff_t desc_off = lkp(js, l, desc_key, strlen(desc_key)); 4411 + if (desc_off != 0) { 4412 + jsval_t desc_obj = loadval(js, desc_off + sizeof(jsoff_t) * 2); 4413 + if (vtype(desc_obj) == T_OBJ) { 4414 + jsoff_t get_off = lkp(js, desc_obj, "get", 3); 4415 + jsoff_t set_off = lkp(js, desc_obj, "set", 3); 4416 + if (get_off != 0 || set_off != 0) { 4417 + jsval_t key = js_mkstr(js, ptr, plen); 4418 + return mkpropref((jsoff_t)vdata(l), (jsoff_t)vdata(key)); 4419 + } 4420 + } 4421 + } 4322 4422 return mkval(T_PROP, own_off); 4423 + } 4424 + 4425 + jsval_t accessor_result; 4426 + if (try_accessor_getter(js, l, ptr, plen, &accessor_result)) { 4427 + return accessor_result; 4323 4428 } 4324 4429 4325 4430 jsval_t result = try_dynamic_getter(js, l, ptr, plen); ··· 5313 5418 5314 5419 if (is_err(l)) return l; 5315 5420 if (is_err(r)) return r; 5316 - if (is_assign(op) && vtype(lhs) != T_PROP && vtype(lhs) != T_PROPREF) return js_mkerr(js, "bad lhs"); 5421 + if (is_assign(op) && vtype(lhs) != T_PROP && vtype(lhs) != T_PROPREF) { 5422 + if (!(js->flags & F_STRICT) && vtype(lhs) == T_UNDEF) return r; 5423 + return js_mkerr(js, "bad lhs"); 5424 + } 5317 5425 5318 5426 switch (op) { 5319 5427 case TOK_TYPEOF: {