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.

#12 revise symbol system and other code-review nitpicks

danielle was here

authored by

Mack and committed by
GitHub
1797a391 67e6d977

+2248 -827
+4
include/ant.h
··· 75 75 jsval_t js_getcurrentfunc(ant_t *); 76 76 jsval_t js_get(ant_t *, jsval_t, const char *); 77 77 jsval_t js_getprop_proto(ant_t *, jsval_t, const char *); 78 + jsval_t js_getprop_fallback(ant_t *js, jsval_t obj, const char *name); 78 79 79 80 jsoff_t js_arr_len(struct js *js, jsval_t arr); 80 81 jsval_t js_arr_get(struct js *js, jsval_t arr, jsoff_t idx); ··· 94 95 const char *js_sym_desc(ant_t *js, jsval_t sym); 95 96 96 97 jsval_t js_mksym_for(ant_t *, const char *key); 98 + jsval_t js_symbol_to_string(struct js *js, jsval_t sym); 97 99 const char *js_sym_key(jsval_t sym); 98 100 99 101 jsval_t js_mkobj(ant_t *); ··· 167 169 168 170 typedef jsval_t (*js_getter_fn)(ant_t *js, jsval_t obj, const char *key, size_t key_len); 169 171 typedef bool (*js_setter_fn)(ant_t *js, jsval_t obj, const char *key, size_t key_len, jsval_t value); 172 + typedef jsval_t (*js_keys_fn)(ant_t *js, jsval_t obj); 170 173 171 174 void js_set_getter(ant_t *js, jsval_t obj, js_getter_fn getter); 172 175 void js_set_setter(ant_t *js, jsval_t obj, js_setter_fn setter); 176 + void js_set_keys(ant_t *js, jsval_t obj, js_keys_fn keys); 173 177 174 178 void js_set_descriptor(ant_t *js, jsval_t obj, const char *key, size_t klen, int flags); 175 179 void js_set_getter_desc(ant_t *js, jsval_t obj, const char *key, size_t klen, jsval_t getter, int flags);
+6 -1
include/internal.h
··· 41 41 jsval_t tval; // holds last parsed numeric or string literal value 42 42 jsval_t scope; // current scope 43 43 jsval_t global; // global root object 44 + jsval_t object; // global object prototype 44 45 jsval_t this_val; // 'this' value for currently executing function 45 46 jsval_t super_val; // 'super' value for class methods 46 47 jsval_t new_target; // constructor called with 'new', undefined otherwise ··· 112 113 double tod(jsval_t v); 113 114 114 115 jsval_t resolveprop(struct js *js, jsval_t v); 115 - jsval_t setprop(struct js *js, jsval_t obj, jsval_t k, jsval_t v); 116 + jsval_t setprop_cstr(struct js *js, jsval_t obj, const char *key, size_t len, jsval_t v); 117 + jsval_t setprop_interned(struct js *js, jsval_t obj, const char *key, size_t len, jsval_t v); 118 + 119 + jsval_t coerce_to_str(struct js *js, jsval_t v); 120 + jsval_t coerce_to_str_concat(struct js *js, jsval_t v); 116 121 117 122 jsoff_t lkp(struct js *js, jsval_t obj, const char *buf, size_t len); 118 123 jsoff_t lkp_proto(struct js *js, jsval_t obj, const char *buf, size_t len);
+7 -1
include/modules/symbol.h
··· 14 14 const char *get_asyncIterator_sym_key(void); 15 15 const char *get_toStringTag_sym_key(void); 16 16 const char *get_observable_sym_key(void); 17 - const char *get_symbol_description_from_key(const char *sym_key, size_t key_len); 17 + const char *get_toPrimitive_sym_key(void); 18 + const char *get_hasInstance_sym_key(void); 19 + 20 + const char *get_symbol_description_from_key( 21 + const char *sym_key, 22 + size_t key_len 23 + ); 18 24 19 25 #endif
+22
include/utils.h
··· 4 4 5 5 #include <stdlib.h> 6 6 #include <stdint.h> 7 + #include <string.h> 8 + 9 + typedef struct { 10 + char *ptr; 11 + char *heap; 12 + } cstr_buf_t; 7 13 8 14 const char *ant_semver(void); 9 15 uint64_t hash_key(const char *key, size_t len); ··· 12 18 int ant_version(void *argtable[]); 13 19 14 20 void *try_oom(size_t size); 21 + void cstr_free(cstr_buf_t *buf); 22 + 23 + char *cstr_init( 24 + cstr_buf_t *buf, 25 + char *stack, 26 + size_t stack_size, 27 + const char *src, 28 + size_t len 29 + ); 30 + 31 + #define CSTR_BUF(name, size) \ 32 + char name##_stack[size]; \ 33 + cstr_buf_t name = {0} 34 + 35 + #define CSTR_INIT(buf, src, len) \ 36 + cstr_init(&(buf), buf##_stack, sizeof(buf##_stack), (src), (len)) 15 37 16 38 #endif
+1043 -690
src/ant.c
··· 219 219 jsoff_t obj_offset; 220 220 js_getter_fn getter; 221 221 js_setter_fn setter; 222 + js_keys_fn keys; 222 223 UT_hash_handle hh; 223 224 } dynamic_accessors_t; 224 225 ··· 2852 2853 jsval_t prototype_key = js_mkstr(js, "prototype", 9); 2853 2854 if (is_err(prototype_key)) return prototype_key; 2854 2855 2855 - res = setprop(js, func, prototype_key, proto_obj); 2856 + res = js_setprop(js, func, prototype_key, proto_obj); 2856 2857 if (is_err(res)) return res; 2857 2858 js_set_descriptor(js, func, "prototype", 9, JS_DESC_W); 2858 2859 ··· 2864 2865 if (vtype(get_slot(js, func_obj, SLOT_NAME)) != T_UNDEF) return; 2865 2866 jsval_t name_val = js_mkstr(js, name, len); 2866 2867 set_slot(js, func_obj, SLOT_NAME, name_val); 2867 - setprop(js, func_obj, js_mkstr(js, "name", 4), name_val); 2868 + js_setprop(js, func_obj, js_mkstr(js, "name", 4), name_val); 2868 2869 } 2869 2870 2870 2871 static jsval_t validate_array_length(struct js *js, jsval_t v) { ··· 3022 3023 return result; 3023 3024 } 3024 3025 3025 - jsval_t setprop(struct js *js, jsval_t obj, jsval_t k, jsval_t v) { 3026 - return js_setprop(js, obj, k, v); 3027 - } 3028 - 3029 3026 static inline void esm_export_binding(struct js *js, const char *exported, size_t exported_len, jsval_t value) { 3030 3027 jsval_t export_key = js_mkstr(js, exported, exported_len); 3031 - setprop(js, js->module_ns, export_key, value); 3028 + js_setprop(js, js->module_ns, export_key, value); 3032 3029 if (exported_len == 7 && strncmp(exported, "default", 7) == 0) js_set_slot(js, js->module_ns, SLOT_DEFAULT, value); 3033 3030 } 3034 3031 3035 - static inline jsval_t setprop_cstr(struct js *js, jsval_t obj, const char *key, size_t len, jsval_t v) { 3032 + jsval_t setprop_cstr(struct js *js, jsval_t obj, const char *key, size_t len, jsval_t v) { 3036 3033 jsval_t k = js_mkstr(js, key, len); 3037 3034 if (is_err(k)) return k; 3038 3035 return mkprop(js, obj, k, v, 0); 3039 3036 } 3040 3037 3041 - static jsval_t setprop_interned(struct js *js, jsval_t obj, const char *key, size_t len, jsval_t v) { 3038 + jsval_t setprop_interned(struct js *js, jsval_t obj, const char *key, size_t len, jsval_t v) { 3042 3039 jsval_t k = js_mkstr(js, key, len); 3043 3040 if (is_err(k)) return k; 3044 3041 return js_setprop(js, obj, k, v); ··· 3047 3044 jsval_t js_setprop_nonconfigurable(struct js *js, jsval_t obj, const char *key, size_t keylen, jsval_t v) { 3048 3045 jsval_t k = js_mkstr(js, key, keylen); 3049 3046 if (is_err(k)) return k; 3050 - jsval_t result = setprop(js, obj, k, v); 3047 + jsval_t result = js_setprop(js, obj, k, v); 3051 3048 if (is_err(result)) return result; 3052 3049 3053 3050 js_set_descriptor(js, obj, key, keylen, JS_DESC_W); ··· 4551 4548 *has_getter_out = false; 4552 4549 *getter_out = js_mkundef(); 4553 4550 4554 - jsval_t current = obj; 4555 - while (vtype(current) == T_OBJ || vtype(current) == T_FUNC) { 4551 + for (jsval_t current = obj; is_object_type(current); ) { 4556 4552 jsoff_t current_off = (jsoff_t)vdata(current); 4557 4553 descriptor_entry_t *desc = lookup_descriptor(current_off, buf, len); 4558 4554 ··· 4566 4562 if (prop_off != 0) return prop_off; 4567 4563 4568 4564 jsval_t proto = get_proto(js, current); 4569 - if (vtype(proto) != T_OBJ && vtype(proto) != T_FUNC) break; 4565 + if (!is_object_type(proto)) break; 4570 4566 current = proto; 4571 4567 } 4572 4568 ··· 4627 4623 jsval_t js_get_proto(struct js *js, jsval_t obj) { 4628 4624 uint8_t t = vtype(obj); 4629 4625 4630 - if (t != T_OBJ && t != T_ARR && t != T_FUNC && t != T_PROMISE) return js_mknull(); 4626 + if (!is_object_type(obj)) return js_mknull(); 4631 4627 jsval_t as_obj = (t == T_OBJ) ? obj : mkval(T_OBJ, vdata(obj)); 4632 4628 4633 4629 jsval_t proto = get_slot(js, as_obj, SLOT_PROTO); 4634 - uint8_t pt = vtype(proto); 4635 - if (pt == T_OBJ || pt == T_ARR || pt == T_FUNC) return proto; 4630 + if (is_object_type(proto)) return proto; 4636 4631 4637 - if (t == T_FUNC || t == T_ARR || t == T_PROMISE) return get_prototype_for_type(js, t); 4632 + if (t != T_OBJ) return get_prototype_for_type(js, t); 4638 4633 return js_mknull(); 4639 4634 } 4640 4635 ··· 4644 4639 4645 4640 void js_set_proto(struct js *js, jsval_t obj, jsval_t proto) { 4646 4641 uint8_t t = vtype(obj); 4647 - if (t != T_OBJ && t != T_ARR && t != T_FUNC) return; 4642 + if (!is_object_type(obj)) return; 4648 4643 4649 4644 jsval_t as_obj = (t == T_OBJ) ? obj : mkval(T_OBJ, vdata(obj)); 4650 4645 set_slot(js, as_obj, SLOT_PROTO, proto); ··· 4751 4746 return 0; 4752 4747 } 4753 4748 4749 + static jsval_t getprop_any(struct js *js, jsval_t obj, const char *key, size_t key_len) { 4750 + uint8_t t = vtype(obj); 4751 + 4752 + if (t == T_STR && key_len == 6 && memcmp(key, "length", 6) == 0) { 4753 + jsoff_t byte_len; 4754 + jsoff_t str_off = vstr(js, obj, &byte_len); 4755 + return tov(D(utf16_strlen((const char *)&js->mem[str_off], byte_len))); 4756 + } 4757 + 4758 + if (t == T_STR || t == T_NUM || t == T_BOOL || t == T_BIGINT) { 4759 + jsoff_t off = lkp_proto(js, obj, key, key_len); 4760 + if (off != 0) return resolveprop(js, mkval(T_PROP, off)); 4761 + return js_mkundef(); 4762 + } 4763 + 4764 + if (t == T_OBJ || t == T_ARR || t == T_FUNC) { 4765 + jsval_t as_obj = (t == T_OBJ) ? obj : mkval(T_OBJ, vdata(obj)); 4766 + jsoff_t off = lkp(js, as_obj, key, key_len); 4767 + if (off != 0) return resolveprop(js, mkval(T_PROP, off)); 4768 + off = lkp_proto(js, obj, key, key_len); 4769 + if (off != 0) return resolveprop(js, mkval(T_PROP, off)); 4770 + } 4771 + 4772 + return js_mkundef(); 4773 + } 4774 + 4754 4775 static jsval_t try_dynamic_getter(struct js *js, jsval_t obj, const char *key, size_t key_len) { 4755 4776 jsoff_t obj_off = (jsoff_t)vdata(obj); 4756 4777 dynamic_accessors_t *entry = NULL; ··· 4993 5014 return setter_result; 4994 5015 } 4995 5016 4996 - return setprop(js, obj, key, val); 5017 + return js_setprop(js, obj, key, val); 4997 5018 } 4998 5019 4999 5020 if (vtype(lhs) != T_PROP) { ··· 5164 5185 } 5165 5186 jsval_t key = js_mkstr(js, "length", 6); 5166 5187 jsval_t len_val = tov(D(js_arr_len(js, obj))); 5167 - jsval_t prop = setprop(js, obj, key, len_val); 5188 + jsval_t prop = js_setprop(js, obj, key, len_val); 5168 5189 return prop; 5169 5190 } 5170 5191 } ··· 5213 5234 } 5214 5235 if (streq(keystr, keylen, "name", 4)) return js_mkstr(js, "", 0); 5215 5236 jsval_t key = js_mkstr(js, keystr, keylen); 5216 - jsval_t prop = setprop(js, func_obj, key, js_mkundef()); 5237 + jsval_t prop = js_setprop(js, func_obj, key, js_mkundef()); 5217 5238 return prop; 5218 5239 } 5219 5240 if (vtype(obj) == T_CFUNC) { ··· 5335 5356 } 5336 5357 if (streq(ptr, plen, "name", 4)) return js_mkstr(js, "", 0); 5337 5358 jsval_t key = js_mkstr(js, ptr, plen); 5338 - jsval_t prop = setprop(js, func_obj, key, js_mkundef()); 5359 + jsval_t prop = js_setprop(js, func_obj, key, js_mkundef()); 5339 5360 return prop; 5340 5361 } 5341 5362 ··· 5355 5376 if (desc) return js_mkstr(js, desc, strlen(desc)); 5356 5377 return js_mkundef(); 5357 5378 } 5379 + 5380 + jsval_t sym_proto = get_ctor_proto(js, "Symbol", 6); 5381 + if (vtype(sym_proto) == T_OBJ) { 5382 + jsoff_t off = lkp(js, sym_proto, ptr, plen); 5383 + if (off != 0) return resolveprop(js, mkval(T_PROP, off)); 5384 + } 5385 + 5358 5386 return js_mkundef(); 5359 5387 } 5360 5388 ··· 5563 5591 5564 5592 jsoff_t var_pos = pos, var_len = name_len; 5565 5593 jsoff_t src_pos = pos, src_len = name_len; 5594 + 5566 5595 pos += name_len; 5567 5596 pos = skiptonext(p, len, pos, NULL); 5568 5597 5598 + bool is_nested = false; 5599 + jsoff_t nested_start = 0, nested_len = 0; 5600 + 5569 5601 if (!is_arr && !is_rest && pos < len && p[pos] == ':') { 5570 5602 pos = skiptonext(p, len, pos + 1, NULL); 5571 - jsoff_t rlen = 0; 5572 - if (parseident(&p[pos], len - pos, &rlen) == TOK_IDENTIFIER) { 5573 - var_pos = pos; var_len = rlen; 5574 - pos += rlen; 5603 + 5604 + if (pos < len && (p[pos] == '{' || p[pos] == '[')) { 5605 + is_nested = true; 5606 + nested_start = pos; 5607 + char open = p[pos], close = (open == '{') ? '}' : ']'; 5608 + int depth = 1; 5609 + pos++; 5610 + while (pos < len && depth > 0) { 5611 + if (p[pos] == open) depth++; 5612 + else if (p[pos] == close) depth--; 5613 + pos++; 5614 + } 5615 + nested_len = pos - nested_start; 5575 5616 pos = skiptonext(p, len, pos, NULL); 5617 + } else { 5618 + jsoff_t rlen = 0; 5619 + if (parseident(&p[pos], len - pos, &rlen) == TOK_IDENTIFIER) { 5620 + var_pos = pos; var_len = rlen; 5621 + pos += rlen; 5622 + pos = skiptonext(p, len, pos, NULL); 5623 + } 5576 5624 } 5577 5625 } 5578 5626 ··· 5583 5631 jsoff_t alen = js_arr_len(js, val); 5584 5632 for (jsoff_t i = idx; i < alen; i++) js_arr_push(js, rest, js_arr_get(js, val, i)); 5585 5633 prop_val = rest; 5586 - } else if (is_rest) { 5587 - prop_val = mkobj(js, 0); 5588 - } else if (is_arr) { 5589 - prop_val = js_arr_get(js, val, idx); 5590 - } else { 5591 - jsoff_t off = lkp(js, val, &p[src_pos], src_len); 5592 - prop_val = off > 0 ? resolveprop(js, mkval(T_PROP, off)) : js_mkundef(); 5634 + } else if (is_rest) prop_val = mkobj(js, 0); 5635 + else if (is_arr) prop_val = js_arr_get(js, val, idx); 5636 + else prop_val = getprop_any(js, val, &p[src_pos], src_len); 5637 + 5638 + if (is_nested) { 5639 + jsval_t r = bind_destruct_pattern(js, &p[nested_start], nested_len, prop_val, scope); 5640 + if (is_err(r)) return r; 5641 + idx++; pos = skiptonext(p, len, pos, NULL); 5642 + if (pos < len && p[pos] == ',') pos++; 5643 + continue; 5593 5644 } 5594 5645 5595 5646 if (is_rest) goto bind; ··· 5607 5658 bind:; 5608 5659 jsval_t vname = js_mkstr(js, &p[var_pos], var_len); 5609 5660 if (is_err(vname)) return vname; 5610 - jsval_t r = setprop(js, scope, vname, prop_val); 5661 + jsval_t r = js_setprop(js, scope, vname, prop_val); 5611 5662 if (is_err(r)) return r; 5612 5663 5613 5664 idx++; ··· 5753 5804 5754 5805 jsval_t arguments_obj = mkobj(js, 0); 5755 5806 for (int i = 0; i < nargs; i++) { 5756 - if (i < 10) { 5757 - setprop(js, arguments_obj, js_mkstr(js, INTERN_IDX[i], 1), args[i]); 5758 - } else { 5807 + if (i < 10) js_setprop(js, arguments_obj, js_mkstr(js, INTERN_IDX[i], 1), args[i]); else { 5759 5808 char idxstr[16]; 5760 5809 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)i); 5761 - setprop(js, arguments_obj, js_mkstr(js, idxstr, idxlen), args[i]); 5810 + js_setprop(js, arguments_obj, js_mkstr(js, idxstr, idxlen), args[i]); 5762 5811 } 5763 5812 } 5764 5813 setprop_interned(js, arguments_obj, INTERN_LENGTH, 6, tov((double) nargs)); ··· 5770 5819 5771 5820 const char *toStringTag_key = get_toStringTag_sym_key(); 5772 5821 if (toStringTag_key && toStringTag_key[0] != '\0') { 5773 - setprop(js, arguments_obj, js_mkstr(js, toStringTag_key, strlen(toStringTag_key)), js_mkstr(js, "Arguments", 9)); 5822 + js_setprop(js, arguments_obj, js_mkstr(js, toStringTag_key, strlen(toStringTag_key)), js_mkstr(js, "Arguments", 9)); 5774 5823 } 5775 5824 5776 5825 arguments_obj = mkval(T_ARR, vdata(arguments_obj)); ··· 5906 5955 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 5907 5956 key = js_mkstr(js, idxstr, idxlen); 5908 5957 } 5909 - setprop(js, rest_array, key, args[argi++]); 5958 + js_setprop(js, rest_array, key, args[argi++]); 5910 5959 idx++; 5911 5960 } 5912 5961 jsval_t len_key = js_mkstr(js, "length", 6); 5913 - setprop(js, rest_array, len_key, tov((double) idx)); 5962 + js_setprop(js, rest_array, len_key, tov((double) idx)); 5914 5963 rest_array = mkval(T_ARR, vdata(rest_array)); 5915 - setprop(js, function_scope, js_mkstr(js, &fn[pf->rest_param_start], pf->rest_param_len), rest_array); 5964 + js_setprop(js, function_scope, js_mkstr(js, &fn[pf->rest_param_start], pf->rest_param_len), rest_array); 5916 5965 } 5917 5966 } 5918 5967 ··· 6157 6206 } else { 6158 6207 v = js_mkundef(); 6159 6208 } 6160 - setprop(js, function_scope, js_mkstr(js, &fn[param_name_pos], identlen), v); 6209 + js_setprop(js, function_scope, js_mkstr(js, &fn[param_name_pos], identlen), v); 6161 6210 arg_idx++; 6162 6211 if (fnpos < fnlen && fn[fnpos] == ',') fnpos++; 6163 6212 } ··· 6170 6219 char idxstr[16]; 6171 6220 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 6172 6221 jsval_t key = js_mkstr(js, idxstr, idxlen); 6173 - setprop(js, rest_array, key, args[arg_idx]); 6222 + js_setprop(js, rest_array, key, args[arg_idx]); 6174 6223 idx++; 6175 6224 arg_idx++; 6176 6225 } 6177 6226 jsval_t len_key = js_mkstr(js, "length", 6); 6178 - setprop(js, rest_array, len_key, tov((double) idx)); 6227 + js_setprop(js, rest_array, len_key, tov((double) idx)); 6179 6228 rest_array = mkval(T_ARR, vdata(rest_array)); 6180 - setprop(js, function_scope, js_mkstr(js, &fn[rest_param_start], rest_param_len), rest_array); 6229 + js_setprop(js, function_scope, js_mkstr(js, &fn[rest_param_start], rest_param_len), rest_array); 6181 6230 } 6182 6231 } 6183 6232 ··· 6448 6497 field_val = resolveprop(js, field_val); 6449 6498 } 6450 6499 6451 - jsval_t set_res = setprop(js, target_this, fname, field_val); 6500 + jsval_t set_res = js_setprop(js, target_this, fname, field_val); 6452 6501 if (is_err(set_res)) { 6453 6502 js->current_func = saved_func; 6454 6503 pop_call_frame(); ··· 6494 6543 return res; 6495 6544 } 6496 6545 6497 - static jsval_t js_call_toString(struct js *js, jsval_t value) { 6498 - jsoff_t ts_off = lkp(js, value, "toString", 8); 6499 - if (ts_off == 0) ts_off = lkp_proto(js, value, "toString", 8); 6500 - if (ts_off == 0) goto fallback; 6546 + static bool js_try_call_method(struct js *js, jsval_t obj, const char *method, size_t method_len, jsval_t *args, int nargs, jsval_t *out_result) { 6547 + jsval_t getter = js_mkundef(); bool has_getter = false; 6548 + jsoff_t off = lkp_with_getter(js, obj, method, method_len, &getter, &has_getter); 6501 6549 6502 - jsval_t ts_func = resolveprop(js, mkval(T_PROP, ts_off)); 6503 - uint8_t ft = vtype(ts_func); 6504 - if (ft != T_FUNC && ft != T_CFUNC) goto fallback; 6550 + jsval_t fn; 6551 + if (has_getter) { 6552 + fn = call_proto_accessor(js, obj, getter, true, NULL, 0, false); 6553 + if (is_err(fn)) { *out_result = fn; return true; } 6554 + } else if (off != 0) { 6555 + fn = resolveprop(js, mkval(T_PROP, off)); 6556 + } else return false; 6557 + 6558 + uint8_t ft = vtype(fn); 6559 + if (ft != T_FUNC && ft != T_CFUNC) return false; 6560 + 6561 + js_parse_state_t saved_state; 6562 + JS_SAVE_STATE(js, saved_state); 6563 + uint8_t saved_flags = js->flags; 6505 6564 6506 6565 jsval_t saved_this = js->this_val; 6507 - js->this_val = value; 6566 + js->this_val = obj; 6567 + push_this(obj); 6568 + 6508 6569 jsval_t result; 6570 + if (ft == T_CFUNC) result = ((jsval_t (*)(struct js *, jsval_t *, int))vdata(fn))(js, args, nargs); 6571 + else result = call_js_with_args(js, fn, args, nargs); 6509 6572 6510 - if (ft == T_CFUNC) { 6511 - result = ((jsval_t (*)(struct js *, jsval_t *, int))vdata(ts_func))(js, NULL, 0); 6512 - } else { 6513 - jsval_t func_obj = mkval(T_OBJ, vdata(ts_func)); 6514 - jsoff_t fnlen; 6515 - const char *code_str = get_func_code(js, func_obj, &fnlen); 6516 - if (!code_str) goto restore_fallback; 6517 - 6518 - jsval_t closure_scope = get_slot(js, func_obj, SLOT_SCOPE); 6519 - if (vtype(closure_scope) == T_UNDEF) closure_scope = js->scope; 6520 - 6521 - result = call_js(js, code_str, fnlen, closure_scope); 6522 - } 6573 + bool had_throw = (js->flags & F_THROW) != 0; 6574 + jsval_t thrown = js->thrown_value; 6523 6575 6576 + pop_this(); 6524 6577 js->this_val = saved_this; 6578 + 6579 + JS_RESTORE_STATE(js, saved_state); 6580 + js->flags = saved_flags; 6581 + 6582 + if (had_throw) { 6583 + js->flags |= F_THROW; 6584 + js->thrown_value = thrown; 6585 + } 6586 + 6587 + *out_result = result; 6588 + return true; 6589 + } 6590 + 6591 + static jsval_t js_call_method(struct js *js, jsval_t obj, const char *method, size_t method_len, jsval_t *args, int nargs) { 6592 + jsval_t result; 6593 + if (!js_try_call_method(js, obj, method, method_len, args, nargs, &result)) return js_mkundef(); 6594 + return result; 6595 + } 6596 + 6597 + static jsval_t js_call_toString(struct js *js, jsval_t value) { 6598 + jsval_t result = js_call_method(js, value, "toString", 8, NULL, 0); 6599 + 6600 + if (is_err(result)) return result; 6525 6601 if (vtype(result) == T_STR) return result; 6526 6602 6527 6603 uint8_t rtype = vtype(result); 6604 + if (rtype == T_UNDEF) { 6605 + goto fallback; 6606 + } 6607 + 6528 6608 if (rtype != T_OBJ && rtype != T_ARR && rtype != T_FUNC) { 6529 6609 char buf[256]; 6530 6610 size_t len = tostr(js, result, buf, sizeof(buf)); 6531 6611 return js_mkstr(js, buf, len); 6532 6612 } 6533 6613 6534 - restore_fallback: 6535 - js->this_val = saved_this; 6536 6614 fallback:; 6537 6615 char buf[4096]; 6538 6616 size_t len = tostr(js, value, buf, sizeof(buf)); ··· 6540 6618 } 6541 6619 6542 6620 static jsval_t js_call_valueOf(struct js *js, jsval_t value) { 6543 - jsoff_t off = lkp(js, value, "valueOf", 7); 6544 - if (off == 0) off = lkp_proto(js, value, "valueOf", 7); 6545 - if (off == 0) return value; 6621 + jsval_t result = js_call_method(js, value, "valueOf", 7, NULL, 0); 6622 + if (vtype(result) == T_UNDEF) return value; 6623 + return result; 6624 + } 6625 + 6626 + static inline bool is_primitive(jsval_t v) { 6627 + uint8_t t = vtype(v); 6628 + return t == T_STR || t == T_NUM || t == T_BOOL || t == T_NULL || t == T_UNDEF || t == T_SYMBOL || t == T_BIGINT; 6629 + } 6630 + 6631 + static jsval_t try_exotic_to_primitive(struct js *js, jsval_t value, int hint) { 6632 + const char *tp_key = get_toPrimitive_sym_key(); 6633 + if (!tp_key || !tp_key[0]) return mkval(T_UNDEF, 0); 6634 + size_t tp_key_len = strlen(tp_key); 6635 + 6636 + jsoff_t tp_off = lkp(js, value, tp_key, tp_key_len); 6637 + if (tp_off == 0) tp_off = lkp_proto(js, value, tp_key, tp_key_len); 6638 + if (tp_off == 0) return mkval(T_UNDEF, 0); 6639 + 6640 + jsval_t tp_fn = resolveprop(js, mkval(T_PROP, tp_off)); 6641 + uint8_t ft = vtype(tp_fn); 6642 + 6643 + if (ft == T_UNDEF) return mkval(T_UNDEF, 0); 6644 + if (ft != T_FUNC && ft != T_CFUNC) { 6645 + return js_mkerr_typed(js, JS_ERR_TYPE, "Symbol.toPrimitive is not a function"); 6646 + } 6647 + 6648 + const char *hint_str = hint == 1 ? "string" : (hint == 2 ? "number" : "default"); 6649 + jsval_t hint_arg = js_mkstr(js, hint_str, strlen(hint_str)); 6650 + jsval_t result = js_call_method(js, value, tp_key, tp_key_len, &hint_arg, 1); 6546 6651 6547 - jsval_t fn = resolveprop(js, mkval(T_PROP, off)); 6548 - uint8_t ft = vtype(fn); 6549 - if (ft != T_FUNC && ft != T_CFUNC) return value; 6652 + if (is_err(result) || is_primitive(result)) return result; 6653 + return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert object to primitive value"); 6654 + } 6655 + 6656 + static jsval_t try_ordinary_to_primitive(struct js *js, jsval_t value, int hint) { 6657 + static const char *names[] = {"valueOf", "toString"}; 6658 + static const size_t lens[] = {7, 8}; 6550 6659 6551 - jsval_t saved = js->this_val; 6552 - js->this_val = value; 6660 + int first = (hint == 1); 6553 6661 jsval_t result; 6554 6662 6555 - if (ft == T_CFUNC) { 6556 - result = ((jsval_t (*)(struct js *, jsval_t *, int))vdata(fn))(js, NULL, 0); 6557 - } else { 6558 - jsval_t func_obj = mkval(T_OBJ, vdata(fn)); 6559 - jsoff_t fnlen; 6560 - const char *code_str = get_func_code(js, func_obj, &fnlen); 6561 - if (!code_str) { js->this_val = saved; return value; } 6562 - 6563 - jsval_t closure_scope = get_slot(js, func_obj, SLOT_SCOPE); 6564 - if (vtype(closure_scope) == T_UNDEF) closure_scope = js->scope; 6565 - 6566 - result = call_js(js, code_str, fnlen, closure_scope); 6663 + for (int i = 0; i < 2; i++) { 6664 + int idx = first ^ i; 6665 + if (js_try_call_method(js, value, names[idx], lens[idx], NULL, 0, &result)) 6666 + if (is_err(result) || is_primitive(result)) return result; 6567 6667 } 6568 6668 6569 - js->this_val = saved; 6570 - return result; 6669 + return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert object to primitive value"); 6670 + } 6671 + 6672 + static jsval_t js_to_primitive(struct js *js, jsval_t value, int hint) { 6673 + if (is_primitive(value)) return value; 6674 + if (!is_object_type(value)) return value; 6675 + 6676 + jsval_t result = try_exotic_to_primitive(js, value, hint); 6677 + if (vtype(result) != T_UNDEF) return result; 6678 + 6679 + return try_ordinary_to_primitive(js, value, hint); 6571 6680 } 6572 6681 6573 6682 static inline bool strict_eq_values(struct js *js, jsval_t l, jsval_t r) { ··· 6582 6691 return vdata(l) == vdata(r); 6583 6692 } 6584 6693 6585 - static inline jsval_t coerce_to_str(struct js *js, jsval_t v) { 6694 + jsval_t coerce_to_str(struct js *js, jsval_t v) { 6586 6695 if (vtype(v) == T_STR) return v; 6587 - if (vtype(v) == T_ARR) { 6588 - char buf[1024]; 6589 - size_t len = array_to_string(js, v, buf, sizeof(buf)); 6590 - return js_mkstr(js, buf, len); 6696 + 6697 + if (is_object_type(v)) { 6698 + jsval_t prim = js_to_primitive(js, v, 1); 6699 + if (is_err(prim)) return prim; 6700 + if (vtype(prim) == T_STR) return prim; 6701 + return js_tostring_val(js, prim); 6591 6702 } 6703 + 6704 + return js_tostring_val(js, v); 6705 + } 6706 + 6707 + jsval_t coerce_to_str_concat(struct js *js, jsval_t v) { 6708 + if (vtype(v) == T_STR) return v; 6709 + 6710 + if (is_object_type(v)) { 6711 + jsval_t prim = js_to_primitive(js, v, 0); 6712 + if (is_err(prim)) return prim; 6713 + if (vtype(prim) == T_STR) return prim; 6714 + return js_tostring_val(js, prim); 6715 + } 6716 + 6592 6717 return js_tostring_val(js, v); 6593 6718 } 6594 6719 ··· 6609 6734 while (vdata(upper(js, global_scope)) != 0) global_scope = upper(js, global_scope); 6610 6735 jsval_t key = js_mkstr(js, &js->code[id_off], id_len); 6611 6736 if (is_err(key)) return key; 6612 - jsval_t prop = setprop(js, global_scope, key, r); 6737 + jsval_t prop = js_setprop(js, global_scope, key, r); 6613 6738 return is_err(prop) ? prop : r; 6614 6739 } 6615 6740 return js_mkerr_typed(js, (js->flags & F_STRICT) && vtype(lhs) == T_UNDEF ? JS_ERR_TYPE : JS_ERR_SYNTAX, ··· 6660 6785 6661 6786 L_TOK_UMINUS: 6662 6787 if (vtype(r) == T_BIGINT) return bigint_neg(js, r); 6788 + if (is_object_type(r)) { 6789 + jsval_t prim = js_to_primitive(js, r, 2); 6790 + if (is_err(prim)) return prim; 6791 + return tov(-js_to_number(js, prim)); 6792 + } 6663 6793 return tov(-js_to_number(js, r)); 6664 6794 6665 6795 L_TOK_UPLUS: 6666 6796 if (vtype(r) == T_BIGINT) return js_mkerr(js, "Cannot convert a BigInt value to a number"); 6797 + if (is_object_type(r)) { 6798 + jsval_t prim = js_to_primitive(js, r, 2); 6799 + if (is_err(prim)) return prim; 6800 + return tov(js_to_number(js, prim)); 6801 + } 6667 6802 return tov(js_to_number(js, r)); 6668 6803 6669 6804 L_TOK_TILDA: return tov((double)(~js_to_int32(js_to_number(js, r)))); ··· 6719 6854 if (vtype(lu) == T_BIGINT && vtype(ru) == T_BIGINT) return bigint_add(js, lu, ru); 6720 6855 if (vtype(lu) == T_BIGINT || vtype(ru) == T_BIGINT) return js_mkerr(js, "Cannot mix BigInt value and other types"); 6721 6856 if (is_non_numeric(lu) || is_non_numeric(ru) || (vtype(lu) == T_STR && vtype(ru) == T_STR)) { 6722 - jsval_t l_str = coerce_to_str(js, l); 6857 + jsval_t l_str = coerce_to_str_concat(js, l); 6723 6858 if (is_err(l_str)) return l_str; 6724 - jsval_t r_str = coerce_to_str(js, r); 6859 + jsval_t r_str = coerce_to_str_concat(js, r); 6725 6860 if (is_err(r_str)) return r_str; 6726 6861 return do_string_op(js, op, l_str, r_str); 6727 6862 } ··· 6890 7025 if (is_err(expr_result)) return expr_result; 6891 7026 expr_result = resolveprop(js, expr_result); 6892 7027 7028 + if (vtype(expr_result) == T_SYMBOL) { 7029 + return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert a Symbol value to a string"); 7030 + } 7031 + 6893 7032 if (vtype(expr_result) != T_STR) { 6894 - const char *str = js_str(js, expr_result); 6895 - expr_result = js_mkstr(js, str, strlen(str)); 7033 + expr_result = coerce_to_str(js, expr_result); 7034 + if (is_err(expr_result)) return expr_result; 6896 7035 } 6897 7036 6898 7037 parts[part_count++] = expr_result; ··· 6994 7133 for (int i = 0; i < string_count; i++) { 6995 7134 char idx[16]; 6996 7135 snprintf(idx, sizeof(idx), "%d", i); 6997 - setprop(js, strings_arr, js_mkstr(js, idx, strlen(idx)), strings[i]); 7136 + js_setprop(js, strings_arr, js_mkstr(js, idx, strlen(idx)), strings[i]); 6998 7137 } 6999 - setprop(js, strings_arr, js_mkstr(js, "length", 6), tov((double)string_count)); 7138 + js_setprop(js, strings_arr, js_mkstr(js, "length", 6), tov((double)string_count)); 7000 7139 strings_arr = mkval(T_ARR, vdata(strings_arr)); 7001 7140 7002 7141 jsval_t args[65]; ··· 7238 7377 7239 7378 jsoff_t existing = lkp_scope(js, js->scope, var_name, var_len); 7240 7379 if (existing != 0) { 7241 - jsval_t res = setprop(js, js->scope, js_mkstr(js, var_name, var_len), prop_val); 7380 + jsval_t res = js_setprop(js, js->scope, js_mkstr(js, var_name, var_len), prop_val); 7242 7381 if (is_err(res)) return res; 7243 7382 } else { 7244 7383 jsval_t global_scope = js->scope; 7245 7384 while (vdata(upper(js, global_scope)) != 0) { 7246 7385 global_scope = upper(js, global_scope); 7247 7386 } 7248 - jsval_t res = setprop(js, global_scope, js_mkstr(js, var_name, var_len), prop_val); 7387 + jsval_t res = js_setprop(js, global_scope, js_mkstr(js, var_name, var_len), prop_val); 7249 7388 if (is_err(res)) return res; 7250 7389 } 7251 7390 } ··· 7403 7542 jsval_t regexp_proto = get_ctor_proto(js, "RegExp", 6); 7404 7543 if (vtype(regexp_proto) == T_OBJ) set_proto(js, regexp_obj, regexp_proto); 7405 7544 7406 - setprop(js, regexp_obj, js_mkstr(js, "source", 6), pattern); 7407 - setprop(js, regexp_obj, js_mkstr(js, "flags", 5), flags); 7545 + js_setprop(js, regexp_obj, js_mkstr(js, "source", 6), pattern); 7546 + js_setprop(js, regexp_obj, js_mkstr(js, "flags", 5), flags); 7408 7547 7409 7548 jsoff_t flen = flags_end - flags_start; 7410 7549 const char *fstr = &js->code[flags_start]; ··· 7417 7556 if (fstr[i] == 'y') sticky = true; 7418 7557 } 7419 7558 7420 - setprop(js, regexp_obj, js_mkstr(js, "global", 6), mkval(T_BOOL, global ? 1 : 0)); 7421 - setprop(js, regexp_obj, js_mkstr(js, "ignoreCase", 10), mkval(T_BOOL, ignoreCase ? 1 : 0)); 7422 - setprop(js, regexp_obj, js_mkstr(js, "multiline", 9), mkval(T_BOOL, multiline ? 1 : 0)); 7423 - setprop(js, regexp_obj, js_mkstr(js, "dotAll", 6), mkval(T_BOOL, dotAll ? 1 : 0)); 7424 - setprop(js, regexp_obj, js_mkstr(js, "sticky", 6), mkval(T_BOOL, sticky ? 1 : 0)); 7425 - setprop(js, regexp_obj, js_mkstr(js, "lastIndex", 9), tov(0)); 7559 + js_setprop(js, regexp_obj, js_mkstr(js, "global", 6), mkval(T_BOOL, global ? 1 : 0)); 7560 + js_setprop(js, regexp_obj, js_mkstr(js, "ignoreCase", 10), mkval(T_BOOL, ignoreCase ? 1 : 0)); 7561 + js_setprop(js, regexp_obj, js_mkstr(js, "multiline", 9), mkval(T_BOOL, multiline ? 1 : 0)); 7562 + js_setprop(js, regexp_obj, js_mkstr(js, "dotAll", 6), mkval(T_BOOL, dotAll ? 1 : 0)); 7563 + js_setprop(js, regexp_obj, js_mkstr(js, "sticky", 6), mkval(T_BOOL, sticky ? 1 : 0)); 7564 + js_setprop(js, regexp_obj, js_mkstr(js, "lastIndex", 9), tov(0)); 7426 7565 7427 7566 return regexp_obj; 7428 7567 } ··· 7449 7588 jsval_t func_obj = mkval(T_OBJ, vdata(val)); 7450 7589 if (lkp(js, func_obj, "name", 4) == 0) { 7451 7590 jsval_t name_key = js_mkstr(js, "name", 4); 7452 - if (!is_err(name_key)) setprop(js, func_obj, name_key, key); 7591 + if (!is_err(name_key)) js_setprop(js, func_obj, name_key, key); 7453 7592 } 7454 7593 } 7455 7594 7456 - return setprop(js, obj, key, val); 7595 + return js_setprop(js, obj, key, val); 7457 7596 } 7458 7597 7459 7598 static jsval_t js_obj_literal(struct js *js) { ··· 7498 7637 if (is_internal_prop(prop_key, klen)) continue; 7499 7638 7500 7639 jsval_t key_str = js_mkstr(js, prop_key, klen); 7501 - setprop(js, obj, key_str, prop_val); 7640 + js_setprop(js, obj, key_str, prop_val); 7502 7641 } 7503 7642 7504 7643 spread_next: ··· 7629 7768 if (exe) { 7630 7769 if (is_err(val)) return val; 7631 7770 if (is_err(key)) return key; 7632 - jsval_t res = setprop(js, obj, key, resolveprop(js, val)); 7771 + jsval_t res = js_setprop(js, obj, key, resolveprop(js, val)); 7633 7772 if (is_err(res)) return res; 7634 7773 } 7635 7774 } else if ( ··· 7661 7800 if (is_err(func_obj)) return func_obj; 7662 7801 set_func_code(js, func_obj, &js->code[pos], js->pos - pos); 7663 7802 jsval_t name_key = js_mkstr(js, "name", 4); 7664 - setprop(js, func_obj, name_key, key); 7803 + js_setprop(js, func_obj, name_key, key); 7665 7804 7666 7805 jsval_t closure_scope = for_let_capture_scope(js); 7667 7806 if (is_err(closure_scope)) return closure_scope; ··· 7685 7824 } else js_set_setter_desc(js, obj, key_str, key_len, val, JS_DESC_E | JS_DESC_C); 7686 7825 } 7687 7826 } else { 7688 - jsval_t res = setprop(js, obj, key, val); 7827 + jsval_t res = js_setprop(js, obj, key, val); 7689 7828 if (is_err(res)) return res; 7690 7829 } 7691 7830 } ··· 7830 7969 7831 7970 jsval_t len_key = js_mkstr(js, "length", 6); 7832 7971 if (is_err(len_key)) return len_key; 7833 - jsval_t res_len = setprop(js, func_obj, len_key, tov(param_count)); 7972 + jsval_t res_len = js_setprop(js, func_obj, len_key, tov(param_count)); 7834 7973 if (is_err(res_len)) return res_len; 7835 7974 js_set_descriptor(js, func_obj, "length", 6, JS_DESC_C); 7836 7975 ··· 7849 7988 set_slot(js, func_obj, SLOT_NAME, name_val); 7850 7989 jsval_t name_key = js_mkstr(js, "name", 4); 7851 7990 if (is_err(name_key)) return name_key; 7852 - jsval_t res3 = setprop(js, func_obj, name_key, name_val); 7991 + jsval_t res3 = js_setprop(js, func_obj, name_key, name_val); 7853 7992 if (is_err(res3)) return res3; 7854 7993 } 7855 7994 ··· 9093 9232 jsval_t obj = js_mkundef(); 9094 9233 if (exe) { 9095 9234 obj = resolveprop(js, v); 9096 - if (vtype(obj) != T_OBJ && vtype(obj) != T_ARR) { 9097 - return js_mkerr(js, "cannot destructure non-object"); 9098 - } 9235 + uint8_t ot = vtype(obj); 9236 + if (ot == T_NULL || ot == T_UNDEF) return js_mkerr(js, "cannot destructure null or undefined"); 9099 9237 } 9100 9238 9101 9239 js_parse_state_t end_state; ··· 9176 9314 obj_destruct_rest:; 9177 9315 jsval_t rest_obj = mkobj(js, 0); 9178 9316 if (is_err(rest_obj)) return rest_obj; 9179 - jsoff_t scan = loadoff(js, (jsoff_t) vdata(obj)) & ~(3U | FLAGMASK); 9180 - while (scan < js->brk && scan != 0) { 9181 - jsoff_t header = loadoff(js, scan); 9182 - if (is_slot_prop(header)) { scan = next_prop(header); continue; } 9183 - 9184 - const char *key; jsoff_t klen; 9185 - get_prop_key(js, scan, &key, &klen); 9186 - bool is_picked = false; 9187 - jsoff_t picked_len = js_arr_len(js, picked_keys); 9188 - for (jsoff_t i = 0; i < picked_len; i++) { 9189 - jsval_t pk = js_arr_get(js, picked_keys, i); 9190 - if (vtype(pk) != T_STR) continue; 9191 - jsoff_t pklen, pkoff = vstr(js, pk, &pklen); 9192 - if (klen == pklen && memcmp(key, &js->mem[pkoff], klen) == 0) { is_picked = true; break; } 9193 - } 9194 - if (!is_picked && !(klen == STR_PROTO_LEN && memcmp(key, STR_PROTO, STR_PROTO_LEN) == 0)) { 9195 - jsval_t val = get_prop_val(js, scan); 9196 - jsval_t key_str = js_mkstr(js, key, klen); 9197 - if (is_err(key_str)) return key_str; 9198 - jsval_t res = setprop(js, rest_obj, key_str, val); 9199 - if (is_err(res)) return res; 9317 + uint8_t obj_type = vtype(obj); 9318 + if (obj_type == T_OBJ || obj_type == T_ARR) { 9319 + jsoff_t scan = loadoff(js, (jsoff_t) vdata(obj)) & ~(3U | FLAGMASK); 9320 + while (scan < js->brk && scan != 0) { 9321 + jsoff_t header = loadoff(js, scan); 9322 + if (is_slot_prop(header)) { scan = next_prop(header); continue; } 9323 + 9324 + const char *key; jsoff_t klen; 9325 + get_prop_key(js, scan, &key, &klen); 9326 + bool is_picked = false; 9327 + jsoff_t picked_len = js_arr_len(js, picked_keys); 9328 + for (jsoff_t i = 0; i < picked_len; i++) { 9329 + jsval_t pk = js_arr_get(js, picked_keys, i); 9330 + if (vtype(pk) != T_STR) continue; 9331 + jsoff_t pklen, pkoff = vstr(js, pk, &pklen); 9332 + if (klen == pklen && memcmp(key, &js->mem[pkoff], klen) == 0) { is_picked = true; break; } 9333 + } 9334 + if (!is_picked && !(klen == STR_PROTO_LEN && memcmp(key, STR_PROTO, STR_PROTO_LEN) == 0)) { 9335 + jsval_t val = get_prop_val(js, scan); 9336 + jsval_t key_str = js_mkstr(js, key, klen); 9337 + if (is_err(key_str)) return key_str; 9338 + jsval_t res = js_setprop(js, rest_obj, key_str, val); 9339 + if (is_err(res)) return res; 9340 + } 9341 + scan = next_prop(header); 9200 9342 } 9201 - scan = next_prop(header); 9202 9343 } 9203 9344 { 9204 9345 const char *vn = &js->code[var_off]; ··· 9214 9355 if (is_err(sk)) return sk; 9215 9356 js_arr_push(js, picked_keys, sk); 9216 9357 9217 - jsoff_t poff = lkp(js, obj, &js->code[src_off], src_len); 9218 - jsval_t nobj = poff > 0 ? resolveprop(js, mkval(T_PROP, poff)) : js_mkundef(); 9358 + jsval_t nobj = getprop_any(js, obj, &js->code[src_off], src_len); 9359 + jsoff_t pattern_end = js->pos; 9219 9360 9220 - jsoff_t pattern_end = js->pos; 9221 9361 js->pos = nested_pattern_start; 9222 9362 js->consumed = 1; 9223 9363 ··· 9244 9384 const char *ivn = &js->code[ivoff]; 9245 9385 if (lkp_scope(js, js->scope, ivn, ivlen) > 0) return js_mkerr(js, "'%.*s' already declared", (int)ivlen, ivn); 9246 9386 9247 - jsoff_t ipoff = lkp(js, nobj, &js->code[isoff], islen); 9248 - jsval_t ival = ipoff > 0 ? resolveprop(js, mkval(T_PROP, ipoff)) : js_mkundef(); 9387 + jsval_t ival = getprop_any(js, nobj, &js->code[isoff], islen); 9249 9388 jsval_t ix = mkprop(js, js->scope, js_mkstr(js, ivn, ivlen), ival, is_const ? CONSTMASK : 0); 9250 9389 if (is_err(ix)) return ix; 9251 9390 ··· 9269 9408 jsval_t sk = js_mkstr(js, &js->code[src_off], src_len); 9270 9409 if (is_err(sk)) return sk; 9271 9410 js_arr_push(js, picked_keys, sk); 9272 - 9273 - jsoff_t poff = lkp(js, obj, &js->code[src_off], src_len); 9274 - jsval_t pval = poff > 0 ? resolveprop(js, mkval(T_PROP, poff)) : js_mkundef(); 9411 + jsval_t pval = getprop_any(js, obj, &js->code[src_off], src_len); 9275 9412 9276 9413 if (vtype(pval) == T_UNDEF && default_len > 0) { 9277 9414 pval = js_eval_slice(js, default_off, default_len); ··· 9544 9681 9545 9682 jsval_t len_key = js_mkstr(js, "length", 6); 9546 9683 if (is_err(len_key)) return len_key; 9547 - jsval_t res_len = setprop(js, func_obj, len_key, tov(param_count)); 9684 + jsval_t res_len = js_setprop(js, func_obj, len_key, tov(param_count)); 9548 9685 if (is_err(res_len)) return res_len; 9549 9686 js_set_descriptor(js, func_obj, "length", 6, JS_DESC_C); 9550 9687 jsval_t name_key = js_mkstr(js, "name", 4); ··· 9552 9689 jsval_t name_val = js_mkstr(js, name, nlen); 9553 9690 if (is_err(name_val)) return name_val; 9554 9691 set_slot(js, func_obj, SLOT_NAME, name_val); 9555 - jsval_t res3 = setprop(js, func_obj, name_key, name_val); 9692 + jsval_t res3 = js_setprop(js, func_obj, name_key, name_val); 9556 9693 if (is_err(res3)) return res3; 9557 9694 if (exe) { 9558 9695 jsval_t closure_scope = for_let_capture_scope(js); ··· 9612 9749 if (vtype(async_proto) == T_FUNC) set_proto(js, func_obj, async_proto); 9613 9750 jsval_t len_key = js_mkstr(js, "length", 6); 9614 9751 if (is_err(len_key)) return len_key; 9615 - jsval_t res_len = setprop(js, func_obj, len_key, tov(0)); 9752 + jsval_t res_len = js_setprop(js, func_obj, len_key, tov(0)); 9616 9753 if (is_err(res_len)) return res_len; 9617 9754 js_set_descriptor(js, func_obj, "length", 6, JS_DESC_C); 9618 9755 jsval_t name_key = js_mkstr(js, "name", 4); ··· 9620 9757 jsval_t name_val = js_mkstr(js, name, nlen); 9621 9758 if (is_err(name_val)) return name_val; 9622 9759 set_slot(js, func_obj, SLOT_NAME, name_val); 9623 - jsval_t res3 = setprop(js, func_obj, name_key, name_val); 9760 + jsval_t res3 = js_setprop(js, func_obj, name_key, name_val); 9624 9761 if (is_err(res3)) return res3; 9625 9762 if (exe) { 9626 9763 jsval_t closure_scope = for_let_capture_scope(js); ··· 11471 11608 js_set_setter_desc(js, proto, name_str, name_len, method_func, JS_DESC_C); 11472 11609 } 11473 11610 } else { 11474 - jsval_t set_res = setprop(js, proto, method_name, method_func); 11611 + jsval_t set_res = js_setprop(js, proto, method_name, method_func); 11475 11612 if (is_err(set_res)) return set_res; 11476 11613 } 11477 11614 } ··· 11538 11675 if (is_err(name_key)) return name_key; 11539 11676 jsval_t name_val = class_name_len > 0 ? js_mkstr(js, class_name, class_name_len) : js_mkstr(js, "", 0); 11540 11677 if (is_err(name_val)) return name_val; 11541 - jsval_t res_name = setprop(js, func_obj, name_key, name_val); 11678 + jsval_t res_name = js_setprop(js, func_obj, name_key, name_val); 11542 11679 if (is_err(res_name)) return res_name; 11543 11680 11544 11681 jsval_t proto_key = js_mkstr(js, "prototype", 9); 11545 11682 if (is_err(proto_key)) return proto_key; 11546 - jsval_t proto_res = setprop(js, func_obj, proto_key, proto); 11683 + jsval_t proto_res = js_setprop(js, func_obj, proto_key, proto); 11547 11684 if (is_err(proto_res)) return proto_res; 11548 11685 11549 11686 jsval_t constructor = mkval(T_FUNC, (unsigned long) vdata(func_obj)); 11550 11687 11551 11688 jsval_t ctor_key = js_mkstr(js, "constructor", 11); 11552 11689 if (is_err(ctor_key)) return ctor_key; 11553 - jsval_t ctor_res = setprop(js, proto, ctor_key, constructor); 11690 + jsval_t ctor_res = js_setprop(js, proto, ctor_key, constructor); 11554 11691 if (is_err(ctor_res)) return ctor_res; 11555 11692 js_set_descriptor(js, proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 11556 11693 ··· 11575 11712 field_val = js_eval_slice(js, m->field_start, m->field_end - m->field_start); 11576 11713 field_val = resolveprop(js, field_val); 11577 11714 } 11578 - jsval_t set_res = setprop(js, func_obj, member_name, field_val); 11715 + jsval_t set_res = js_setprop(js, func_obj, member_name, field_val); 11579 11716 if (is_err(set_res)) return set_res; 11580 11717 } else { 11581 11718 jsoff_t mlen = m->fn_end - m->fn_start; ··· 11591 11728 if (vtype(method_func_proto) == T_FUNC) set_proto(js, method_obj, method_func_proto); 11592 11729 11593 11730 jsval_t method_func = mkval(T_FUNC, (unsigned long) vdata(method_obj)); 11594 - jsval_t set_res = setprop(js, func_obj, member_name, method_func); 11731 + jsval_t set_res = js_setprop(js, func_obj, member_name, method_func); 11595 11732 if (is_err(set_res)) return set_res; 11596 11733 } 11597 11734 } ··· 11710 11847 if (existing_off > 0) { 11711 11848 if (has_initializer && !is_err(v)) { 11712 11849 jsval_t key_val = js_mkstr(js, decoded_name, decoded_len); 11713 - setprop(js, var_scope, key_val, resolveprop(js, v)); 11850 + js_setprop(js, var_scope, key_val, resolveprop(js, v)); 11714 11851 } 11715 11852 } else { 11716 11853 jsval_t x = mkprop(js, var_scope, js_mkstr(js, decoded_name, decoded_len), resolveprop(js, v), 0); ··· 11909 12046 return js_stmt_impl(js); 11910 12047 } 11911 12048 12049 + jsval_t js_symbol_to_string(struct js *js, jsval_t sym) { 12050 + const char *desc = js_sym_desc(js, sym); 12051 + if (!desc) return js_mkstr(js, "Symbol()", 8); 12052 + 12053 + size_t desc_len = strlen(desc); 12054 + size_t total = 7 + desc_len + 1; 12055 + 12056 + char stack_buf[128]; 12057 + char *buf = (total + 1 <= sizeof(stack_buf)) ? stack_buf : malloc(total + 1); 12058 + if (!buf) return js_mkerr(js, "out of memory"); 12059 + 12060 + memcpy(buf, "Symbol(", 7); 12061 + memcpy(buf + 7, desc, desc_len); 12062 + buf[7 + desc_len] = ')'; 12063 + buf[total] = '\0'; 12064 + 12065 + jsval_t result = js_mkstr(js, buf, total); 12066 + if (buf != stack_buf) free(buf); 12067 + return result; 12068 + } 12069 + 11912 12070 static jsval_t builtin_String(struct js *js, jsval_t *args, int nargs) { 11913 12071 jsval_t sval; 12072 + 11914 12073 if (nargs == 0) { 11915 12074 sval = js_mkstr(js, "", 0); 12075 + } else if (vtype(args[0]) == T_STR) { 12076 + sval = args[0]; 12077 + } else if (vtype(args[0]) == T_SYMBOL) { 12078 + sval = js_symbol_to_string(js, args[0]); 12079 + if (is_err(sval)) return sval; 11916 12080 } else { 11917 - jsval_t arg = args[0]; 11918 - if (vtype(arg) == T_STR) { 11919 - sval = arg; 11920 - } else { 11921 - const char *str = js_str(js, arg); 11922 - sval = js_mkstr(js, str, strlen(str)); 11923 - } 12081 + sval = coerce_to_str(js, args[0]); 12082 + if (is_err(sval)) return sval; 11924 12083 } 12084 + 11925 12085 jsval_t string_proto = js_get_ctor_proto(js, "String", 6); 11926 12086 if (is_unboxed_obj(js, js->this_val, string_proto)) { 11927 12087 set_slot(js, js->this_val, SLOT_PRIMITIVE, sval); 11928 12088 jsoff_t slen; 11929 12089 vstr(js, sval, &slen); 11930 - setprop(js, js->this_val, js_mkstr(js, "length", 6), tov((double)slen)); 12090 + js_setprop(js, js->this_val, js_mkstr(js, "length", 6), tov((double)slen)); 11931 12091 js_set_descriptor(js, js->this_val, "length", 6, 0); 11932 12092 } 11933 12093 return sval; ··· 12456 12616 for (int i = 0; i < bound_argc; i++) { 12457 12617 char idx[16]; 12458 12618 snprintf(idx, sizeof(idx), "%d", i); 12459 - setprop(js, bound_arr, js_mkstr(js, idx, strlen(idx)), bound_args[i]); 12619 + js_setprop(js, bound_arr, js_mkstr(js, idx, strlen(idx)), bound_args[i]); 12460 12620 } 12461 - setprop(js, bound_arr, js_mkstr(js, "length", 6), tov((double) bound_argc)); 12621 + js_setprop(js, bound_arr, js_mkstr(js, "length", 6), tov((double) bound_argc)); 12462 12622 set_slot(js, bound_func, SLOT_BOUND_ARGS, bound_arr); 12463 12623 } 12464 12624 ··· 12466 12626 if (vtype(func_proto) == T_FUNC) set_proto(js, bound_func, func_proto); 12467 12627 12468 12628 jsval_t bound = mkval(T_FUNC, (unsigned long) vdata(bound_func)); 12469 - setprop(js, bound_func, js_mkstr(js, "length", 6), tov((double) bound_length)); 12629 + js_setprop(js, bound_func, js_mkstr(js, "length", 6), tov((double) bound_length)); 12470 12630 12471 12631 jsval_t proto_setup = setup_func_prototype(js, bound); 12472 12632 if (is_err(proto_setup)) return proto_setup; ··· 12517 12677 for (int i = 0; i < bound_argc; i++) { 12518 12678 char idx[16]; 12519 12679 snprintf(idx, sizeof(idx), "%d", i); 12520 - setprop(js, bound_arr, js_mkstr(js, idx, strlen(idx)), bound_args[i]); 12680 + js_setprop(js, bound_arr, js_mkstr(js, idx, strlen(idx)), bound_args[i]); 12521 12681 } 12522 - setprop(js, bound_arr, js_mkstr(js, "length", 6), tov((double) bound_argc)); 12682 + js_setprop(js, bound_arr, js_mkstr(js, "length", 6), tov((double) bound_argc)); 12523 12683 set_slot(js, bound_func, SLOT_BOUND_ARGS, bound_arr); 12524 12684 } 12525 12685 12526 - setprop(js, bound_func, js_mkstr(js, "length", 6), tov((double) bound_length)); 12686 + js_setprop(js, bound_func, js_mkstr(js, "length", 6), tov((double) bound_length)); 12527 12687 12528 12688 jsval_t bound = mkval(T_FUNC, (unsigned long) vdata(bound_func)); 12529 12689 jsval_t proto_setup = setup_func_prototype(js, bound); ··· 12538 12698 if (nargs == 1 && vtype(args[0]) == T_NUM) { 12539 12699 jsval_t err = validate_array_length(js, args[0]); 12540 12700 if (is_err(err)) return err; 12541 - setprop(js, arr, ANT_STRING("length"), tov(tod(args[0]))); 12701 + js_setprop(js, arr, ANT_STRING("length"), tov(tod(args[0]))); 12542 12702 } else if (nargs > 0) { 12543 12703 for (int i = 0; i < nargs; i++) { 12544 12704 char idxstr[16]; 12545 12705 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)i); 12546 - setprop(js, arr, js_mkstr(js, idxstr, idxlen), args[i]); 12706 + js_setprop(js, arr, js_mkstr(js, idxstr, idxlen), args[i]); 12547 12707 } 12548 - setprop(js, arr, ANT_STRING("length"), tov((double)nargs)); 12708 + js_setprop(js, arr, ANT_STRING("length"), tov((double)nargs)); 12549 12709 } 12550 12710 12551 12711 return arr; ··· 12583 12743 return this_val; 12584 12744 } 12585 12745 12746 + static jsval_t builtin_Error_toString(struct js *js, jsval_t *args, int nargs) { 12747 + jsval_t this_val = js_getthis(js); 12748 + 12749 + jsval_t name = js_get(js, this_val, "name"); 12750 + if (vtype(name) == T_UNDEF) name = js_mkstr(js, "Error", 5); 12751 + else if (vtype(name) != T_STR) { 12752 + const char *s = js_str(js, name); 12753 + name = js_mkstr(js, s, strlen(s)); 12754 + } 12755 + 12756 + jsval_t msg = js_get(js, this_val, "message"); 12757 + if (vtype(msg) == T_UNDEF) msg = js_mkstr(js, "", 0); 12758 + else if (vtype(msg) != T_STR) { 12759 + const char *s = js_str(js, msg); 12760 + msg = js_mkstr(js, s, strlen(s)); 12761 + } 12762 + 12763 + jsoff_t name_len, msg_len; 12764 + jsoff_t name_off = vstr(js, name, &name_len); 12765 + jsoff_t msg_off = vstr(js, msg, &msg_len); 12766 + 12767 + const char *name_str = (const char *)&js->mem[name_off]; 12768 + const char *msg_str = (const char *)&js->mem[msg_off]; 12769 + 12770 + if (name_len == 0) return msg; 12771 + if (msg_len == 0) return name; 12772 + 12773 + size_t total = name_len + 2 + msg_len; 12774 + char *buf = malloc(total + 1); 12775 + if (!buf) return js_mkerr(js, "out of memory"); 12776 + 12777 + memcpy(buf, name_str, name_len); 12778 + buf[name_len] = ':'; buf[name_len + 1] = ' '; 12779 + memcpy(buf + name_len + 2, msg_str, msg_len); 12780 + buf[total] = '\0'; 12781 + 12782 + jsval_t result = js_mkstr(js, buf, total); 12783 + free(buf); return result; 12784 + } 12785 + 12586 12786 static jsval_t builtin_AggregateError(struct js *js, jsval_t *args, int nargs) { 12587 12787 bool is_new = (vtype(js->new_target) != T_UNDEF); 12588 12788 jsval_t this_val = js->this_val; ··· 12637 12837 } 12638 12838 12639 12839 jsval_t source_key = js_mkstr(js, "source", 6); 12640 - setprop(js, regexp_obj, source_key, pattern); 12840 + js_setprop(js, regexp_obj, source_key, pattern); 12641 12841 12642 12842 jsval_t flags_key = js_mkstr(js, "flags", 5); 12643 - setprop(js, regexp_obj, flags_key, flags); 12843 + js_setprop(js, regexp_obj, flags_key, flags); 12644 12844 12645 12845 jsoff_t flags_len, flags_off = vstr(js, flags, &flags_len); 12646 12846 const char *flags_str = (char *) &js->mem[flags_off]; ··· 12654 12854 if (flags_str[i] == 'y') sticky = true; 12655 12855 } 12656 12856 12657 - setprop(js, regexp_obj, js_mkstr(js, "global", 6), mkval(T_BOOL, global ? 1 : 0)); 12658 - setprop(js, regexp_obj, js_mkstr(js, "ignoreCase", 10), mkval(T_BOOL, ignoreCase ? 1 : 0)); 12659 - setprop(js, regexp_obj, js_mkstr(js, "multiline", 9), mkval(T_BOOL, multiline ? 1 : 0)); 12660 - setprop(js, regexp_obj, js_mkstr(js, "dotAll", 6), mkval(T_BOOL, dotAll ? 1 : 0)); 12661 - setprop(js, regexp_obj, js_mkstr(js, "sticky", 6), mkval(T_BOOL, sticky ? 1 : 0)); 12662 - setprop(js, regexp_obj, js_mkstr(js, "lastIndex", 9), tov(0)); 12857 + js_setprop(js, regexp_obj, js_mkstr(js, "global", 6), mkval(T_BOOL, global ? 1 : 0)); 12858 + js_setprop(js, regexp_obj, js_mkstr(js, "ignoreCase", 10), mkval(T_BOOL, ignoreCase ? 1 : 0)); 12859 + js_setprop(js, regexp_obj, js_mkstr(js, "multiline", 9), mkval(T_BOOL, multiline ? 1 : 0)); 12860 + js_setprop(js, regexp_obj, js_mkstr(js, "dotAll", 6), mkval(T_BOOL, dotAll ? 1 : 0)); 12861 + js_setprop(js, regexp_obj, js_mkstr(js, "sticky", 6), mkval(T_BOOL, sticky ? 1 : 0)); 12862 + js_setprop(js, regexp_obj, js_mkstr(js, "lastIndex", 9), tov(0)); 12663 12863 12664 12864 return regexp_obj; 12665 12865 } ··· 12783 12983 pcre2_match_data_free(match_data); 12784 12984 pcre2_code_free(re); 12785 12985 if (global_flag) { 12786 - setprop(js, regexp, js_mkstr(js, "lastIndex", 9), tov(0)); 12986 + js_setprop(js, regexp, js_mkstr(js, "lastIndex", 9), tov(0)); 12787 12987 } 12788 12988 return js_mknull(); 12789 12989 } ··· 12803 13003 } 12804 13004 } 12805 13005 12806 - setprop(js, result_arr, js_mkstr(js, "index", 5), tov((double)ovector[0])); 12807 - setprop(js, result_arr, js_mkstr(js, "input", 5), str_arg); 13006 + js_setprop(js, result_arr, js_mkstr(js, "index", 5), tov((double)ovector[0])); 13007 + js_setprop(js, result_arr, js_mkstr(js, "input", 5), str_arg); 12808 13008 12809 13009 if (global_flag) { 12810 13010 PCRE2_SIZE new_lastindex = ovector[1]; 12811 13011 if (ovector[0] == ovector[1]) new_lastindex++; 12812 - setprop(js, regexp, js_mkstr(js, "lastIndex", 9), tov((double)new_lastindex)); 13012 + js_setprop(js, regexp, js_mkstr(js, "lastIndex", 9), tov((double)new_lastindex)); 12813 13013 } 12814 13014 12815 13015 pcre2_match_data_free(match_data); ··· 13146 13346 } 13147 13347 13148 13348 static jsval_t builtin_Date_toString(struct js *js, jsval_t *args, int nargs) { 13149 - (void) args; 13150 - (void) nargs; 13151 13349 double ms = date_get_time(js, js->this_val); 13152 13350 if (isnan(ms)) return js_mkstr(js, "Invalid Date", 12); 13351 + 13153 13352 time_t t = (time_t)(ms / 1000.0); 13154 - char *s = ctime(&t); 13155 - size_t len = strlen(s); 13156 - if (len > 0 && s[len - 1] == '\n') len--; 13157 - return js_mkstr(js, s, len); 13353 + struct tm *tm_local = localtime(&t); 13354 + if (!tm_local) return js_mkstr(js, "Invalid Date", 12); 13355 + 13356 + struct tm local_copy = *tm_local; 13357 + struct tm *gm = gmtime(&t); 13358 + long offset_sec = (long)difftime(mktime(&local_copy), mktime(gm)); 13359 + int offset_hours = (int)(offset_sec / 3600); 13360 + int offset_mins = (int)(labs(offset_sec) % 3600) / 60; 13361 + 13362 + char tz[32], buf[80]; 13363 + strftime(tz, sizeof(tz), "%Z", &local_copy); 13364 + strftime(buf, sizeof(buf), "%a %b %d %Y %H:%M:%S", &local_copy); 13365 + size_t n = strlen(buf); 13366 + n += snprintf(buf + n, sizeof(buf) - n, " GMT%+03d%02d (%s)", offset_hours, offset_mins, tz); 13367 + return js_mkstr(js, buf, n); 13158 13368 } 13159 13369 13160 13370 static jsval_t builtin_Date_valueOf(struct js *js, jsval_t *args, int nargs) { ··· 13834 14044 return tov(trunc(x)); 13835 14045 } 13836 14046 14047 + typedef jsval_t (*dynamic_kv_mapper_fn)( 14048 + struct js *js, 14049 + jsval_t key, 14050 + jsval_t val 14051 + ); 14052 + 14053 + static jsval_t iterate_dynamic_keys(struct js *js, jsval_t obj, dynamic_accessors_t *acc, dynamic_kv_mapper_fn mapper) { 14054 + jsval_t keys_arr = acc->keys(js, obj); 14055 + jsval_t arr = mkarr(js); 14056 + jsoff_t len = get_array_length(js, keys_arr); 14057 + 14058 + for (jsoff_t i = 0; i < len; i++) { 14059 + char idx_buf[16]; 14060 + size_t idx_len = uint_to_str(idx_buf, sizeof(idx_buf), (unsigned)i); 14061 + jsoff_t prop_off = lkp(js, keys_arr, idx_buf, idx_len); 14062 + if (!prop_off) continue; 14063 + jsval_t key_val = resolveprop(js, mkval(T_PROP, prop_off)); 14064 + if (vtype(key_val) != T_STR) continue; 14065 + jsoff_t klen; jsoff_t str_off = vstr(js, key_val, &klen); 14066 + const char *key = (const char *)&js->mem[str_off]; 14067 + jsval_t val = acc->getter(js, obj, key, klen); 14068 + js_arr_push(js, arr, mapper ? mapper(js, key_val, val) : val); 14069 + } 14070 + 14071 + return mkval(T_ARR, vdata(arr)); 14072 + } 14073 + 13837 14074 static jsval_t builtin_object_keys(struct js *js, jsval_t *args, int nargs) { 13838 14075 if (nargs == 0) return mkarr(js); 13839 14076 jsval_t obj = args[0]; ··· 13841 14078 if (vtype(obj) != T_OBJ && vtype(obj) != T_ARR && vtype(obj) != T_FUNC) return mkarr(js); 13842 14079 if (vtype(obj) == T_FUNC) obj = mkval(T_OBJ, vdata(obj)); 13843 14080 14081 + jsoff_t obj_off = (jsoff_t)vdata(obj); 14082 + dynamic_accessors_t *acc = NULL; 14083 + HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), acc); 14084 + if (acc && acc->keys) return acc->keys(js, obj); 14085 + 13844 14086 jsval_t arr = mkarr(js); 13845 14087 jsoff_t idx = 0; 13846 - 13847 - jsoff_t obj_off = (jsoff_t)vdata(obj); 13848 14088 jsoff_t next = loadoff(js, obj_off) & ~(3U | FLAGMASK); 13849 14089 13850 14090 while (next < js->brk && next != 0) { ··· 13895 14135 if (vtype(obj) != T_OBJ && vtype(obj) != T_ARR && vtype(obj) != T_FUNC) return mkarr(js); 13896 14136 if (vtype(obj) == T_FUNC) obj = mkval(T_OBJ, vdata(obj)); 13897 14137 13898 - jsval_t arr = mkarr(js); 13899 - jsoff_t idx = 0; 13900 - jsoff_t next = loadoff(js, (jsoff_t) vdata(obj)) & ~(3U | FLAGMASK); 14138 + jsoff_t obj_off = (jsoff_t)vdata(obj); 14139 + dynamic_accessors_t *acc = NULL; 14140 + HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), acc); 14141 + if (acc && acc->keys && acc->getter) return iterate_dynamic_keys(js, obj, acc, NULL); 14142 + 14143 + jsval_t arr = mkarr(js); jsoff_t idx = 0; 14144 + jsoff_t next = loadoff(js, obj_off) & ~(3U | FLAGMASK); 13901 14145 13902 14146 while (next < js->brk && next != 0) { 13903 14147 jsoff_t header = loadoff(js, next); ··· 13912 14156 if (is_internal_prop(key, klen)) continue; 13913 14157 13914 14158 bool should_include = true; 13915 - jsoff_t obj_off = (jsoff_t)vdata(obj); 13916 14159 descriptor_entry_t *desc = lookup_descriptor(obj_off, key, klen); 13917 - if (desc) { 13918 - should_include = desc->enumerable; 13919 - } 14160 + if (desc) should_include = desc->enumerable; 13920 14161 13921 14162 if (should_include) { 13922 14163 char idxstr[16]; ··· 13932 14173 return mkval(T_ARR, vdata(arr)); 13933 14174 } 13934 14175 14176 + static jsval_t map_to_entry(struct js *js, jsval_t key, jsval_t val) { 14177 + jsval_t pair = mkarr(js); 14178 + js_mkprop_fast(js, pair, "0", 1, key); 14179 + js_mkprop_fast(js, pair, "1", 1, val); 14180 + js_mkprop_fast(js, pair, "length", 6, tov(2.0)); 14181 + return mkval(T_ARR, vdata(pair)); 14182 + } 14183 + 13935 14184 static jsval_t builtin_object_entries(struct js *js, jsval_t *args, int nargs) { 13936 14185 if (nargs == 0) return mkarr(js); 13937 14186 jsval_t obj = args[0]; ··· 13939 14188 if (vtype(obj) != T_OBJ && vtype(obj) != T_ARR && vtype(obj) != T_FUNC) return mkarr(js); 13940 14189 if (vtype(obj) == T_FUNC) obj = mkval(T_OBJ, vdata(obj)); 13941 14190 14191 + jsoff_t obj_off = (jsoff_t)vdata(obj); 14192 + dynamic_accessors_t *acc = NULL; 14193 + HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), acc); 14194 + if (acc && acc->keys && acc->getter) { 14195 + return iterate_dynamic_keys(js, obj, acc, map_to_entry); 14196 + } 14197 + 13942 14198 jsval_t arr = mkarr(js); 13943 14199 jsoff_t idx = 0; 13944 - jsoff_t next = loadoff(js, (jsoff_t) vdata(obj)) & ~(3U | FLAGMASK); 14200 + jsoff_t next = loadoff(js, obj_off) & ~(3U | FLAGMASK); 13945 14201 13946 14202 while (next < js->brk && next != 0) { 13947 14203 jsoff_t header = loadoff(js, next); ··· 13953 14209 jsval_t val = loadval(js, next + (jsoff_t) (sizeof(next) + sizeof(koff))); 13954 14210 13955 14211 next = next_prop(header); 13956 - 13957 14212 if (is_internal_prop(key, klen)) continue; 13958 14213 13959 14214 bool should_include = true; 13960 - jsoff_t obj_off = (jsoff_t)vdata(obj); 13961 14215 descriptor_entry_t *desc = lookup_descriptor(obj_off, key, klen); 13962 - if (desc) { 13963 - should_include = desc->enumerable; 13964 - } 14216 + if (desc) should_include = desc->enumerable; 13965 14217 13966 14218 if (should_include) { 13967 14219 jsval_t pair = mkarr(js); ··· 13987 14239 uint8_t t = vtype(obj); 13988 14240 13989 14241 if (t == T_STR || t == T_NUM || t == T_BOOL || t == T_BIGINT) return get_prototype_for_type(js, t); 13990 - if (t == T_OBJ || t == T_ARR || t == T_FUNC) return get_proto(js, obj); 14242 + if (is_object_type(obj)) return get_proto(js, obj); 13991 14243 13992 14244 return js_mknull(); 13993 14245 } ··· 14093 14345 if (val_off != 0) { 14094 14346 jsval_t val = resolveprop(js, mkval(T_PROP, val_off)); 14095 14347 jsval_t key_str = js_mkstr(js, key, klen); 14096 - setprop(js, obj, key_str, val); 14348 + js_setprop(js, obj, key_str, val); 14097 14349 } 14098 14350 } 14099 14351 ··· 14377 14629 14378 14630 if (should_copy) { 14379 14631 jsval_t key_str = js_mkstr(js, key, klen); 14380 - setprop(js, as_obj, key_str, val); 14632 + js_setprop(js, as_obj, key_str, val); 14381 14633 } 14382 14634 } 14383 14635 } ··· 14534 14786 key = js_mkstr(js, buf, n); 14535 14787 } 14536 14788 14537 - setprop(js, result, key, val); 14789 + js_setprop(js, result, key, val); 14538 14790 } 14539 14791 14540 14792 return result; ··· 14570 14822 14571 14823 if (desc && (desc->has_getter || desc->has_setter)) { 14572 14824 if (desc->has_getter) { 14573 - setprop(js, result, js_mkstr(js, "get", 3), desc->getter); 14825 + js_setprop(js, result, js_mkstr(js, "get", 3), desc->getter); 14574 14826 } 14575 14827 if (desc->has_setter) { 14576 - setprop(js, result, js_mkstr(js, "set", 3), desc->setter); 14828 + js_setprop(js, result, js_mkstr(js, "set", 3), desc->setter); 14577 14829 } 14578 - setprop(js, result, js_mkstr(js, "enumerable", 10), js_bool(desc->enumerable)); 14579 - setprop(js, result, js_mkstr(js, "configurable", 12), js_bool(desc->configurable)); 14830 + js_setprop(js, result, js_mkstr(js, "enumerable", 10), js_bool(desc->enumerable)); 14831 + js_setprop(js, result, js_mkstr(js, "configurable", 12), js_bool(desc->configurable)); 14580 14832 } else { 14581 14833 if (prop_off != 0) { 14582 14834 jsval_t prop_val = resolveprop(js, mkval(T_PROP, prop_off)); 14583 - setprop(js, result, js_mkstr(js, "value", 5), prop_val); 14835 + js_setprop(js, result, js_mkstr(js, "value", 5), prop_val); 14584 14836 } 14585 - setprop(js, result, js_mkstr(js, "writable", 8), desc ? (js_bool(desc->writable)) : js_true); 14586 - setprop(js, result, js_mkstr(js, "enumerable", 10), desc ? (js_bool(desc->enumerable)) : js_true); 14587 - setprop(js, result, js_mkstr(js, "configurable", 12), desc ? (js_bool(desc->configurable)) : js_true); 14837 + js_setprop(js, result, js_mkstr(js, "writable", 8), desc ? (js_bool(desc->writable)) : js_true); 14838 + js_setprop(js, result, js_mkstr(js, "enumerable", 10), desc ? (js_bool(desc->enumerable)) : js_true); 14839 + js_setprop(js, result, js_mkstr(js, "configurable", 12), desc ? (js_bool(desc->configurable)) : js_true); 14588 14840 } 14589 14841 14590 14842 return result; ··· 14646 14898 14647 14899 free(keys); 14648 14900 js_mkprop_fast(js, arr, "length", 6, tov((double) idx)); 14901 + return mkval(T_ARR, vdata(arr)); 14902 + } 14903 + 14904 + // refactor with desc when SLOT_SYMBOL 14905 + static jsval_t builtin_object_getOwnPropertySymbols(struct js *js, jsval_t *args, int nargs) { 14906 + if (nargs == 0) return mkarr(js); 14907 + jsval_t obj = args[0]; 14908 + 14909 + uint8_t t = vtype(obj); 14910 + if (t != T_OBJ && t != T_ARR && t != T_FUNC) return mkarr(js); 14911 + if (t == T_FUNC) obj = mkval(T_OBJ, vdata(obj)); 14912 + 14913 + jsval_t arr = mkarr(js); jsoff_t idx = 0; 14914 + jsoff_t next = loadoff(js, (jsoff_t)vdata(obj)) & ~(3U | FLAGMASK); 14915 + 14916 + while (next < js->brk && next != 0) { 14917 + jsoff_t header = loadoff(js, next); 14918 + if (!is_slot_prop(header)) { 14919 + jsoff_t koff = loadoff(js, next + (jsoff_t)sizeof(next)); 14920 + jsoff_t klen = offtolen(loadoff(js, koff)); 14921 + const char *key = (char *)&js->mem[koff + sizeof(koff)]; 14922 + 14923 + if (klen >= 9 && memcmp(key, "__sym_", 6) == 0 && memcmp(key + klen - 2, "__", 2) == 0) { 14924 + uint64_t sym_id = 0; 14925 + for (const char *p = key + 6; *p >= '0' && *p <= '9' && sym_id <= PROPREF_PAYLOAD / 10; p++) 14926 + sym_id = sym_id * 10 + (uint64_t)(*p - '0'); 14927 + char idxstr[16]; size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx++); 14928 + js_mkprop_fast(js, arr, idxstr, idxlen, mkval(T_SYMBOL, (sym_id & PROPREF_PAYLOAD) << PROPREF_KEY_SHIFT)); 14929 + } 14930 + } 14931 + next = next_prop(header); 14932 + } 14933 + 14934 + js_mkprop_fast(js, arr, "length", 6, tov((double)idx)); 14649 14935 return mkval(T_ARR, vdata(arr)); 14650 14936 } 14651 14937 ··· 14771 15057 obj = resolveprop(js, obj); 14772 15058 uint8_t t = vtype(obj); 14773 15059 14774 - if (t == T_OBJ || t == T_ARR || t == T_FUNC) { 14775 - jsval_t check_obj = (t == T_FUNC) ? mkval(T_OBJ, vdata(obj)) : obj; 15060 + if (is_object_type(obj)) { 15061 + jsval_t check_obj = (t != T_OBJ) ? mkval(T_OBJ, vdata(obj)) : obj; 14776 15062 const char *tostr_tag_key = get_toStringTag_sym_key(); 14777 15063 jsoff_t tag_off = lkp(js, check_obj, tostr_tag_key, strlen(tostr_tag_key)); 14778 15064 if (tag_off == 0) tag_off = lkp_proto(js, check_obj, tostr_tag_key, strlen(tostr_tag_key)); ··· 14792 15078 const char *type_name = NULL; 14793 15079 14794 15080 switch (t) { 14795 - case T_UNDEF: type_name = "Undefined"; break; 14796 - case T_NULL: type_name = "Null"; break; 14797 - case T_BOOL: type_name = "Boolean"; break; 14798 - case T_NUM: type_name = "Number"; break; 14799 - case T_STR: type_name = "String"; break; 14800 - case T_ARR: type_name = "Array"; break; 14801 - case T_FUNC: type_name = "Function"; break; 14802 - case T_ERR: type_name = "Error"; break; 14803 - case T_BIGINT: type_name = "BigInt"; break; 14804 - case T_OBJ: type_name = "Object"; break; 14805 - default: type_name = "Unknown"; break; 15081 + case T_UNDEF: type_name = "Undefined"; break; 15082 + case T_NULL: type_name = "Null"; break; 15083 + case T_BOOL: type_name = "Boolean"; break; 15084 + case T_NUM: type_name = "Number"; break; 15085 + case T_STR: type_name = "String"; break; 15086 + case T_ARR: type_name = "Array"; break; 15087 + case T_FUNC: type_name = "Function"; break; 15088 + case T_ERR: type_name = "Error"; break; 15089 + case T_BIGINT: type_name = "BigInt"; break; 15090 + case T_PROMISE: type_name = "Promise"; break; 15091 + case T_OBJ: type_name = "Object"; break; 15092 + default: type_name = "Unknown"; break; 14806 15093 } 14807 15094 14808 15095 char buf[256]; ··· 14881 15168 char idxstr[16]; 14882 15169 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)len); 14883 15170 jsval_t key = js_mkstr(js, idxstr, idxlen); 14884 - setprop(js, arr, key, args[i]); 15171 + js_setprop(js, arr, key, args[i]); 14885 15172 len++; 14886 15173 } 14887 15174 14888 15175 jsval_t len_key = js_mkstr(js, "length", 6); 14889 15176 jsval_t len_val = tov((double) len); 14890 15177 14891 - setprop(js, arr, len_key, len_val); 15178 + js_setprop(js, arr, len_key, len_val); 14892 15179 return len_val; 14893 15180 } 14894 15181 ··· 14941 15228 14942 15229 jsval_t len_key = js_mkstr(js, "length", 6); 14943 15230 jsval_t len_val = tov((double) len); 14944 - setprop(js, arr, len_key, len_val); 15231 + js_setprop(js, arr, len_key, len_val); 14945 15232 js->needs_gc = true; 14946 15233 14947 15234 return result; ··· 14994 15281 jsval_t elem = resolveprop(js, mkval(T_PROP, elem_off)); 14995 15282 size_t result_idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)result_idx); 14996 15283 jsval_t key = js_mkstr(js, idxstr, result_idxlen); 14997 - setprop(js, result, key, elem); 15284 + js_setprop(js, result, key, elem); 14998 15285 } 14999 15286 result_idx++; 15000 15287 } 15001 15288 15002 15289 jsval_t len_key = js_mkstr(js, "length", 6); 15003 - setprop(js, result, len_key, tov((double) result_idx)); 15290 + js_setprop(js, result, len_key, tov((double) result_idx)); 15004 15291 return mkval(T_ARR, vdata(result)); 15005 15292 } 15006 15293 ··· 15057 15344 15058 15345 if (elem_off != 0) { 15059 15346 jsval_t elem = resolveprop(js, mkval(T_PROP, elem_off)); 15060 - if (vtype(elem) == T_STR) { 15061 - jsoff_t elem_len, elem_off_str = vstr(js, elem, &elem_len); 15347 + uint8_t et = vtype(elem); 15348 + if (et == T_NULL || et == T_UNDEF) continue; 15349 + 15350 + const char *elem_str = NULL; 15351 + size_t elem_len = 0; 15352 + char numstr[64]; 15353 + jsval_t str_val = js_mkundef(); 15354 + 15355 + if (et == T_STR) { 15356 + jsoff_t soff, slen; 15357 + soff = vstr(js, elem, &slen); 15358 + elem_str = (const char *)&js->mem[soff]; 15359 + elem_len = slen; 15360 + } else if (et == T_NUM) { 15361 + snprintf(numstr, sizeof(numstr), "%g", tod(elem)); 15362 + elem_str = numstr; 15363 + elem_len = strlen(numstr); 15364 + } else if (et == T_BOOL) { 15365 + elem_str = vdata(elem) ? "true" : "false"; 15366 + elem_len = strlen(elem_str); 15367 + } else if (et == T_ARR || et == T_OBJ || et == T_FUNC || et == T_BIGINT) { 15368 + str_val = to_string_val(js, elem); 15369 + 15370 + if (is_err(str_val)) { 15371 + free(result); 15372 + return str_val; 15373 + } 15374 + 15375 + if (vtype(str_val) == T_STR) { 15376 + jsoff_t soff, slen; 15377 + soff = vstr(js, str_val, &slen); 15378 + elem_str = (const char *)&js->mem[soff]; 15379 + elem_len = slen; 15380 + } 15381 + } 15382 + 15383 + 15384 + if (elem_str && elem_len > 0) { 15062 15385 if (result_len + elem_len >= capacity) { 15063 15386 capacity = (result_len + elem_len + 1) * 2; 15064 15387 char *new_result = (char *)ant_realloc(result, capacity); 15065 - if (!new_result) return js_mkerr(js, "oom"); 15388 + if (!new_result) { free(result); return js_mkerr(js, "oom"); } 15066 15389 result = new_result; 15067 15390 } 15068 - memcpy(result + result_len, &js->mem[elem_off_str], elem_len); 15391 + memcpy(result + result_len, elem_str, elem_len); 15069 15392 result_len += elem_len; 15070 - } else if (vtype(elem) == T_NUM) { 15071 - char numstr[32]; 15072 - snprintf(numstr, sizeof(numstr), "%g", tod(elem)); 15073 - size_t num_len = strlen(numstr); 15074 - if (result_len + num_len >= capacity) { 15075 - capacity = (result_len + num_len + 1) * 2; 15076 - char *new_result = (char *)ant_realloc(result, capacity); 15077 - if (!new_result) return js_mkerr(js, "oom"); 15078 - result = new_result; 15079 - } 15080 - memcpy(result + result_len, numstr, num_len); 15081 - result_len += num_len; 15082 - } else if (vtype(elem) == T_BOOL) { 15083 - const char *boolstr = vdata(elem) ? "true" : "false"; 15084 - size_t bool_len = strlen(boolstr); 15085 - if (result_len + bool_len >= capacity) { 15086 - capacity = (result_len + bool_len + 1) * 2; 15087 - char *new_result = (char *)ant_realloc(result, capacity); 15088 - if (!new_result) return js_mkerr(js, "oom"); 15089 - result = new_result; 15090 - } 15091 - memcpy(result + result_len, boolstr, bool_len); 15092 - result_len += bool_len; 15093 15393 } 15094 15394 } 15095 15395 } 15396 + 15096 15397 jsval_t ret = js_mkstr(js, result, result_len); 15097 - free(result); 15098 - return ret; 15398 + free(result); return ret; 15099 15399 } 15100 15400 15101 15401 static jsval_t builtin_array_includes(struct js *js, jsval_t *args, int nargs) { ··· 15488 15788 flat_helper(js, arr, result, &result_idx, depth); 15489 15789 15490 15790 jsval_t len_key = js_mkstr(js, "length", 6); 15491 - setprop(js, result, len_key, tov((double) result_idx)); 15791 + js_setprop(js, result, len_key, tov((double) result_idx)); 15492 15792 return mkval(T_ARR, vdata(result)); 15493 15793 } 15494 15794 ··· 15616 15916 char idxstr[16]; 15617 15917 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)i); 15618 15918 jsval_t key = js_mkstr(js, idxstr, idxlen); 15619 - setprop(js, arr, key, value); 15919 + js_setprop(js, arr, key, value); 15620 15920 } 15621 15921 15622 15922 return arr; ··· 15782 16082 char res_idx[16]; 15783 16083 snprintf(res_idx, sizeof(res_idx), "%u", (unsigned) result_idx); 15784 16084 jsval_t key = js_mkstr(js, res_idx, strlen(res_idx)); 15785 - setprop(js, result, key, m_elem); 16085 + js_setprop(js, result, key, m_elem); 15786 16086 } 15787 16087 result_idx++; 15788 16088 } ··· 15790 16090 char res_idx[16]; 15791 16091 snprintf(res_idx, sizeof(res_idx), "%u", (unsigned) result_idx); 15792 16092 jsval_t key = js_mkstr(js, res_idx, strlen(res_idx)); 15793 - setprop(js, result, key, mapped); 16093 + js_setprop(js, result, key, mapped); 15794 16094 result_idx++; 15795 16095 } 15796 16096 } 15797 16097 15798 16098 jsval_t len_key = js_mkstr(js, "length", 6); 15799 - setprop(js, result, len_key, tov((double) result_idx)); 16099 + js_setprop(js, result, len_key, tov((double) result_idx)); 15800 16100 return mkval(T_ARR, vdata(result)); 15801 16101 } 15802 16102 ··· 15991 16291 jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 15992 16292 jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 15993 16293 jsval_t key = js_mkstr(js, dst, strlen(dst)); 15994 - setprop(js, arr, key, elem); 16294 + js_setprop(js, arr, key, elem); 15995 16295 } 15996 16296 15997 16297 jsval_t len_key = js_mkstr(js, "length", 6); 15998 - setprop(js, arr, len_key, tov((double)(len - 1))); 16298 + js_setprop(js, arr, len_key, tov((double)(len - 1))); 15999 16299 js->needs_gc = true; 16000 16300 return first; 16001 16301 } ··· 16020 16320 jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 16021 16321 jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 16022 16322 jsval_t key = js_mkstr(js, dst, strlen(dst)); 16023 - setprop(js, arr, key, elem); 16323 + js_setprop(js, arr, key, elem); 16024 16324 } 16025 16325 16026 16326 for (int i = 0; i < nargs; i++) { 16027 16327 char idxstr[16]; 16028 16328 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)i); 16029 16329 jsval_t key = js_mkstr(js, idxstr, idxlen); 16030 - setprop(js, arr, key, args[i]); 16330 + js_setprop(js, arr, key, args[i]); 16031 16331 } 16032 16332 16033 16333 jsval_t len_key = js_mkstr(js, "length", 6); 16034 16334 jsoff_t new_len = len + nargs; 16035 - setprop(js, arr, len_key, tov((double) new_len)); 16335 + js_setprop(js, arr, len_key, tov((double) new_len)); 16036 16336 return tov((double) new_len); 16037 16337 } 16038 16338 ··· 16250 16550 if (elem_off != 0) { 16251 16551 jsval_t elem = resolveprop(js, mkval(T_PROP, elem_off)); 16252 16552 jsval_t key = js_mkstr(js, dst, strlen(dst)); 16253 - setprop(js, removed, key, elem); 16553 + js_setprop(js, removed, key, elem); 16254 16554 } 16255 16555 } 16256 16556 jsval_t rem_len_key = js_mkstr(js, "length", 6); 16257 - setprop(js, removed, rem_len_key, tov((double) deleteCount)); 16557 + js_setprop(js, removed, rem_len_key, tov((double) deleteCount)); 16258 16558 16259 16559 int shift = insertCount - deleteCount; 16260 16560 if (shift > 0) { ··· 16265 16565 jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 16266 16566 jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 16267 16567 jsval_t key = js_mkstr(js, dst, strlen(dst)); 16268 - setprop(js, arr, key, elem); 16568 + js_setprop(js, arr, key, elem); 16269 16569 } 16270 16570 } else if (shift < 0) { 16271 16571 for (int i = start + deleteCount; i < (int)len; i++) { ··· 16275 16575 jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 16276 16576 jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 16277 16577 jsval_t key = js_mkstr(js, dst, strlen(dst)); 16278 - setprop(js, arr, key, elem); 16578 + js_setprop(js, arr, key, elem); 16279 16579 } 16280 16580 } 16281 16581 ··· 16283 16583 char idxstr[16]; 16284 16584 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)(start + i)); 16285 16585 jsval_t key = js_mkstr(js, idxstr, idxlen); 16286 - setprop(js, arr, key, args[2 + i]); 16586 + js_setprop(js, arr, key, args[2 + i]); 16287 16587 } 16288 16588 16289 16589 jsval_t len_key = js_mkstr(js, "length", 6); 16290 - setprop(js, arr, len_key, tov((double)((int)len + shift))); 16590 + js_setprop(js, arr, len_key, tov((double)((int)len + shift))); 16291 16591 if (deleteCount > 0) js->needs_gc = true; 16292 16592 return mkval(T_ARR, vdata(removed)); 16293 16593 } ··· 16338 16638 char idxstr[16]; 16339 16639 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)(target + i)); 16340 16640 jsval_t key = js_mkstr(js, idxstr, idxlen); 16341 - setprop(js, arr, key, temp[i]); 16641 + js_setprop(js, arr, key, temp[i]); 16342 16642 } 16343 16643 16344 16644 free(temp); ··· 16429 16729 elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 16430 16730 } 16431 16731 jsval_t key = js_mkstr(js, idxstr, idxlen); 16432 - setprop(js, result, key, elem); 16732 + js_setprop(js, result, key, elem); 16433 16733 } 16434 16734 16435 16735 jsval_t len_key = js_mkstr(js, "length", 6); 16436 - setprop(js, result, len_key, tov((double) len)); 16736 + js_setprop(js, result, len_key, tov((double) len)); 16437 16737 return mkval(T_ARR, vdata(result)); 16438 16738 } 16439 16739 ··· 16459 16759 char idxstr[16]; 16460 16760 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)i); 16461 16761 jsval_t key = js_mkstr(js, idxstr, idxlen); 16462 - setprop(js, result, key, tov((double) i)); 16762 + js_setprop(js, result, key, tov((double) i)); 16463 16763 } 16464 16764 16465 16765 jsval_t len_key = js_mkstr(js, "length", 6); 16466 - setprop(js, result, len_key, tov((double) len)); 16766 + js_setprop(js, result, len_key, tov((double) len)); 16467 16767 return mkval(T_ARR, vdata(result)); 16468 16768 } 16469 16769 ··· 16491 16791 jsoff_t elem_off = lkp(js, arr, idxstr, idxlen); 16492 16792 jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 16493 16793 jsval_t key = js_mkstr(js, idxstr, idxlen); 16494 - setprop(js, result, key, elem); 16794 + js_setprop(js, result, key, elem); 16495 16795 } 16496 16796 16497 16797 jsval_t len_key = js_mkstr(js, "length", 6); 16498 - setprop(js, result, len_key, tov((double) len)); 16798 + js_setprop(js, result, len_key, tov((double) len)); 16499 16799 return mkval(T_ARR, vdata(result)); 16500 16800 } 16501 16801 ··· 16526 16826 jsoff_t elem_off = lkp(js, arr, idxstr, idxlen); 16527 16827 jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 16528 16828 16529 - setprop(js, entry, js_mkstr(js, "0", 1), tov((double) i)); 16530 - setprop(js, entry, js_mkstr(js, "1", 1), elem); 16531 - setprop(js, entry, js_mkstr(js, "length", 6), tov(2)); 16829 + js_setprop(js, entry, js_mkstr(js, "0", 1), tov((double) i)); 16830 + js_setprop(js, entry, js_mkstr(js, "1", 1), elem); 16831 + js_setprop(js, entry, js_mkstr(js, "length", 6), tov(2)); 16532 16832 16533 16833 jsval_t key = js_mkstr(js, idxstr, idxlen); 16534 - setprop(js, result, key, mkval(T_ARR, vdata(entry))); 16834 + js_setprop(js, result, key, mkval(T_ARR, vdata(entry))); 16535 16835 } 16536 16836 16537 16837 jsval_t len_key = js_mkstr(js, "length", 6); 16538 - setprop(js, result, len_key, tov((double) len)); 16838 + js_setprop(js, result, len_key, tov((double) len)); 16539 16839 return mkval(T_ARR, vdata(result)); 16540 16840 } 16541 16841 16542 16842 static jsval_t builtin_array_toString(struct js *js, jsval_t *args, int nargs) { 16543 - (void) args; 16544 - (void) nargs; 16545 16843 jsval_t arr = js->this_val; 16546 - jsval_t sep_args[1] = { js_mkstr(js, ",", 1) }; 16547 - jsval_t old_this = js->this_val; 16548 - js->this_val = arr; 16549 - jsval_t result = builtin_array_join(js, sep_args, 1); 16550 - js->this_val = old_this; 16551 - return result; 16844 + 16845 + jsval_t join_result; 16846 + if (js_try_call_method(js, arr, "join", 4, NULL, 0, &join_result)) { 16847 + if (is_err(join_result)) return join_result; 16848 + return join_result; 16849 + } 16850 + 16851 + return builtin_object_toString(js, args, nargs); 16552 16852 } 16553 16853 16554 16854 static jsval_t builtin_array_toLocaleString(struct js *js, jsval_t *args, int nargs) { ··· 16639 16939 if (is_err(elem)) return elem; 16640 16940 } 16641 16941 jsval_t key = js_mkstr(js, idxstr, idxlen); 16642 - setprop(js, result, key, elem); 16942 + js_setprop(js, result, key, elem); 16643 16943 } 16644 16944 jsval_t len_key = js_mkstr(js, "length", 6); 16645 - setprop(js, result, len_key, tov((double) str_len)); 16945 + js_setprop(js, result, len_key, tov((double) str_len)); 16646 16946 } else if (vtype(src) == T_ARR || vtype(src) == T_OBJ) { 16647 16947 jsoff_t off = lkp_interned(js, src, INTERN_LENGTH, 6); 16648 16948 jsoff_t len = 0; ··· 16661 16961 if (is_err(elem)) return elem; 16662 16962 } 16663 16963 jsval_t key = js_mkstr(js, idxstr, idxlen); 16664 - setprop(js, result, key, elem); 16964 + js_setprop(js, result, key, elem); 16665 16965 } 16666 16966 jsval_t len_key = js_mkstr(js, "length", 6); 16667 - setprop(js, result, len_key, tov((double) len)); 16967 + js_setprop(js, result, len_key, tov((double) len)); 16668 16968 } 16669 16969 16670 16970 return mkval(T_ARR, vdata(result)); ··· 16678 16978 char idxstr[16]; 16679 16979 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)i); 16680 16980 jsval_t key = js_mkstr(js, idxstr, idxlen); 16681 - setprop(js, arr, key, args[i]); 16981 + js_setprop(js, arr, key, args[i]); 16682 16982 } 16683 16983 jsval_t len_key = js_mkstr(js, "length", 6); 16684 - setprop(js, arr, len_key, tov((double) nargs)); 16984 + js_setprop(js, arr, len_key, tov((double) nargs)); 16685 16985 return mkval(T_ARR, vdata(arr)); 16686 16986 } 16687 16987 ··· 16796 17096 } 16797 17097 } 16798 17098 if (limit == 0) { 16799 - setprop(js, arr, js_mkstr(js, "length", 6), tov(0)); 17099 + js_setprop(js, arr, js_mkstr(js, "length", 6), tov(0)); 16800 17100 return mkval(T_ARR, vdata(arr)); 16801 17101 } 16802 17102 if (nargs == 0) goto return_whole; ··· 16818 17118 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 16819 17119 jsval_t key = js_mkstr(js, idxstr, idxlen); 16820 17120 jsval_t part = js_mkstr(js, str_ptr + i, 1); 16821 - setprop(js, arr, key, part); 17121 + js_setprop(js, arr, key, part); 16822 17122 idx++; 16823 17123 } 16824 17124 jsval_t len_key = js_mkstr(js, "length", 6); 16825 - setprop(js, arr, len_key, tov((double)idx)); 17125 + js_setprop(js, arr, len_key, tov((double)idx)); 16826 17126 return mkval(T_ARR, vdata(arr)); 16827 17127 } 16828 17128 ··· 16844 17144 if (rc >= 0) { 16845 17145 pcre2_match_data_free(match_data); 16846 17146 pcre2_code_free(re); 16847 - setprop(js, arr, js_mkstr(js, "length", 6), tov(0)); 17147 + js_setprop(js, arr, js_mkstr(js, "length", 6), tov(0)); 16848 17148 return mkval(T_ARR, vdata(arr)); 16849 17149 } 16850 17150 } ··· 16890 17190 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 16891 17191 jsval_t key = js_mkstr(js, idxstr, idxlen); 16892 17192 jsval_t part = js_mkstr(js, str_ptr + segment_start, match_start - segment_start); 16893 - setprop(js, arr, key, part); 17193 + js_setprop(js, arr, key, part); 16894 17194 idx++; 16895 17195 16896 17196 for (uint32_t i = 1; i <= capture_count && idx < limit; i++) { ··· 16899 17199 size_t cap_idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 16900 17200 key = js_mkstr(js, idxstr, cap_idxlen); 16901 17201 if (cap_start == PCRE2_UNSET) { 16902 - setprop(js, arr, key, js_mkundef()); 17202 + js_setprop(js, arr, key, js_mkundef()); 16903 17203 } else { 16904 17204 part = js_mkstr(js, str_ptr + cap_start, cap_end - cap_start); 16905 - setprop(js, arr, key, part); 17205 + js_setprop(js, arr, key, part); 16906 17206 } 16907 17207 idx++; 16908 17208 } ··· 16919 17219 if (!had_any_split) { 16920 17220 pcre2_match_data_free(match_data); 16921 17221 pcre2_code_free(re); 16922 - setprop(js, arr, js_mkstr(js, "0", 1), js_mkstr(js, str_ptr, str_len)); 16923 - setprop(js, arr, js_mkstr(js, "length", 6), tov(1)); 17222 + js_setprop(js, arr, js_mkstr(js, "0", 1), js_mkstr(js, str_ptr, str_len)); 17223 + js_setprop(js, arr, js_mkstr(js, "length", 6), tov(1)); 16924 17224 return mkval(T_ARR, vdata(arr)); 16925 17225 } 16926 17226 ··· 16929 17229 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 16930 17230 jsval_t key = js_mkstr(js, idxstr, idxlen); 16931 17231 jsval_t part = js_mkstr(js, str_ptr + segment_start, str_len - segment_start); 16932 - setprop(js, arr, key, part); 17232 + js_setprop(js, arr, key, part); 16933 17233 idx++; 16934 17234 } 16935 17235 16936 17236 pcre2_match_data_free(match_data); 16937 17237 pcre2_code_free(re); 16938 17238 jsval_t len_key = js_mkstr(js, "length", 6); 16939 - setprop(js, arr, len_key, tov((double)idx)); 17239 + js_setprop(js, arr, len_key, tov((double)idx)); 16940 17240 return mkval(T_ARR, vdata(arr)); 16941 17241 } 16942 17242 ··· 16952 17252 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 16953 17253 jsval_t key = js_mkstr(js, idxstr, idxlen); 16954 17254 jsval_t part = js_mkstr(js, str_ptr + i, 1); 16955 - setprop(js, arr, key, part); 17255 + js_setprop(js, arr, key, part); 16956 17256 idx++; 16957 17257 } 16958 17258 goto set_length; ··· 16964 17264 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 16965 17265 jsval_t key = js_mkstr(js, idxstr, idxlen); 16966 17266 jsval_t part = js_mkstr(js, str_ptr + start, i - start); 16967 - setprop(js, arr, key, part); 17267 + js_setprop(js, arr, key, part); 16968 17268 idx++; 16969 17269 start = i + sep_len; 16970 17270 i += sep_len - 1; ··· 16974 17274 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 16975 17275 jsval_t key = js_mkstr(js, idxstr, idxlen); 16976 17276 jsval_t part = js_mkstr(js, str_ptr + start, str_len - start); 16977 - setprop(js, arr, key, part); 17277 + js_setprop(js, arr, key, part); 16978 17278 idx++; 16979 17279 } 16980 17280 16981 17281 set_length:; 16982 17282 jsval_t len_key = js_mkstr(js, "length", 6); 16983 - setprop(js, arr, len_key, tov((double) idx)); 17283 + js_setprop(js, arr, len_key, tov((double) idx)); 16984 17284 return mkval(T_ARR, vdata(arr)); 16985 17285 16986 17286 return_whole: 16987 17287 if (limit > 0) { 16988 - setprop(js, arr, js_mkstr(js, "0", 1), str); 16989 - setprop(js, arr, js_mkstr(js, "length", 6), tov(1)); 17288 + js_setprop(js, arr, js_mkstr(js, "0", 1), str); 17289 + js_setprop(js, arr, js_mkstr(js, "length", 6), tov(1)); 16990 17290 } else { 16991 - setprop(js, arr, js_mkstr(js, "length", 6), tov(0)); 17291 + js_setprop(js, arr, js_mkstr(js, "length", 6), tov(0)); 16992 17292 } 16993 17293 return mkval(T_ARR, vdata(arr)); 16994 17294 } ··· 17564 17864 js_arr_push(js, result_arr, match_str); 17565 17865 } 17566 17866 } 17567 - setprop(js, result_arr, js_mkstr(js, "index", 5), tov((double)match_start)); 17867 + js_setprop(js, result_arr, js_mkstr(js, "index", 5), tov((double)match_start)); 17568 17868 } 17569 17869 match_count++; 17570 17870 ··· 17633 17933 jsval_t result = do_regex_match_pcre2(js, pattern_ptr, pattern_len, str_ptr, str_len, global_flag, ignore_case, multiline); 17634 17934 17635 17935 if (!global_flag && vtype(result) == T_ARR) { 17636 - setprop(js, result, js_mkstr(js, "input", 5), str); 17936 + js_setprop(js, result, js_mkstr(js, "input", 5), str); 17637 17937 } 17638 17938 17639 17939 return result; ··· 19109 19409 jsval_t results = js_get(js, tracker, "results"); 19110 19410 char idx[16]; 19111 19411 snprintf(idx, sizeof(idx), "%d", index); 19112 - setprop(js, results, js_mkstr(js, idx, strlen(idx)), value); 19412 + js_setprop(js, results, js_mkstr(js, idx, strlen(idx)), value); 19113 19413 19114 19414 jsval_t remaining_val = js_get(js, tracker, "remaining"); 19115 19415 int remaining = (int)tod(remaining_val) - 1; 19116 - setprop(js, tracker, js_mkstr(js, "remaining", 9), tov((double)remaining)); 19416 + js_setprop(js, tracker, js_mkstr(js, "remaining", 9), tov((double)remaining)); 19117 19417 19118 19418 if (remaining == 0) { 19119 19419 jsval_t result_promise = get_slot(js, tracker, SLOT_DATA); ··· 19147 19447 19148 19448 if (len == 0) { 19149 19449 jsval_t empty_arr = mkarr(js); 19150 - setprop(js, empty_arr, js_mkstr(js, "length", 6), tov(0.0)); 19450 + js_setprop(js, empty_arr, js_mkstr(js, "length", 6), tov(0.0)); 19151 19451 jsval_t resolve_args[] = { mkval(T_ARR, vdata(empty_arr)) }; 19152 19452 return builtin_Promise_resolve(js, resolve_args, 1); 19153 19453 } ··· 19155 19455 jsval_t result_promise = mkpromise(js); 19156 19456 jsval_t tracker = mkobj(js, 0); 19157 19457 19158 - setprop(js, tracker, js_mkstr(js, "remaining", 9), tov((double)len)); 19159 - setprop(js, tracker, js_mkstr(js, "results", 7), mkarr(js)); 19458 + js_setprop(js, tracker, js_mkstr(js, "remaining", 9), tov((double)len)); 19459 + js_setprop(js, tracker, js_mkstr(js, "results", 7), mkarr(js)); 19160 19460 set_slot(js, tracker, SLOT_DATA, result_promise); 19161 19461 19162 19462 jsval_t results = resolveprop(js, js_get(js, tracker, "results")); 19163 - setprop(js, results, js_mkstr(js, "length", 6), tov((double)len)); 19463 + js_setprop(js, results, js_mkstr(js, "length", 6), tov((double)len)); 19164 19464 19165 19465 for (int i = 0; i < len; i++) { 19166 19466 char idx[16]; ··· 19174 19474 19175 19475 jsval_t resolve_obj = mkobj(js, 0); 19176 19476 set_slot(js, resolve_obj, SLOT_CFUNC, js_mkfun(builtin_Promise_all_resolve_handler)); 19177 - setprop(js, resolve_obj, js_mkstr(js, "index", 5), tov((double)i)); 19178 - setprop(js, resolve_obj, js_mkstr(js, "tracker", 7), tracker); 19477 + js_setprop(js, resolve_obj, js_mkstr(js, "index", 5), tov((double)i)); 19478 + js_setprop(js, resolve_obj, js_mkstr(js, "tracker", 7), tracker); 19179 19479 jsval_t resolve_fn = mkval(T_FUNC, vdata(resolve_obj)); 19180 19480 19181 19481 jsval_t reject_obj = mkobj(js, 0); 19182 19482 set_slot(js, reject_obj, SLOT_CFUNC, js_mkfun(builtin_Promise_all_reject_handler)); 19183 - setprop(js, reject_obj, js_mkstr(js, "tracker", 7), tracker); 19483 + js_setprop(js, reject_obj, js_mkstr(js, "tracker", 7), tracker); 19184 19484 jsval_t reject_fn = mkval(T_FUNC, vdata(reject_obj)); 19185 19485 19186 19486 jsval_t then_args[] = { resolve_fn, reject_fn }; ··· 19267 19567 jsval_t errors = resolveprop(js, js_get(js, tracker, "errors")); 19268 19568 char idx[16]; 19269 19569 snprintf(idx, sizeof(idx), "%d", index); 19270 - setprop(js, errors, js_mkstr(js, idx, strlen(idx)), reason); 19570 + js_setprop(js, errors, js_mkstr(js, idx, strlen(idx)), reason); 19271 19571 19272 19572 int remaining = (int)tod(js_get(js, tracker, "remaining")) - 1; 19273 19573 js_set(js, tracker, "remaining", tov((double)remaining)); ··· 19310 19610 19311 19611 set_slot(js, tracker, SLOT_DATA, result_promise); 19312 19612 19313 - setprop(js, tracker, js_mkstr(js, "remaining", 9), tov((double)len)); 19314 - setprop(js, tracker, js_mkstr(js, "errors", 6), errors); 19315 - setprop(js, tracker, js_mkstr(js, "resolved", 8), js_false); 19316 - setprop(js, errors, js_mkstr(js, "length", 6), tov((double)len)); 19613 + js_setprop(js, tracker, js_mkstr(js, "remaining", 9), tov((double)len)); 19614 + js_setprop(js, tracker, js_mkstr(js, "errors", 6), errors); 19615 + js_setprop(js, tracker, js_mkstr(js, "resolved", 8), js_false); 19616 + js_setprop(js, errors, js_mkstr(js, "length", 6), tov((double)len)); 19317 19617 19318 19618 for (int i = 0; i < len; i++) { 19319 19619 char idx[16]; ··· 19344 19644 19345 19645 jsval_t resolve_obj = mkobj(js, 0); 19346 19646 set_slot(js, resolve_obj, SLOT_CFUNC, js_mkfun(builtin_Promise_any_resolve_handler)); 19347 - setprop(js, resolve_obj, js_mkstr(js, "tracker", 7), tracker); 19647 + js_setprop(js, resolve_obj, js_mkstr(js, "tracker", 7), tracker); 19348 19648 19349 19649 jsval_t reject_obj = mkobj(js, 0); 19350 19650 set_slot(js, reject_obj, SLOT_CFUNC, js_mkfun(builtin_Promise_any_reject_handler)); 19351 - setprop(js, reject_obj, js_mkstr(js, "index", 5), tov((double)i)); 19352 - setprop(js, reject_obj, js_mkstr(js, "tracker", 7), tracker); 19651 + js_setprop(js, reject_obj, js_mkstr(js, "index", 5), tov((double)i)); 19652 + js_setprop(js, reject_obj, js_mkstr(js, "tracker", 7), tracker); 19353 19653 19354 19654 jsval_t then_args[] = { mkval(T_FUNC, vdata(resolve_obj)), mkval(T_FUNC, vdata(reject_obj)) }; 19355 19655 jsval_t saved_this = js->this_val; ··· 19708 20008 for (size_t i = 0; i < size; i++) { 19709 20009 char idx[16]; 19710 20010 snprintf(idx, sizeof(idx), "%zu", i); 19711 - setprop(js, data_arr, js_mkstr(js, idx, strlen(idx)), tov((double)content[i])); 20011 + js_setprop(js, data_arr, js_mkstr(js, idx, strlen(idx)), tov((double)content[i])); 19712 20012 } 19713 - setprop(js, data_arr, js_mkstr(js, "length", 6), tov((double)size)); 20013 + js_setprop(js, data_arr, js_mkstr(js, "length", 6), tov((double)size)); 19714 20014 19715 - setprop(js, obj, js_mkstr(js, "data", 4), mkval(T_ARR, vdata(data_arr))); 19716 - setprop(js, obj, js_mkstr(js, "path", 4), js_mkstr(js, path, strlen(path))); 19717 - setprop(js, obj, js_mkstr(js, "size", 4), tov((double)size)); 20015 + js_setprop(js, obj, js_mkstr(js, "data", 4), mkval(T_ARR, vdata(data_arr))); 20016 + js_setprop(js, obj, js_mkstr(js, "path", 4), js_mkstr(js, path, strlen(path))); 20017 + js_setprop(js, obj, js_mkstr(js, "size", 4), tov((double)size)); 19718 20018 19719 20019 free(file.data); 19720 20020 return obj; ··· 19979 20279 bool is_url = esm_is_url(filename); 19980 20280 19981 20281 jsval_t url_val = is_url ? js_mkstr(js, filename, strlen(filename)) : esm_make_file_url(js, filename); 19982 - if (!is_err(url_val)) setprop(js, import_meta, js_mkstr(js, "url", 3), url_val); 20282 + if (!is_err(url_val)) js_setprop(js, import_meta, js_mkstr(js, "url", 3), url_val); 19983 20283 19984 20284 jsval_t filename_val = js_mkstr(js, filename, strlen(filename)); 19985 - if (!is_err(filename_val)) setprop(js, import_meta, js_mkstr(js, "filename", 8), filename_val); 20285 + if (!is_err(filename_val)) js_setprop(js, import_meta, js_mkstr(js, "filename", 8), filename_val); 19986 20286 19987 20287 if (is_url) { 19988 20288 char *filename_copy = strdup(filename); ··· 19992 20292 if (last_slash && scheme_end && last_slash > scheme_end + 2) { 19993 20293 *last_slash = '\0'; 19994 20294 jsval_t dirname_val = js_mkstr(js, filename_copy, strlen(filename_copy)); 19995 - if (!is_err(dirname_val)) setprop(js, import_meta, js_mkstr(js, "dirname", 7), dirname_val); 20295 + if (!is_err(dirname_val)) js_setprop(js, import_meta, js_mkstr(js, "dirname", 7), dirname_val); 19996 20296 } 19997 20297 free(filename_copy); 19998 20298 } ··· 20002 20302 char *dir = dirname(filename_copy); 20003 20303 if (dir) { 20004 20304 jsval_t dirname_val = js_mkstr(js, dir, strlen(dir)); 20005 - if (!is_err(dirname_val)) setprop(js, import_meta, js_mkstr(js, "dirname", 7), dirname_val); 20305 + if (!is_err(dirname_val)) js_setprop(js, import_meta, js_mkstr(js, "dirname", 7), dirname_val); 20006 20306 } 20007 20307 free(filename_copy); 20008 20308 } 20009 20309 } 20010 20310 20011 - setprop(js, import_meta, js_mkstr(js, "main", 4), js_true); 20311 + js_setprop(js, import_meta, js_mkstr(js, "main", 4), js_true); 20012 20312 jsval_t resolve_fn = js_mkfun(builtin_import_meta_resolve); 20013 - setprop(js, import_meta, js_mkstr(js, "resolve", 7), resolve_fn); 20313 + js_setprop(js, import_meta, js_mkstr(js, "resolve", 7), resolve_fn); 20014 20314 20015 20315 jsval_t glob = js_glob(js); 20016 20316 jsoff_t import_off = lkp(js, glob, "import", 6); ··· 20019 20319 jsval_t import_fn = resolveprop(js, mkval(T_PROP, import_off)); 20020 20320 if (vtype(import_fn) == T_FUNC) { 20021 20321 jsval_t import_obj = mkval(T_OBJ, vdata(import_fn)); 20022 - setprop(js, import_obj, js_mkstr(js, "meta", 4), import_meta); 20322 + js_setprop(js, import_obj, js_mkstr(js, "meta", 4), import_meta); 20023 20323 } 20024 20324 } 20025 20325 } ··· 20069 20369 return js_mkerr_typed(js, JS_ERR_SYNTAX, "Cannot re-export from non-object module"); 20070 20370 } 20071 20371 20072 - setprop(js, js->scope, js_mkstr(js, namespace_name, namespace_len), ns); 20372 + js_setprop(js, js->scope, js_mkstr(js, namespace_name, namespace_len), ns); 20073 20373 return js_mkundef(); 20074 20374 } 20075 20375 ··· 20124 20424 jsval_t slot_val = js_get_slot(js, ns, SLOT_DEFAULT); 20125 20425 default_val = vtype(slot_val) != T_UNDEF ? slot_val : ns; 20126 20426 } else default_val = ns; 20127 - setprop(js, js->scope, js_mkstr(js, default_name, default_len), default_val); 20427 + js_setprop(js, js->scope, js_mkstr(js, default_name, default_len), default_val); 20128 20428 20129 20429 for (int i = 0; i < binding_count; i++) { 20130 20430 if (bindings[i].import_name == NULL) { 20131 - setprop(js, js->scope, js_mkstr(js, bindings[i].local_name, bindings[i].local_len), ns); 20431 + js_setprop(js, js->scope, js_mkstr(js, bindings[i].local_name, bindings[i].local_len), ns); 20132 20432 } else if (vtype(ns) == T_OBJ) { 20133 20433 jsoff_t prop_off = lkp(js, ns, bindings[i].import_name, bindings[i].import_len); 20134 20434 if (prop_off == 0) return js_mkerr_typed( ··· 20136 20436 (int)bindings[i].import_len, bindings[i].import_name 20137 20437 ); 20138 20438 jsval_t imported_val = resolveprop(js, mkval(T_PROP, prop_off)); 20139 - setprop(js, js->scope, js_mkstr(js, bindings[i].local_name, bindings[i].local_len), imported_val); 20439 + js_setprop(js, js->scope, js_mkstr(js, bindings[i].local_name, bindings[i].local_len), imported_val); 20140 20440 } else return js_mkerr_typed(js, JS_ERR_SYNTAX, "Cannot use named imports from non-object module"); 20141 20441 } 20142 20442 ··· 20184 20484 (int)bindings[i].import_len, bindings[i].import_name 20185 20485 ); 20186 20486 jsval_t imported_val = resolveprop(js, mkval(T_PROP, prop_off)); 20187 - setprop(js, js->scope, js_mkstr(js, bindings[i].local_name, bindings[i].local_len), imported_val); 20487 + js_setprop(js, js->scope, js_mkstr(js, bindings[i].local_name, bindings[i].local_len), imported_val); 20188 20488 } 20189 20489 20190 20490 return js_mkundef(); ··· 20249 20549 20250 20550 jsval_t key = js_mkstr(js, name, name_len); 20251 20551 mkprop(js, js->scope, key, resolveprop(js, value), is_const ? CONSTMASK : 0); 20252 - setprop(js, js->module_ns, key, resolveprop(js, value)); 20552 + js_setprop(js, js->module_ns, key, resolveprop(js, value)); 20253 20553 20254 20554 return value; 20255 20555 } ··· 20263 20563 if (name_off != 0) { 20264 20564 jsval_t name_val = resolveprop(js, mkval(T_PROP, name_off)); 20265 20565 if (vtype(name_val) == T_STR) { 20266 - setprop(js, js->scope, name_val, func); 20267 - setprop(js, js->module_ns, name_val, func); 20566 + js_setprop(js, js->scope, name_val, func); 20567 + js_setprop(js, js->module_ns, name_val, func); 20268 20568 } 20269 20569 } 20270 20570 ··· 20280 20580 if (name_off != 0) { 20281 20581 jsval_t name_val = resolveprop(js, mkval(T_PROP, name_off)); 20282 20582 if (vtype(name_val) == T_STR) { 20283 - setprop(js, js->scope, name_val, cls); 20284 - setprop(js, js->module_ns, name_val, cls); 20583 + js_setprop(js, js->scope, name_val, cls); 20584 + js_setprop(js, js->module_ns, name_val, cls); 20285 20585 } 20286 20586 } 20287 20587 ··· 20319 20619 if (is_err(ns)) return ns; 20320 20620 20321 20621 if (alias_name) { 20322 - setprop(js, js->module_ns, js_mkstr(js, alias_name, alias_len), ns); 20622 + js_setprop(js, js->module_ns, js_mkstr(js, alias_name, alias_len), ns); 20323 20623 } else if (vtype(ns) == T_OBJ) { 20324 20624 ant_iter_t iter = js_prop_iter_begin(js, ns); 20325 20625 const char *key; size_t key_len; jsval_t value; 20326 20626 20327 20627 while (js_prop_iter_next(&iter, &key, &key_len, &value)) { 20328 - setprop(js, js->module_ns, js_mkstr(js, key, key_len), resolveprop(js, value)); 20628 + js_setprop(js, js->module_ns, js_mkstr(js, key, key_len), resolveprop(js, value)); 20329 20629 } 20330 20630 js_prop_iter_end(&iter); 20331 20631 } ··· 20420 20720 20421 20721 static jsval_t throw_proxy_error(struct js *js, const char *message) { 20422 20722 jsval_t err_obj = mkobj(js, 0); 20423 - setprop(js, err_obj, js_mkstr(js, "message", 7), js_mkstr(js, message, strlen(message))); 20424 - setprop(js, err_obj, js_mkstr(js, "name", 4), js_mkstr(js, "TypeError", 9)); 20723 + js_setprop(js, err_obj, js_mkstr(js, "message", 7), js_mkstr(js, message, strlen(message))); 20724 + js_setprop(js, err_obj, js_mkstr(js, "name", 4), js_mkstr(js, "TypeError", 9)); 20425 20725 return js_throw(js, err_obj); 20426 20726 } 20427 20727 ··· 20478 20778 } 20479 20779 20480 20780 jsval_t key_str = js_mkstr(js, key, key_len); 20481 - setprop(js, target, key_str, value); 20781 + js_setprop(js, target, key_str, value); 20482 20782 return js_true; 20483 20783 } 20484 20784 ··· 20528 20828 } 20529 20829 20530 20830 jsval_t key_str = js_mkstr(js, key, key_len); 20531 - setprop(js, target, key_str, js_mkundef()); 20831 + js_setprop(js, target, key_str, js_mkundef()); 20532 20832 return js_true; 20533 20833 } 20534 20834 ··· 20592 20892 jsval_t revoke_func = mkval(T_FUNC, vdata(revoke_obj)); 20593 20893 20594 20894 jsval_t result = mkobj(js, 0); 20595 - setprop(js, result, js_mkstr(js, "proxy", 5), proxy); 20596 - setprop(js, result, js_mkstr(js, "revoke", 6), revoke_func); 20895 + js_setprop(js, result, js_mkstr(js, "proxy", 5), proxy); 20896 + js_setprop(js, result, js_mkstr(js, "revoke", 6), revoke_func); 20597 20897 20598 20898 return result; 20599 20899 } ··· 20639 20939 jsval_t object_proto = js_mkobj(js); 20640 20940 set_proto(js, object_proto, js_mknull()); 20641 20941 20642 - setprop(js, object_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_object_toString)); 20942 + js_setprop(js, object_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_object_toString)); 20643 20943 js_set_descriptor(js, object_proto, "toString", 8, JS_DESC_W | JS_DESC_C); 20644 20944 20645 - setprop(js, object_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_object_valueOf)); 20945 + js_setprop(js, object_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_object_valueOf)); 20646 20946 js_set_descriptor(js, object_proto, "valueOf", 7, JS_DESC_W | JS_DESC_C); 20647 20947 20648 - setprop(js, object_proto, js_mkstr(js, "toLocaleString", 14), js_mkfun(builtin_object_toLocaleString)); 20948 + js_setprop(js, object_proto, js_mkstr(js, "toLocaleString", 14), js_mkfun(builtin_object_toLocaleString)); 20649 20949 js_set_descriptor(js, object_proto, "toLocaleString", 14, JS_DESC_W | JS_DESC_C); 20650 20950 20651 - setprop(js, object_proto, js_mkstr(js, "hasOwnProperty", 14), js_mkfun(builtin_object_hasOwnProperty)); 20951 + js_setprop(js, object_proto, js_mkstr(js, "hasOwnProperty", 14), js_mkfun(builtin_object_hasOwnProperty)); 20652 20952 js_set_descriptor(js, object_proto, "hasOwnProperty", 14, JS_DESC_W | JS_DESC_C); 20653 20953 20654 - setprop(js, object_proto, js_mkstr(js, "isPrototypeOf", 13), js_mkfun(builtin_object_isPrototypeOf)); 20954 + js_setprop(js, object_proto, js_mkstr(js, "isPrototypeOf", 13), js_mkfun(builtin_object_isPrototypeOf)); 20655 20955 js_set_descriptor(js, object_proto, "isPrototypeOf", 13, JS_DESC_W | JS_DESC_C); 20656 20956 20657 - setprop(js, object_proto, js_mkstr(js, "propertyIsEnumerable", 20), js_mkfun(builtin_object_propertyIsEnumerable)); 20957 + js_setprop(js, object_proto, js_mkstr(js, "propertyIsEnumerable", 20), js_mkfun(builtin_object_propertyIsEnumerable)); 20658 20958 js_set_descriptor(js, object_proto, "propertyIsEnumerable", 20, JS_DESC_W | JS_DESC_C); 20659 20959 20660 20960 jsval_t proto_getter = js_mkfun(builtin_proto_getter); 20661 20961 jsval_t proto_setter = js_mkfun(builtin_proto_setter); 20662 - setprop(js, object_proto, js_mkstr(js, STR_PROTO, STR_PROTO_LEN), js_mkundef()); 20962 + js_setprop(js, object_proto, js_mkstr(js, STR_PROTO, STR_PROTO_LEN), js_mkundef()); 20663 20963 js_set_accessor_desc(js, object_proto, STR_PROTO, STR_PROTO_LEN, proto_getter, proto_setter, JS_DESC_C); 20664 20964 20665 20965 jsval_t function_proto_obj = js_mkobj(js); 20666 20966 set_proto(js, function_proto_obj, object_proto); 20667 20967 set_slot(js, function_proto_obj, SLOT_CFUNC, js_mkfun(builtin_function_empty)); 20668 - setprop(js, function_proto_obj, ANT_STRING("call"), js_mkfun(builtin_function_call)); 20669 - setprop(js, function_proto_obj, ANT_STRING("apply"), js_mkfun(builtin_function_apply)); 20670 - setprop(js, function_proto_obj, ANT_STRING("bind"), js_mkfun(builtin_function_bind)); 20671 - setprop(js, function_proto_obj, ANT_STRING("toString"), js_mkfun(builtin_function_toString)); 20968 + js_setprop(js, function_proto_obj, ANT_STRING("call"), js_mkfun(builtin_function_call)); 20969 + js_setprop(js, function_proto_obj, ANT_STRING("apply"), js_mkfun(builtin_function_apply)); 20970 + js_setprop(js, function_proto_obj, ANT_STRING("bind"), js_mkfun(builtin_function_bind)); 20971 + js_setprop(js, function_proto_obj, ANT_STRING("toString"), js_mkfun(builtin_function_toString)); 20672 20972 jsval_t function_proto = mkval(T_FUNC, vdata(function_proto_obj)); 20673 20973 set_slot(js, glob, SLOT_FUNC_PROTO, function_proto); 20674 20974 20675 20975 jsval_t array_proto = js_mkobj(js); 20676 20976 set_proto(js, array_proto, object_proto); 20677 - setprop(js, array_proto, js_mkstr(js, "push", 4), js_mkfun(builtin_array_push)); 20678 - setprop(js, array_proto, js_mkstr(js, "pop", 3), js_mkfun(builtin_array_pop)); 20679 - setprop(js, array_proto, js_mkstr(js, "slice", 5), js_mkfun(builtin_array_slice)); 20680 - setprop(js, array_proto, js_mkstr(js, "join", 4), js_mkfun(builtin_array_join)); 20681 - setprop(js, array_proto, js_mkstr(js, "includes", 8), js_mkfun(builtin_array_includes)); 20682 - setprop(js, array_proto, js_mkstr(js, "every", 5), js_mkfun(builtin_array_every)); 20683 - setprop(js, array_proto, js_mkstr(js, "reverse", 7), js_mkfun(builtin_array_reverse)); 20684 - setprop(js, array_proto, js_mkstr(js, "map", 3), js_mkfun(builtin_array_map)); 20685 - setprop(js, array_proto, js_mkstr(js, "filter", 6), js_mkfun(builtin_array_filter)); 20686 - setprop(js, array_proto, js_mkstr(js, "reduce", 6), js_mkfun(builtin_array_reduce)); 20687 - setprop(js, array_proto, js_mkstr(js, "flat", 4), js_mkfun(builtin_array_flat)); 20688 - setprop(js, array_proto, js_mkstr(js, "concat", 6), js_mkfun(builtin_array_concat)); 20689 - setprop(js, array_proto, js_mkstr(js, "at", 2), js_mkfun(builtin_array_at)); 20690 - setprop(js, array_proto, js_mkstr(js, "fill", 4), js_mkfun(builtin_array_fill)); 20691 - setprop(js, array_proto, js_mkstr(js, "find", 4), js_mkfun(builtin_array_find)); 20692 - setprop(js, array_proto, js_mkstr(js, "findIndex", 9), js_mkfun(builtin_array_findIndex)); 20693 - setprop(js, array_proto, js_mkstr(js, "findLast", 8), js_mkfun(builtin_array_findLast)); 20694 - setprop(js, array_proto, js_mkstr(js, "findLastIndex", 13), js_mkfun(builtin_array_findLastIndex)); 20695 - setprop(js, array_proto, js_mkstr(js, "flatMap", 7), js_mkfun(builtin_array_flatMap)); 20696 - setprop(js, array_proto, js_mkstr(js, "forEach", 7), js_mkfun(builtin_array_forEach)); 20697 - setprop(js, array_proto, js_mkstr(js, "indexOf", 7), js_mkfun(builtin_array_indexOf)); 20698 - setprop(js, array_proto, js_mkstr(js, "lastIndexOf", 11), js_mkfun(builtin_array_lastIndexOf)); 20699 - setprop(js, array_proto, js_mkstr(js, "reduceRight", 11), js_mkfun(builtin_array_reduceRight)); 20700 - setprop(js, array_proto, js_mkstr(js, "shift", 5), js_mkfun(builtin_array_shift)); 20701 - setprop(js, array_proto, js_mkstr(js, "unshift", 7), js_mkfun(builtin_array_unshift)); 20702 - setprop(js, array_proto, js_mkstr(js, "some", 4), js_mkfun(builtin_array_some)); 20703 - setprop(js, array_proto, js_mkstr(js, "sort", 4), js_mkfun(builtin_array_sort)); 20704 - setprop(js, array_proto, js_mkstr(js, "splice", 6), js_mkfun(builtin_array_splice)); 20705 - setprop(js, array_proto, js_mkstr(js, "copyWithin", 10), js_mkfun(builtin_array_copyWithin)); 20706 - setprop(js, array_proto, js_mkstr(js, "toReversed", 10), js_mkfun(builtin_array_toReversed)); 20707 - setprop(js, array_proto, js_mkstr(js, "toSorted", 8), js_mkfun(builtin_array_toSorted)); 20708 - setprop(js, array_proto, js_mkstr(js, "toSpliced", 9), js_mkfun(builtin_array_toSpliced)); 20709 - setprop(js, array_proto, js_mkstr(js, "with", 4), js_mkfun(builtin_array_with)); 20710 - setprop(js, array_proto, js_mkstr(js, "keys", 4), js_mkfun(builtin_array_keys)); 20711 - setprop(js, array_proto, js_mkstr(js, "values", 6), js_mkfun(builtin_array_values)); 20712 - setprop(js, array_proto, js_mkstr(js, "entries", 7), js_mkfun(builtin_array_entries)); 20713 - setprop(js, array_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_array_toString)); 20714 - setprop(js, array_proto, js_mkstr(js, "toLocaleString", 14), js_mkfun(builtin_array_toLocaleString)); 20977 + js_setprop(js, array_proto, js_mkstr(js, "push", 4), js_mkfun(builtin_array_push)); 20978 + js_setprop(js, array_proto, js_mkstr(js, "pop", 3), js_mkfun(builtin_array_pop)); 20979 + js_setprop(js, array_proto, js_mkstr(js, "slice", 5), js_mkfun(builtin_array_slice)); 20980 + js_setprop(js, array_proto, js_mkstr(js, "join", 4), js_mkfun(builtin_array_join)); 20981 + js_setprop(js, array_proto, js_mkstr(js, "includes", 8), js_mkfun(builtin_array_includes)); 20982 + js_setprop(js, array_proto, js_mkstr(js, "every", 5), js_mkfun(builtin_array_every)); 20983 + js_setprop(js, array_proto, js_mkstr(js, "reverse", 7), js_mkfun(builtin_array_reverse)); 20984 + js_setprop(js, array_proto, js_mkstr(js, "map", 3), js_mkfun(builtin_array_map)); 20985 + js_setprop(js, array_proto, js_mkstr(js, "filter", 6), js_mkfun(builtin_array_filter)); 20986 + js_setprop(js, array_proto, js_mkstr(js, "reduce", 6), js_mkfun(builtin_array_reduce)); 20987 + js_setprop(js, array_proto, js_mkstr(js, "flat", 4), js_mkfun(builtin_array_flat)); 20988 + js_setprop(js, array_proto, js_mkstr(js, "concat", 6), js_mkfun(builtin_array_concat)); 20989 + js_setprop(js, array_proto, js_mkstr(js, "at", 2), js_mkfun(builtin_array_at)); 20990 + js_setprop(js, array_proto, js_mkstr(js, "fill", 4), js_mkfun(builtin_array_fill)); 20991 + js_setprop(js, array_proto, js_mkstr(js, "find", 4), js_mkfun(builtin_array_find)); 20992 + js_setprop(js, array_proto, js_mkstr(js, "findIndex", 9), js_mkfun(builtin_array_findIndex)); 20993 + js_setprop(js, array_proto, js_mkstr(js, "findLast", 8), js_mkfun(builtin_array_findLast)); 20994 + js_setprop(js, array_proto, js_mkstr(js, "findLastIndex", 13), js_mkfun(builtin_array_findLastIndex)); 20995 + js_setprop(js, array_proto, js_mkstr(js, "flatMap", 7), js_mkfun(builtin_array_flatMap)); 20996 + js_setprop(js, array_proto, js_mkstr(js, "forEach", 7), js_mkfun(builtin_array_forEach)); 20997 + js_setprop(js, array_proto, js_mkstr(js, "indexOf", 7), js_mkfun(builtin_array_indexOf)); 20998 + js_setprop(js, array_proto, js_mkstr(js, "lastIndexOf", 11), js_mkfun(builtin_array_lastIndexOf)); 20999 + js_setprop(js, array_proto, js_mkstr(js, "reduceRight", 11), js_mkfun(builtin_array_reduceRight)); 21000 + js_setprop(js, array_proto, js_mkstr(js, "shift", 5), js_mkfun(builtin_array_shift)); 21001 + js_setprop(js, array_proto, js_mkstr(js, "unshift", 7), js_mkfun(builtin_array_unshift)); 21002 + js_setprop(js, array_proto, js_mkstr(js, "some", 4), js_mkfun(builtin_array_some)); 21003 + js_setprop(js, array_proto, js_mkstr(js, "sort", 4), js_mkfun(builtin_array_sort)); 21004 + js_setprop(js, array_proto, js_mkstr(js, "splice", 6), js_mkfun(builtin_array_splice)); 21005 + js_setprop(js, array_proto, js_mkstr(js, "copyWithin", 10), js_mkfun(builtin_array_copyWithin)); 21006 + js_setprop(js, array_proto, js_mkstr(js, "toReversed", 10), js_mkfun(builtin_array_toReversed)); 21007 + js_setprop(js, array_proto, js_mkstr(js, "toSorted", 8), js_mkfun(builtin_array_toSorted)); 21008 + js_setprop(js, array_proto, js_mkstr(js, "toSpliced", 9), js_mkfun(builtin_array_toSpliced)); 21009 + js_setprop(js, array_proto, js_mkstr(js, "with", 4), js_mkfun(builtin_array_with)); 21010 + js_setprop(js, array_proto, js_mkstr(js, "keys", 4), js_mkfun(builtin_array_keys)); 21011 + js_setprop(js, array_proto, js_mkstr(js, "values", 6), js_mkfun(builtin_array_values)); 21012 + js_setprop(js, array_proto, js_mkstr(js, "entries", 7), js_mkfun(builtin_array_entries)); 21013 + js_setprop(js, array_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_array_toString)); 21014 + js_setprop(js, array_proto, js_mkstr(js, "toLocaleString", 14), js_mkfun(builtin_array_toLocaleString)); 20715 21015 20716 21016 jsval_t string_proto = js_mkobj(js); 20717 21017 set_proto(js, string_proto, object_proto); 20718 - setprop(js, string_proto, js_mkstr(js, "indexOf", 7), js_mkfun(builtin_string_indexOf)); 20719 - setprop(js, string_proto, js_mkstr(js, "substring", 9), js_mkfun(builtin_string_substring)); 20720 - setprop(js, string_proto, js_mkstr(js, "substr", 6), js_mkfun(builtin_string_substr)); 20721 - setprop(js, string_proto, js_mkstr(js, "split", 5), js_mkfun(builtin_string_split)); 20722 - setprop(js, string_proto, js_mkstr(js, "slice", 5), js_mkfun(builtin_string_slice)); 20723 - setprop(js, string_proto, js_mkstr(js, "includes", 8), js_mkfun(builtin_string_includes)); 20724 - setprop(js, string_proto, js_mkstr(js, "startsWith", 10), js_mkfun(builtin_string_startsWith)); 20725 - setprop(js, string_proto, js_mkstr(js, "endsWith", 8), js_mkfun(builtin_string_endsWith)); 20726 - setprop(js, string_proto, js_mkstr(js, "replace", 7), js_mkfun(builtin_string_replace)); 20727 - setprop(js, string_proto, js_mkstr(js, "replaceAll", 10), js_mkfun(builtin_string_replaceAll)); 20728 - setprop(js, string_proto, js_mkstr(js, "match", 5), js_mkfun(builtin_string_match)); 20729 - setprop(js, string_proto, js_mkstr(js, "template", 8), js_mkfun(builtin_string_template)); 20730 - setprop(js, string_proto, js_mkstr(js, "charCodeAt", 10), js_mkfun(builtin_string_charCodeAt)); 20731 - setprop(js, string_proto, js_mkstr(js, "codePointAt", 11), js_mkfun(builtin_string_codePointAt)); 20732 - setprop(js, string_proto, js_mkstr(js, "toLowerCase", 11), js_mkfun(builtin_string_toLowerCase)); 20733 - setprop(js, string_proto, js_mkstr(js, "toUpperCase", 11), js_mkfun(builtin_string_toUpperCase)); 20734 - setprop(js, string_proto, js_mkstr(js, "toLocaleLowerCase", 17), js_mkfun(builtin_string_toLowerCase)); 20735 - setprop(js, string_proto, js_mkstr(js, "toLocaleUpperCase", 17), js_mkfun(builtin_string_toUpperCase)); 20736 - setprop(js, string_proto, js_mkstr(js, "trim", 4), js_mkfun(builtin_string_trim)); 20737 - setprop(js, string_proto, js_mkstr(js, "trimStart", 9), js_mkfun(builtin_string_trimStart)); 20738 - setprop(js, string_proto, js_mkstr(js, "trimEnd", 7), js_mkfun(builtin_string_trimEnd)); 20739 - setprop(js, string_proto, js_mkstr(js, "repeat", 6), js_mkfun(builtin_string_repeat)); 20740 - setprop(js, string_proto, js_mkstr(js, "padStart", 8), js_mkfun(builtin_string_padStart)); 20741 - setprop(js, string_proto, js_mkstr(js, "padEnd", 6), js_mkfun(builtin_string_padEnd)); 20742 - setprop(js, string_proto, js_mkstr(js, "charAt", 6), js_mkfun(builtin_string_charAt)); 20743 - setprop(js, string_proto, js_mkstr(js, "at", 2), js_mkfun(builtin_string_at)); 20744 - setprop(js, string_proto, js_mkstr(js, "lastIndexOf", 11), js_mkfun(builtin_string_lastIndexOf)); 20745 - setprop(js, string_proto, js_mkstr(js, "concat", 6), js_mkfun(builtin_string_concat)); 20746 - setprop(js, string_proto, js_mkstr(js, "search", 6), js_mkfun(builtin_string_search)); 20747 - setprop(js, string_proto, js_mkstr(js, "localeCompare", 13), js_mkfun(builtin_string_localeCompare)); 20748 - setprop(js, string_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_string_valueOf)); 20749 - setprop(js, string_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_string_toString)); 21018 + js_setprop(js, string_proto, js_mkstr(js, "indexOf", 7), js_mkfun(builtin_string_indexOf)); 21019 + js_setprop(js, string_proto, js_mkstr(js, "substring", 9), js_mkfun(builtin_string_substring)); 21020 + js_setprop(js, string_proto, js_mkstr(js, "substr", 6), js_mkfun(builtin_string_substr)); 21021 + js_setprop(js, string_proto, js_mkstr(js, "split", 5), js_mkfun(builtin_string_split)); 21022 + js_setprop(js, string_proto, js_mkstr(js, "slice", 5), js_mkfun(builtin_string_slice)); 21023 + js_setprop(js, string_proto, js_mkstr(js, "includes", 8), js_mkfun(builtin_string_includes)); 21024 + js_setprop(js, string_proto, js_mkstr(js, "startsWith", 10), js_mkfun(builtin_string_startsWith)); 21025 + js_setprop(js, string_proto, js_mkstr(js, "endsWith", 8), js_mkfun(builtin_string_endsWith)); 21026 + js_setprop(js, string_proto, js_mkstr(js, "replace", 7), js_mkfun(builtin_string_replace)); 21027 + js_setprop(js, string_proto, js_mkstr(js, "replaceAll", 10), js_mkfun(builtin_string_replaceAll)); 21028 + js_setprop(js, string_proto, js_mkstr(js, "match", 5), js_mkfun(builtin_string_match)); 21029 + js_setprop(js, string_proto, js_mkstr(js, "template", 8), js_mkfun(builtin_string_template)); 21030 + js_setprop(js, string_proto, js_mkstr(js, "charCodeAt", 10), js_mkfun(builtin_string_charCodeAt)); 21031 + js_setprop(js, string_proto, js_mkstr(js, "codePointAt", 11), js_mkfun(builtin_string_codePointAt)); 21032 + js_setprop(js, string_proto, js_mkstr(js, "toLowerCase", 11), js_mkfun(builtin_string_toLowerCase)); 21033 + js_setprop(js, string_proto, js_mkstr(js, "toUpperCase", 11), js_mkfun(builtin_string_toUpperCase)); 21034 + js_setprop(js, string_proto, js_mkstr(js, "toLocaleLowerCase", 17), js_mkfun(builtin_string_toLowerCase)); 21035 + js_setprop(js, string_proto, js_mkstr(js, "toLocaleUpperCase", 17), js_mkfun(builtin_string_toUpperCase)); 21036 + js_setprop(js, string_proto, js_mkstr(js, "trim", 4), js_mkfun(builtin_string_trim)); 21037 + js_setprop(js, string_proto, js_mkstr(js, "trimStart", 9), js_mkfun(builtin_string_trimStart)); 21038 + js_setprop(js, string_proto, js_mkstr(js, "trimEnd", 7), js_mkfun(builtin_string_trimEnd)); 21039 + js_setprop(js, string_proto, js_mkstr(js, "repeat", 6), js_mkfun(builtin_string_repeat)); 21040 + js_setprop(js, string_proto, js_mkstr(js, "padStart", 8), js_mkfun(builtin_string_padStart)); 21041 + js_setprop(js, string_proto, js_mkstr(js, "padEnd", 6), js_mkfun(builtin_string_padEnd)); 21042 + js_setprop(js, string_proto, js_mkstr(js, "charAt", 6), js_mkfun(builtin_string_charAt)); 21043 + js_setprop(js, string_proto, js_mkstr(js, "at", 2), js_mkfun(builtin_string_at)); 21044 + js_setprop(js, string_proto, js_mkstr(js, "lastIndexOf", 11), js_mkfun(builtin_string_lastIndexOf)); 21045 + js_setprop(js, string_proto, js_mkstr(js, "concat", 6), js_mkfun(builtin_string_concat)); 21046 + js_setprop(js, string_proto, js_mkstr(js, "search", 6), js_mkfun(builtin_string_search)); 21047 + js_setprop(js, string_proto, js_mkstr(js, "localeCompare", 13), js_mkfun(builtin_string_localeCompare)); 21048 + js_setprop(js, string_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_string_valueOf)); 21049 + js_setprop(js, string_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_string_toString)); 20750 21050 20751 21051 jsval_t number_proto = js_mkobj(js); 20752 21052 set_proto(js, number_proto, object_proto); 20753 - setprop(js, number_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_number_toString)); 20754 - setprop(js, number_proto, js_mkstr(js, "toFixed", 7), js_mkfun(builtin_number_toFixed)); 20755 - setprop(js, number_proto, js_mkstr(js, "toPrecision", 11), js_mkfun(builtin_number_toPrecision)); 20756 - setprop(js, number_proto, js_mkstr(js, "toExponential", 13), js_mkfun(builtin_number_toExponential)); 20757 - setprop(js, number_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_number_valueOf)); 20758 - setprop(js, number_proto, js_mkstr(js, "toLocaleString", 14), js_mkfun(builtin_number_toLocaleString)); 21053 + js_setprop(js, number_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_number_toString)); 21054 + js_setprop(js, number_proto, js_mkstr(js, "toFixed", 7), js_mkfun(builtin_number_toFixed)); 21055 + js_setprop(js, number_proto, js_mkstr(js, "toPrecision", 11), js_mkfun(builtin_number_toPrecision)); 21056 + js_setprop(js, number_proto, js_mkstr(js, "toExponential", 13), js_mkfun(builtin_number_toExponential)); 21057 + js_setprop(js, number_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_number_valueOf)); 21058 + js_setprop(js, number_proto, js_mkstr(js, "toLocaleString", 14), js_mkfun(builtin_number_toLocaleString)); 20759 21059 20760 21060 jsval_t boolean_proto = js_mkobj(js); 20761 21061 set_proto(js, boolean_proto, object_proto); 20762 - setprop(js, boolean_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_boolean_valueOf)); 20763 - setprop(js, boolean_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_boolean_toString)); 21062 + js_setprop(js, boolean_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_boolean_valueOf)); 21063 + js_setprop(js, boolean_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_boolean_toString)); 20764 21064 20765 21065 jsval_t bigint_proto = js_mkobj(js); 20766 21066 set_proto(js, bigint_proto, object_proto); 20767 - setprop(js, bigint_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_bigint_toString)); 21067 + js_setprop(js, bigint_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_bigint_toString)); 20768 21068 20769 21069 jsval_t error_proto = js_mkobj(js); 20770 21070 set_proto(js, error_proto, object_proto); 20771 - setprop(js, error_proto, ANT_STRING("name"), ANT_STRING("Error")); 20772 - setprop(js, error_proto, ANT_STRING("message"), js_mkstr(js, "", 0)); 21071 + js_setprop(js, error_proto, ANT_STRING("name"), ANT_STRING("Error")); 21072 + js_setprop(js, error_proto, ANT_STRING("message"), js_mkstr(js, "", 0)); 21073 + js_setprop(js, error_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_Error_toString)); 20773 21074 20774 21075 jsval_t err_ctor_obj = mkobj(js, 0); 20775 21076 set_proto(js, err_ctor_obj, function_proto); 20776 21077 set_slot(js, err_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Error)); 20777 21078 js_setprop_nonconfigurable(js, err_ctor_obj, "prototype", 9, error_proto); 20778 - setprop(js, err_ctor_obj, ANT_STRING("name"), ANT_STRING("Error")); 20779 - setprop(js, glob, ANT_STRING("Error"), mkval(T_FUNC, vdata(err_ctor_obj))); 20780 - setprop(js, error_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(err_ctor_obj))); 21079 + js_setprop(js, err_ctor_obj, ANT_STRING("name"), ANT_STRING("Error")); 21080 + js_setprop(js, glob, ANT_STRING("Error"), mkval(T_FUNC, vdata(err_ctor_obj))); 21081 + js_setprop(js, error_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(err_ctor_obj))); 20781 21082 js_set_descriptor(js, error_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 20782 21083 20783 21084 #define REGISTER_ERROR_SUBTYPE(name_str) do { \ 20784 21085 jsval_t proto = js_mkobj(js); \ 20785 21086 set_proto(js, proto, error_proto); \ 20786 - setprop(js, proto, ANT_STRING("name"), ANT_STRING(name_str)); \ 21087 + js_setprop(js, proto, ANT_STRING("name"), ANT_STRING(name_str)); \ 20787 21088 jsval_t ctor = mkobj(js, 0); \ 20788 21089 set_proto(js, ctor, function_proto); \ 20789 21090 set_slot(js, ctor, SLOT_CFUNC, js_mkfun(builtin_Error)); \ 20790 21091 js_setprop_nonconfigurable(js, ctor, "prototype", 9, proto); \ 20791 - setprop(js, ctor, ANT_STRING("name"), ANT_STRING(name_str)); \ 20792 - setprop(js, proto, ANT_STRING("constructor"), mkval(T_FUNC, vdata(ctor))); \ 21092 + js_setprop(js, ctor, ANT_STRING("name"), ANT_STRING(name_str)); \ 21093 + js_setprop(js, proto, ANT_STRING("constructor"), mkval(T_FUNC, vdata(ctor))); \ 20793 21094 js_set_descriptor(js, proto, "constructor", 11, JS_DESC_W | JS_DESC_C); \ 20794 - setprop(js, glob, ANT_STRING(name_str), mkval(T_FUNC, vdata(ctor))); \ 21095 + js_setprop(js, glob, ANT_STRING(name_str), mkval(T_FUNC, vdata(ctor))); \ 20795 21096 } while(0) 20796 21097 20797 21098 REGISTER_ERROR_SUBTYPE("EvalError"); ··· 20806 21107 20807 21108 jsval_t proto = js_mkobj(js); 20808 21109 set_proto(js, proto, error_proto); 20809 - setprop(js, proto, ANT_STRING("name"), ANT_STRING("AggregateError")); 21110 + js_setprop(js, proto, ANT_STRING("name"), ANT_STRING("AggregateError")); 20810 21111 jsval_t ctor = mkobj(js, 0); 20811 21112 set_proto(js, ctor, function_proto); 20812 21113 set_slot(js, ctor, SLOT_CFUNC, js_mkfun(builtin_AggregateError)); 20813 21114 js_setprop_nonconfigurable(js, ctor, "prototype", 9, proto); 20814 - setprop(js, ctor, ANT_STRING("name"), ANT_STRING("AggregateError")); 20815 - setprop(js, proto, ANT_STRING("constructor"), mkval(T_FUNC, vdata(ctor))); 21115 + js_setprop(js, ctor, ANT_STRING("name"), ANT_STRING("AggregateError")); 21116 + js_setprop(js, proto, ANT_STRING("constructor"), mkval(T_FUNC, vdata(ctor))); 20816 21117 js_set_descriptor(js, proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 20817 - setprop(js, glob, ANT_STRING("AggregateError"), mkval(T_FUNC, vdata(ctor))); 21118 + js_setprop(js, glob, ANT_STRING("AggregateError"), mkval(T_FUNC, vdata(ctor))); 20818 21119 20819 21120 jsval_t date_proto = js_mkobj(js); 20820 21121 set_proto(js, date_proto, object_proto); 20821 - setprop(js, date_proto, js_mkstr(js, "getTime", 7), js_mkfun(builtin_Date_getTime)); 20822 - setprop(js, date_proto, js_mkstr(js, "getFullYear", 11), js_mkfun(builtin_Date_getFullYear)); 20823 - setprop(js, date_proto, js_mkstr(js, "getMonth", 8), js_mkfun(builtin_Date_getMonth)); 20824 - setprop(js, date_proto, js_mkstr(js, "getDate", 7), js_mkfun(builtin_Date_getDate)); 20825 - setprop(js, date_proto, js_mkstr(js, "getHours", 8), js_mkfun(builtin_Date_getHours)); 20826 - setprop(js, date_proto, js_mkstr(js, "getMinutes", 10), js_mkfun(builtin_Date_getMinutes)); 20827 - setprop(js, date_proto, js_mkstr(js, "getSeconds", 10), js_mkfun(builtin_Date_getSeconds)); 20828 - setprop(js, date_proto, js_mkstr(js, "getMilliseconds", 15), js_mkfun(builtin_Date_getMilliseconds)); 20829 - setprop(js, date_proto, js_mkstr(js, "getDay", 6), js_mkfun(builtin_Date_getDay)); 20830 - setprop(js, date_proto, js_mkstr(js, "getTimezoneOffset", 17), js_mkfun(builtin_Date_getTimezoneOffset)); 20831 - setprop(js, date_proto, js_mkstr(js, "getUTCFullYear", 14), js_mkfun(builtin_Date_getUTCFullYear)); 20832 - setprop(js, date_proto, js_mkstr(js, "getUTCMonth", 11), js_mkfun(builtin_Date_getUTCMonth)); 20833 - setprop(js, date_proto, js_mkstr(js, "getUTCDate", 10), js_mkfun(builtin_Date_getUTCDate)); 20834 - setprop(js, date_proto, js_mkstr(js, "getUTCHours", 11), js_mkfun(builtin_Date_getUTCHours)); 20835 - setprop(js, date_proto, js_mkstr(js, "getUTCMinutes", 13), js_mkfun(builtin_Date_getUTCMinutes)); 20836 - setprop(js, date_proto, js_mkstr(js, "getUTCSeconds", 13), js_mkfun(builtin_Date_getUTCSeconds)); 20837 - setprop(js, date_proto, js_mkstr(js, "getUTCMilliseconds", 18), js_mkfun(builtin_Date_getUTCMilliseconds)); 20838 - setprop(js, date_proto, js_mkstr(js, "getUTCDay", 9), js_mkfun(builtin_Date_getUTCDay)); 20839 - setprop(js, date_proto, js_mkstr(js, "setTime", 7), js_mkfun(builtin_Date_setTime)); 20840 - setprop(js, date_proto, js_mkstr(js, "setMilliseconds", 15), js_mkfun(builtin_Date_setMilliseconds)); 20841 - setprop(js, date_proto, js_mkstr(js, "setSeconds", 10), js_mkfun(builtin_Date_setSeconds)); 20842 - setprop(js, date_proto, js_mkstr(js, "setMinutes", 10), js_mkfun(builtin_Date_setMinutes)); 20843 - setprop(js, date_proto, js_mkstr(js, "setHours", 8), js_mkfun(builtin_Date_setHours)); 20844 - setprop(js, date_proto, js_mkstr(js, "setDate", 7), js_mkfun(builtin_Date_setDate)); 20845 - setprop(js, date_proto, js_mkstr(js, "setMonth", 8), js_mkfun(builtin_Date_setMonth)); 20846 - setprop(js, date_proto, js_mkstr(js, "setFullYear", 11), js_mkfun(builtin_Date_setFullYear)); 20847 - setprop(js, date_proto, js_mkstr(js, "setUTCMilliseconds", 18), js_mkfun(builtin_Date_setUTCMilliseconds)); 20848 - setprop(js, date_proto, js_mkstr(js, "setUTCSeconds", 13), js_mkfun(builtin_Date_setUTCSeconds)); 20849 - setprop(js, date_proto, js_mkstr(js, "setUTCMinutes", 13), js_mkfun(builtin_Date_setUTCMinutes)); 20850 - setprop(js, date_proto, js_mkstr(js, "setUTCHours", 11), js_mkfun(builtin_Date_setUTCHours)); 20851 - setprop(js, date_proto, js_mkstr(js, "setUTCDate", 10), js_mkfun(builtin_Date_setUTCDate)); 20852 - setprop(js, date_proto, js_mkstr(js, "setUTCMonth", 11), js_mkfun(builtin_Date_setUTCMonth)); 20853 - setprop(js, date_proto, js_mkstr(js, "setUTCFullYear", 14), js_mkfun(builtin_Date_setUTCFullYear)); 20854 - setprop(js, date_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_Date_valueOf)); 20855 - setprop(js, date_proto, js_mkstr(js, "toISOString", 11), js_mkfun(builtin_Date_toISOString)); 20856 - setprop(js, date_proto, js_mkstr(js, "toUTCString", 11), js_mkfun(builtin_Date_toUTCString)); 20857 - setprop(js, date_proto, js_mkstr(js, "toGMTString", 11), js_mkfun(builtin_Date_toUTCString)); 20858 - setprop(js, date_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_Date_toString)); 20859 - setprop(js, date_proto, js_mkstr(js, "toDateString", 12), js_mkfun(builtin_Date_toDateString)); 20860 - setprop(js, date_proto, js_mkstr(js, "toTimeString", 12), js_mkfun(builtin_Date_toTimeString)); 20861 - setprop(js, date_proto, js_mkstr(js, "toLocaleDateString", 18), js_mkfun(builtin_Date_toLocaleDateString)); 20862 - setprop(js, date_proto, js_mkstr(js, "toLocaleTimeString", 18), js_mkfun(builtin_Date_toLocaleTimeString)); 20863 - setprop(js, date_proto, js_mkstr(js, "getYear", 7), js_mkfun(builtin_Date_getYear)); 20864 - setprop(js, date_proto, js_mkstr(js, "setYear", 7), js_mkfun(builtin_Date_setYear)); 20865 - setprop(js, date_proto, js_mkstr(js, "toJSON", 6), js_mkfun(builtin_Date_toJSON)); 21122 + js_setprop(js, date_proto, js_mkstr(js, "getTime", 7), js_mkfun(builtin_Date_getTime)); 21123 + js_setprop(js, date_proto, js_mkstr(js, "getFullYear", 11), js_mkfun(builtin_Date_getFullYear)); 21124 + js_setprop(js, date_proto, js_mkstr(js, "getMonth", 8), js_mkfun(builtin_Date_getMonth)); 21125 + js_setprop(js, date_proto, js_mkstr(js, "getDate", 7), js_mkfun(builtin_Date_getDate)); 21126 + js_setprop(js, date_proto, js_mkstr(js, "getHours", 8), js_mkfun(builtin_Date_getHours)); 21127 + js_setprop(js, date_proto, js_mkstr(js, "getMinutes", 10), js_mkfun(builtin_Date_getMinutes)); 21128 + js_setprop(js, date_proto, js_mkstr(js, "getSeconds", 10), js_mkfun(builtin_Date_getSeconds)); 21129 + js_setprop(js, date_proto, js_mkstr(js, "getMilliseconds", 15), js_mkfun(builtin_Date_getMilliseconds)); 21130 + js_setprop(js, date_proto, js_mkstr(js, "getDay", 6), js_mkfun(builtin_Date_getDay)); 21131 + js_setprop(js, date_proto, js_mkstr(js, "getTimezoneOffset", 17), js_mkfun(builtin_Date_getTimezoneOffset)); 21132 + js_setprop(js, date_proto, js_mkstr(js, "getUTCFullYear", 14), js_mkfun(builtin_Date_getUTCFullYear)); 21133 + js_setprop(js, date_proto, js_mkstr(js, "getUTCMonth", 11), js_mkfun(builtin_Date_getUTCMonth)); 21134 + js_setprop(js, date_proto, js_mkstr(js, "getUTCDate", 10), js_mkfun(builtin_Date_getUTCDate)); 21135 + js_setprop(js, date_proto, js_mkstr(js, "getUTCHours", 11), js_mkfun(builtin_Date_getUTCHours)); 21136 + js_setprop(js, date_proto, js_mkstr(js, "getUTCMinutes", 13), js_mkfun(builtin_Date_getUTCMinutes)); 21137 + js_setprop(js, date_proto, js_mkstr(js, "getUTCSeconds", 13), js_mkfun(builtin_Date_getUTCSeconds)); 21138 + js_setprop(js, date_proto, js_mkstr(js, "getUTCMilliseconds", 18), js_mkfun(builtin_Date_getUTCMilliseconds)); 21139 + js_setprop(js, date_proto, js_mkstr(js, "getUTCDay", 9), js_mkfun(builtin_Date_getUTCDay)); 21140 + js_setprop(js, date_proto, js_mkstr(js, "setTime", 7), js_mkfun(builtin_Date_setTime)); 21141 + js_setprop(js, date_proto, js_mkstr(js, "setMilliseconds", 15), js_mkfun(builtin_Date_setMilliseconds)); 21142 + js_setprop(js, date_proto, js_mkstr(js, "setSeconds", 10), js_mkfun(builtin_Date_setSeconds)); 21143 + js_setprop(js, date_proto, js_mkstr(js, "setMinutes", 10), js_mkfun(builtin_Date_setMinutes)); 21144 + js_setprop(js, date_proto, js_mkstr(js, "setHours", 8), js_mkfun(builtin_Date_setHours)); 21145 + js_setprop(js, date_proto, js_mkstr(js, "setDate", 7), js_mkfun(builtin_Date_setDate)); 21146 + js_setprop(js, date_proto, js_mkstr(js, "setMonth", 8), js_mkfun(builtin_Date_setMonth)); 21147 + js_setprop(js, date_proto, js_mkstr(js, "setFullYear", 11), js_mkfun(builtin_Date_setFullYear)); 21148 + js_setprop(js, date_proto, js_mkstr(js, "setUTCMilliseconds", 18), js_mkfun(builtin_Date_setUTCMilliseconds)); 21149 + js_setprop(js, date_proto, js_mkstr(js, "setUTCSeconds", 13), js_mkfun(builtin_Date_setUTCSeconds)); 21150 + js_setprop(js, date_proto, js_mkstr(js, "setUTCMinutes", 13), js_mkfun(builtin_Date_setUTCMinutes)); 21151 + js_setprop(js, date_proto, js_mkstr(js, "setUTCHours", 11), js_mkfun(builtin_Date_setUTCHours)); 21152 + js_setprop(js, date_proto, js_mkstr(js, "setUTCDate", 10), js_mkfun(builtin_Date_setUTCDate)); 21153 + js_setprop(js, date_proto, js_mkstr(js, "setUTCMonth", 11), js_mkfun(builtin_Date_setUTCMonth)); 21154 + js_setprop(js, date_proto, js_mkstr(js, "setUTCFullYear", 14), js_mkfun(builtin_Date_setUTCFullYear)); 21155 + js_setprop(js, date_proto, js_mkstr(js, "valueOf", 7), js_mkfun(builtin_Date_valueOf)); 21156 + js_setprop(js, date_proto, js_mkstr(js, "toISOString", 11), js_mkfun(builtin_Date_toISOString)); 21157 + js_setprop(js, date_proto, js_mkstr(js, "toUTCString", 11), js_mkfun(builtin_Date_toUTCString)); 21158 + js_setprop(js, date_proto, js_mkstr(js, "toGMTString", 11), js_mkfun(builtin_Date_toUTCString)); 21159 + js_setprop(js, date_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_Date_toString)); 21160 + js_setprop(js, date_proto, js_mkstr(js, "toDateString", 12), js_mkfun(builtin_Date_toDateString)); 21161 + js_setprop(js, date_proto, js_mkstr(js, "toTimeString", 12), js_mkfun(builtin_Date_toTimeString)); 21162 + js_setprop(js, date_proto, js_mkstr(js, "toLocaleDateString", 18), js_mkfun(builtin_Date_toLocaleDateString)); 21163 + js_setprop(js, date_proto, js_mkstr(js, "toLocaleTimeString", 18), js_mkfun(builtin_Date_toLocaleTimeString)); 21164 + js_setprop(js, date_proto, js_mkstr(js, "getYear", 7), js_mkfun(builtin_Date_getYear)); 21165 + js_setprop(js, date_proto, js_mkstr(js, "setYear", 7), js_mkfun(builtin_Date_setYear)); 21166 + js_setprop(js, date_proto, js_mkstr(js, "toJSON", 6), js_mkfun(builtin_Date_toJSON)); 20866 21167 20867 21168 jsval_t regexp_proto = js_mkobj(js); 20868 21169 set_proto(js, regexp_proto, object_proto); 20869 - setprop(js, regexp_proto, js_mkstr(js, "test", 4), js_mkfun(builtin_regexp_test)); 20870 - setprop(js, regexp_proto, js_mkstr(js, "exec", 4), js_mkfun(builtin_regexp_exec)); 20871 - setprop(js, regexp_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_regexp_toString)); 21170 + js_setprop(js, regexp_proto, js_mkstr(js, "test", 4), js_mkfun(builtin_regexp_test)); 21171 + js_setprop(js, regexp_proto, js_mkstr(js, "exec", 4), js_mkfun(builtin_regexp_exec)); 21172 + js_setprop(js, regexp_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_regexp_toString)); 20872 21173 20873 21174 jsval_t promise_proto = js_mkobj(js); 20874 21175 set_proto(js, promise_proto, object_proto); 20875 - setprop(js, promise_proto, js_mkstr(js, "then", 4), js_mkfun(builtin_promise_then)); 20876 - setprop(js, promise_proto, js_mkstr(js, "catch", 5), js_mkfun(builtin_promise_catch)); 20877 - setprop(js, promise_proto, js_mkstr(js, "finally", 7), js_mkfun(builtin_promise_finally)); 21176 + js_setprop(js, promise_proto, js_mkstr(js, "then", 4), js_mkfun(builtin_promise_then)); 21177 + js_setprop(js, promise_proto, js_mkstr(js, "catch", 5), js_mkfun(builtin_promise_catch)); 21178 + js_setprop(js, promise_proto, js_mkstr(js, "finally", 7), js_mkfun(builtin_promise_finally)); 21179 + // Symbol.toStringTag is set in init_symbol_module after symbols are initialized 20878 21180 20879 21181 jsval_t obj_func_obj = mkobj(js, 0); 20880 21182 set_proto(js, obj_func_obj, function_proto); 20881 21183 set_slot(js, obj_func_obj, SLOT_BUILTIN, tov(BUILTIN_OBJECT)); 20882 - setprop(js, obj_func_obj, js_mkstr(js, "keys", 4), js_mkfun(builtin_object_keys)); 20883 - setprop(js, obj_func_obj, js_mkstr(js, "values", 6), js_mkfun(builtin_object_values)); 20884 - setprop(js, obj_func_obj, js_mkstr(js, "entries", 7), js_mkfun(builtin_object_entries)); 20885 - setprop(js, obj_func_obj, js_mkstr(js, "getPrototypeOf", 14), js_mkfun(builtin_object_getPrototypeOf)); 20886 - setprop(js, obj_func_obj, js_mkstr(js, "setPrototypeOf", 14), js_mkfun(builtin_object_setPrototypeOf)); 20887 - setprop(js, obj_func_obj, js_mkstr(js, "create", 6), js_mkfun(builtin_object_create)); 20888 - setprop(js, obj_func_obj, js_mkstr(js, "hasOwn", 6), js_mkfun(builtin_object_hasOwn)); 20889 - setprop(js, obj_func_obj, js_mkstr(js, "defineProperty", 14), js_mkfun(builtin_object_defineProperty)); 20890 - setprop(js, obj_func_obj, js_mkstr(js, "defineProperties", 16), js_mkfun(builtin_object_defineProperties)); 20891 - setprop(js, obj_func_obj, js_mkstr(js, "assign", 6), js_mkfun(builtin_object_assign)); 20892 - setprop(js, obj_func_obj, js_mkstr(js, "freeze", 6), js_mkfun(builtin_object_freeze)); 20893 - setprop(js, obj_func_obj, js_mkstr(js, "isFrozen", 8), js_mkfun(builtin_object_isFrozen)); 20894 - setprop(js, obj_func_obj, js_mkstr(js, "seal", 4), js_mkfun(builtin_object_seal)); 20895 - setprop(js, obj_func_obj, js_mkstr(js, "isSealed", 8), js_mkfun(builtin_object_isSealed)); 20896 - setprop(js, obj_func_obj, js_mkstr(js, "fromEntries", 11), js_mkfun(builtin_object_fromEntries)); 20897 - setprop(js, obj_func_obj, js_mkstr(js, "getOwnPropertyDescriptor", 24), js_mkfun(builtin_object_getOwnPropertyDescriptor)); 20898 - setprop(js, obj_func_obj, js_mkstr(js, "getOwnPropertyNames", 19), js_mkfun(builtin_object_getOwnPropertyNames)); 20899 - setprop(js, obj_func_obj, js_mkstr(js, "isExtensible", 12), js_mkfun(builtin_object_isExtensible)); 20900 - setprop(js, obj_func_obj, js_mkstr(js, "preventExtensions", 17), js_mkfun(builtin_object_preventExtensions)); 20901 - setprop(js, obj_func_obj, ANT_STRING("name"), ANT_STRING("Object")); 21184 + js_setprop(js, obj_func_obj, js_mkstr(js, "keys", 4), js_mkfun(builtin_object_keys)); 21185 + js_setprop(js, obj_func_obj, js_mkstr(js, "values", 6), js_mkfun(builtin_object_values)); 21186 + js_setprop(js, obj_func_obj, js_mkstr(js, "entries", 7), js_mkfun(builtin_object_entries)); 21187 + js_setprop(js, obj_func_obj, js_mkstr(js, "getPrototypeOf", 14), js_mkfun(builtin_object_getPrototypeOf)); 21188 + js_setprop(js, obj_func_obj, js_mkstr(js, "setPrototypeOf", 14), js_mkfun(builtin_object_setPrototypeOf)); 21189 + js_setprop(js, obj_func_obj, js_mkstr(js, "create", 6), js_mkfun(builtin_object_create)); 21190 + js_setprop(js, obj_func_obj, js_mkstr(js, "hasOwn", 6), js_mkfun(builtin_object_hasOwn)); 21191 + js_setprop(js, obj_func_obj, js_mkstr(js, "defineProperty", 14), js_mkfun(builtin_object_defineProperty)); 21192 + js_setprop(js, obj_func_obj, js_mkstr(js, "defineProperties", 16), js_mkfun(builtin_object_defineProperties)); 21193 + js_setprop(js, obj_func_obj, js_mkstr(js, "assign", 6), js_mkfun(builtin_object_assign)); 21194 + js_setprop(js, obj_func_obj, js_mkstr(js, "freeze", 6), js_mkfun(builtin_object_freeze)); 21195 + js_setprop(js, obj_func_obj, js_mkstr(js, "isFrozen", 8), js_mkfun(builtin_object_isFrozen)); 21196 + js_setprop(js, obj_func_obj, js_mkstr(js, "seal", 4), js_mkfun(builtin_object_seal)); 21197 + js_setprop(js, obj_func_obj, js_mkstr(js, "isSealed", 8), js_mkfun(builtin_object_isSealed)); 21198 + js_setprop(js, obj_func_obj, js_mkstr(js, "fromEntries", 11), js_mkfun(builtin_object_fromEntries)); 21199 + js_setprop(js, obj_func_obj, js_mkstr(js, "getOwnPropertyDescriptor", 24), js_mkfun(builtin_object_getOwnPropertyDescriptor)); 21200 + js_setprop(js, obj_func_obj, js_mkstr(js, "getOwnPropertyNames", 19), js_mkfun(builtin_object_getOwnPropertyNames)); 21201 + js_setprop(js, obj_func_obj, js_mkstr(js, "getOwnPropertySymbols", 21), js_mkfun(builtin_object_getOwnPropertySymbols)); 21202 + js_setprop(js, obj_func_obj, js_mkstr(js, "isExtensible", 12), js_mkfun(builtin_object_isExtensible)); 21203 + js_setprop(js, obj_func_obj, js_mkstr(js, "preventExtensions", 17), js_mkfun(builtin_object_preventExtensions)); 21204 + js_setprop(js, obj_func_obj, ANT_STRING("name"), ANT_STRING("Object")); 20902 21205 js_setprop_nonconfigurable(js, obj_func_obj, "prototype", 9, object_proto); 20903 - setprop(js, glob, js_mkstr(js, "Object", 6), mkval(T_FUNC, vdata(obj_func_obj))); 21206 + js_setprop(js, glob, js_mkstr(js, "Object", 6), mkval(T_FUNC, vdata(obj_func_obj))); 20904 21207 20905 21208 jsval_t func_ctor_obj = mkobj(js, 0); 20906 21209 set_proto(js, func_ctor_obj, function_proto); 20907 21210 set_slot(js, func_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Function)); 20908 21211 js_setprop_nonconfigurable(js, func_ctor_obj, "prototype", 9, function_proto); 20909 - setprop(js, func_ctor_obj, js_mkstr(js, "length", 6), tov(1.0)); 21212 + js_setprop(js, func_ctor_obj, js_mkstr(js, "length", 6), tov(1.0)); 20910 21213 js_set_descriptor(js, func_ctor_obj, "length", 6, JS_DESC_C); 20911 - setprop(js, func_ctor_obj, ANT_STRING("name"), ANT_STRING("Function")); 20912 - setprop(js, glob, js_mkstr(js, "Function", 8), mkval(T_FUNC, vdata(func_ctor_obj))); 21214 + js_setprop(js, func_ctor_obj, ANT_STRING("name"), ANT_STRING("Function")); 21215 + js_setprop(js, glob, js_mkstr(js, "Function", 8), mkval(T_FUNC, vdata(func_ctor_obj))); 20913 21216 20914 21217 jsval_t async_func_proto_obj = js_mkobj(js); 20915 21218 set_proto(js, async_func_proto_obj, function_proto); ··· 20921 21224 set_proto(js, async_func_ctor_obj, function_proto); 20922 21225 set_slot(js, async_func_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_AsyncFunction)); 20923 21226 js_setprop_nonconfigurable(js, async_func_ctor_obj, "prototype", 9, async_func_proto); 20924 - setprop(js, async_func_ctor_obj, js_mkstr(js, "length", 6), tov(1.0)); 21227 + js_setprop(js, async_func_ctor_obj, js_mkstr(js, "length", 6), tov(1.0)); 20925 21228 js_set_descriptor(js, async_func_ctor_obj, "length", 6, JS_DESC_C); 20926 - setprop(js, async_func_ctor_obj, ANT_STRING("name"), ANT_STRING("AsyncFunction")); 21229 + js_setprop(js, async_func_ctor_obj, ANT_STRING("name"), ANT_STRING("AsyncFunction")); 20927 21230 jsval_t async_func_ctor = mkval(T_FUNC, vdata(async_func_ctor_obj)); 20928 21231 20929 - setprop(js, async_func_proto_obj, js_mkstr(js, "constructor", 11), async_func_ctor); 21232 + js_setprop(js, async_func_proto_obj, js_mkstr(js, "constructor", 11), async_func_ctor); 20930 21233 js_set_descriptor(js, async_func_proto_obj, "constructor", 11, JS_DESC_W | JS_DESC_C); 20931 21234 20932 21235 jsval_t str_ctor_obj = mkobj(js, 0); 20933 21236 set_proto(js, str_ctor_obj, function_proto); 20934 21237 set_slot(js, str_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_String)); 20935 21238 js_setprop_nonconfigurable(js, str_ctor_obj, "prototype", 9, string_proto); 20936 - setprop(js, str_ctor_obj, js_mkstr(js, "fromCharCode", 12), js_mkfun(builtin_string_fromCharCode)); 20937 - setprop(js, str_ctor_obj, js_mkstr(js, "fromCodePoint", 13), js_mkfun(builtin_string_fromCodePoint)); 20938 - setprop(js, str_ctor_obj, ANT_STRING("name"), ANT_STRING("String")); 20939 - setprop(js, glob, js_mkstr(js, "String", 6), mkval(T_FUNC, vdata(str_ctor_obj))); 21239 + js_setprop(js, str_ctor_obj, js_mkstr(js, "fromCharCode", 12), js_mkfun(builtin_string_fromCharCode)); 21240 + js_setprop(js, str_ctor_obj, js_mkstr(js, "fromCodePoint", 13), js_mkfun(builtin_string_fromCodePoint)); 21241 + js_setprop(js, str_ctor_obj, ANT_STRING("name"), ANT_STRING("String")); 21242 + js_setprop(js, glob, js_mkstr(js, "String", 6), mkval(T_FUNC, vdata(str_ctor_obj))); 20940 21243 20941 21244 jsval_t number_ctor_obj = mkobj(js, 0); 20942 21245 set_proto(js, number_ctor_obj, function_proto); 20943 21246 20944 21247 set_slot(js, number_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Number)); 20945 - setprop(js, number_ctor_obj, js_mkstr(js, "isNaN", 5), js_mkfun(builtin_Number_isNaN)); 20946 - setprop(js, number_ctor_obj, js_mkstr(js, "isFinite", 8), js_mkfun(builtin_Number_isFinite)); 20947 - setprop(js, number_ctor_obj, js_mkstr(js, "isInteger", 9), js_mkfun(builtin_Number_isInteger)); 20948 - setprop(js, number_ctor_obj, js_mkstr(js, "isSafeInteger", 13), js_mkfun(builtin_Number_isSafeInteger)); 21248 + js_setprop(js, number_ctor_obj, js_mkstr(js, "isNaN", 5), js_mkfun(builtin_Number_isNaN)); 21249 + js_setprop(js, number_ctor_obj, js_mkstr(js, "isFinite", 8), js_mkfun(builtin_Number_isFinite)); 21250 + js_setprop(js, number_ctor_obj, js_mkstr(js, "isInteger", 9), js_mkfun(builtin_Number_isInteger)); 21251 + js_setprop(js, number_ctor_obj, js_mkstr(js, "isSafeInteger", 13), js_mkfun(builtin_Number_isSafeInteger)); 20949 21252 20950 - setprop(js, number_ctor_obj, js_mkstr(js, "MAX_VALUE", 9), tov(1.7976931348623157e+308)); 20951 - setprop(js, number_ctor_obj, js_mkstr(js, "MIN_VALUE", 9), tov(5e-324)); 20952 - setprop(js, number_ctor_obj, js_mkstr(js, "MAX_SAFE_INTEGER", 16), tov(9007199254740991.0)); 20953 - setprop(js, number_ctor_obj, js_mkstr(js, "MIN_SAFE_INTEGER", 16), tov(-9007199254740991.0)); 20954 - setprop(js, number_ctor_obj, js_mkstr(js, "POSITIVE_INFINITY", 17), tov(JS_INF)); 20955 - setprop(js, number_ctor_obj, js_mkstr(js, "NEGATIVE_INFINITY", 17), tov(JS_NEG_INF)); 20956 - setprop(js, number_ctor_obj, js_mkstr(js, "NaN", 3), tov(JS_NAN)); 20957 - setprop(js, number_ctor_obj, js_mkstr(js, "EPSILON", 7), tov(2.220446049250313e-16)); 21253 + js_setprop(js, number_ctor_obj, js_mkstr(js, "MAX_VALUE", 9), tov(1.7976931348623157e+308)); 21254 + js_setprop(js, number_ctor_obj, js_mkstr(js, "MIN_VALUE", 9), tov(5e-324)); 21255 + js_setprop(js, number_ctor_obj, js_mkstr(js, "MAX_SAFE_INTEGER", 16), tov(9007199254740991.0)); 21256 + js_setprop(js, number_ctor_obj, js_mkstr(js, "MIN_SAFE_INTEGER", 16), tov(-9007199254740991.0)); 21257 + js_setprop(js, number_ctor_obj, js_mkstr(js, "POSITIVE_INFINITY", 17), tov(JS_INF)); 21258 + js_setprop(js, number_ctor_obj, js_mkstr(js, "NEGATIVE_INFINITY", 17), tov(JS_NEG_INF)); 21259 + js_setprop(js, number_ctor_obj, js_mkstr(js, "NaN", 3), tov(JS_NAN)); 21260 + js_setprop(js, number_ctor_obj, js_mkstr(js, "EPSILON", 7), tov(2.220446049250313e-16)); 20958 21261 20959 21262 js_setprop_nonconfigurable(js, number_ctor_obj, "prototype", 9, number_proto); 20960 - setprop(js, number_ctor_obj, ANT_STRING("name"), ANT_STRING("Number")); 20961 - setprop(js, glob, js_mkstr(js, "Number", 6), mkval(T_FUNC, vdata(number_ctor_obj))); 21263 + js_setprop(js, number_ctor_obj, ANT_STRING("name"), ANT_STRING("Number")); 21264 + js_setprop(js, glob, js_mkstr(js, "Number", 6), mkval(T_FUNC, vdata(number_ctor_obj))); 20962 21265 20963 21266 jsval_t bool_ctor_obj = mkobj(js, 0); 20964 21267 set_proto(js, bool_ctor_obj, function_proto); 20965 21268 set_slot(js, bool_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Boolean)); 20966 21269 js_setprop_nonconfigurable(js, bool_ctor_obj, "prototype", 9, boolean_proto); 20967 - setprop(js, bool_ctor_obj, ANT_STRING("name"), ANT_STRING("Boolean")); 20968 - setprop(js, glob, js_mkstr(js, "Boolean", 7), mkval(T_FUNC, vdata(bool_ctor_obj))); 21270 + js_setprop(js, bool_ctor_obj, ANT_STRING("name"), ANT_STRING("Boolean")); 21271 + js_setprop(js, glob, js_mkstr(js, "Boolean", 7), mkval(T_FUNC, vdata(bool_ctor_obj))); 20969 21272 20970 21273 jsval_t arr_ctor_obj = mkobj(js, 0); 20971 21274 set_proto(js, arr_ctor_obj, function_proto); 20972 21275 set_slot(js, arr_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Array)); 20973 21276 js_setprop_nonconfigurable(js, arr_ctor_obj, "prototype", 9, array_proto); 20974 - setprop(js, arr_ctor_obj, js_mkstr(js, "isArray", 7), js_mkfun(builtin_Array_isArray)); 20975 - setprop(js, arr_ctor_obj, js_mkstr(js, "from", 4), js_mkfun(builtin_Array_from)); 20976 - setprop(js, arr_ctor_obj, js_mkstr(js, "of", 2), js_mkfun(builtin_Array_of)); 20977 - setprop(js, arr_ctor_obj, js_mkstr(js, "length", 6), tov(1.0)); 21277 + js_setprop(js, arr_ctor_obj, js_mkstr(js, "isArray", 7), js_mkfun(builtin_Array_isArray)); 21278 + js_setprop(js, arr_ctor_obj, js_mkstr(js, "from", 4), js_mkfun(builtin_Array_from)); 21279 + js_setprop(js, arr_ctor_obj, js_mkstr(js, "of", 2), js_mkfun(builtin_Array_of)); 21280 + js_setprop(js, arr_ctor_obj, js_mkstr(js, "length", 6), tov(1.0)); 20978 21281 js_set_descriptor(js, arr_ctor_obj, "length", 6, JS_DESC_C); 20979 - setprop(js, arr_ctor_obj, ANT_STRING("name"), ANT_STRING("Array")); 20980 - setprop(js, glob, js_mkstr(js, "Array", 5), mkval(T_FUNC, vdata(arr_ctor_obj))); 21282 + js_setprop(js, arr_ctor_obj, ANT_STRING("name"), ANT_STRING("Array")); 21283 + js_setprop(js, glob, js_mkstr(js, "Array", 5), mkval(T_FUNC, vdata(arr_ctor_obj))); 20981 21284 20982 21285 jsval_t proxy_ctor_obj = mkobj(js, 0); 20983 21286 set_proto(js, proxy_ctor_obj, function_proto); 20984 21287 set_slot(js, proxy_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Proxy)); 20985 - setprop(js, proxy_ctor_obj, js_mkstr(js, "revocable", 9), js_mkfun(builtin_Proxy_revocable)); 20986 - setprop(js, proxy_ctor_obj, ANT_STRING("name"), ANT_STRING("Proxy")); 20987 - setprop(js, glob, js_mkstr(js, "Proxy", 5), mkval(T_FUNC, vdata(proxy_ctor_obj))); 21288 + js_setprop(js, proxy_ctor_obj, js_mkstr(js, "revocable", 9), js_mkfun(builtin_Proxy_revocable)); 21289 + js_setprop(js, proxy_ctor_obj, ANT_STRING("name"), ANT_STRING("Proxy")); 21290 + js_setprop(js, glob, js_mkstr(js, "Proxy", 5), mkval(T_FUNC, vdata(proxy_ctor_obj))); 20988 21291 20989 21292 jsval_t regex_ctor_obj = mkobj(js, 0); 20990 21293 set_proto(js, regex_ctor_obj, function_proto); 20991 21294 set_slot(js, regex_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_RegExp)); 20992 21295 js_setprop_nonconfigurable(js, regex_ctor_obj, "prototype", 9, regexp_proto); 20993 - setprop(js, regex_ctor_obj, ANT_STRING("name"), ANT_STRING("RegExp")); 20994 - setprop(js, glob, js_mkstr(js, "RegExp", 6), mkval(T_FUNC, vdata(regex_ctor_obj))); 21296 + js_setprop(js, regex_ctor_obj, ANT_STRING("name"), ANT_STRING("RegExp")); 21297 + js_setprop(js, glob, js_mkstr(js, "RegExp", 6), mkval(T_FUNC, vdata(regex_ctor_obj))); 20995 21298 20996 21299 jsval_t date_ctor_obj = mkobj(js, 0); 20997 21300 set_proto(js, date_ctor_obj, function_proto); 20998 21301 set_slot(js, date_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Date)); 20999 - setprop(js, date_ctor_obj, js_mkstr(js, "now", 3), js_mkfun(builtin_Date_now)); 21000 - setprop(js, date_ctor_obj, js_mkstr(js, "UTC", 3), js_mkfun(builtin_Date_UTC)); 21302 + js_setprop(js, date_ctor_obj, js_mkstr(js, "now", 3), js_mkfun(builtin_Date_now)); 21303 + js_setprop(js, date_ctor_obj, js_mkstr(js, "UTC", 3), js_mkfun(builtin_Date_UTC)); 21001 21304 js_setprop_nonconfigurable(js, date_ctor_obj, "prototype", 9, date_proto); 21002 - setprop(js, date_ctor_obj, ANT_STRING("name"), ANT_STRING("Date")); 21003 - setprop(js, glob, js_mkstr(js, "Date", 4), mkval(T_FUNC, vdata(date_ctor_obj))); 21305 + js_setprop(js, date_ctor_obj, ANT_STRING("name"), ANT_STRING("Date")); 21306 + js_setprop(js, glob, js_mkstr(js, "Date", 4), mkval(T_FUNC, vdata(date_ctor_obj))); 21004 21307 21005 21308 jsval_t p_ctor_obj = mkobj(js, 0); 21006 21309 set_proto(js, p_ctor_obj, function_proto); 21007 21310 set_slot(js, p_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Promise)); 21008 - setprop(js, p_ctor_obj, js_mkstr(js, "resolve", 7), js_mkfun(builtin_Promise_resolve)); 21009 - setprop(js, p_ctor_obj, js_mkstr(js, "reject", 6), js_mkfun(builtin_Promise_reject)); 21010 - setprop(js, p_ctor_obj, js_mkstr(js, "try", 3), js_mkfun(builtin_Promise_try)); 21011 - setprop(js, p_ctor_obj, js_mkstr(js, "all", 3), js_mkfun(builtin_Promise_all)); 21012 - setprop(js, p_ctor_obj, js_mkstr(js, "race", 4), js_mkfun(builtin_Promise_race)); 21013 - setprop(js, p_ctor_obj, js_mkstr(js, "any", 3), js_mkfun(builtin_Promise_any)); 21311 + js_setprop(js, p_ctor_obj, js_mkstr(js, "resolve", 7), js_mkfun(builtin_Promise_resolve)); 21312 + js_setprop(js, p_ctor_obj, js_mkstr(js, "reject", 6), js_mkfun(builtin_Promise_reject)); 21313 + js_setprop(js, p_ctor_obj, js_mkstr(js, "try", 3), js_mkfun(builtin_Promise_try)); 21314 + js_setprop(js, p_ctor_obj, js_mkstr(js, "all", 3), js_mkfun(builtin_Promise_all)); 21315 + js_setprop(js, p_ctor_obj, js_mkstr(js, "race", 4), js_mkfun(builtin_Promise_race)); 21316 + js_setprop(js, p_ctor_obj, js_mkstr(js, "any", 3), js_mkfun(builtin_Promise_any)); 21014 21317 js_setprop_nonconfigurable(js, p_ctor_obj, "prototype", 9, promise_proto); 21015 - setprop(js, p_ctor_obj, ANT_STRING("name"), ANT_STRING("Promise")); 21016 - setprop(js, glob, js_mkstr(js, "Promise", 7), mkval(T_FUNC, vdata(p_ctor_obj))); 21318 + js_setprop(js, p_ctor_obj, ANT_STRING("name"), ANT_STRING("Promise")); 21319 + js_setprop(js, glob, js_mkstr(js, "Promise", 7), mkval(T_FUNC, vdata(p_ctor_obj))); 21017 21320 21018 21321 jsval_t bigint_ctor_obj = mkobj(js, 0); 21019 21322 set_proto(js, bigint_ctor_obj, function_proto); 21020 21323 set_slot(js, bigint_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_BigInt)); 21021 - setprop(js, bigint_ctor_obj, js_mkstr(js, "asIntN", 6), js_mkfun(builtin_BigInt_asIntN)); 21022 - setprop(js, bigint_ctor_obj, js_mkstr(js, "asUintN", 7), js_mkfun(builtin_BigInt_asUintN)); 21324 + js_setprop(js, bigint_ctor_obj, js_mkstr(js, "asIntN", 6), js_mkfun(builtin_BigInt_asIntN)); 21325 + js_setprop(js, bigint_ctor_obj, js_mkstr(js, "asUintN", 7), js_mkfun(builtin_BigInt_asUintN)); 21023 21326 js_setprop_nonconfigurable(js, bigint_ctor_obj, "prototype", 9, bigint_proto); 21024 - setprop(js, bigint_ctor_obj, ANT_STRING("name"), ANT_STRING("BigInt")); 21025 - setprop(js, glob, js_mkstr(js, "BigInt", 6), mkval(T_FUNC, vdata(bigint_ctor_obj))); 21327 + js_setprop(js, bigint_ctor_obj, ANT_STRING("name"), ANT_STRING("BigInt")); 21328 + js_setprop(js, glob, js_mkstr(js, "BigInt", 6), mkval(T_FUNC, vdata(bigint_ctor_obj))); 21026 21329 21027 - setprop(js, glob, js_mkstr(js, "eval", 4), js_mkfun(builtin_eval)); 21028 - setprop(js, glob, js_mkstr(js, "parseInt", 8), js_mkfun(builtin_parseInt)); 21029 - setprop(js, glob, js_mkstr(js, "parseFloat", 10), js_mkfun(builtin_parseFloat)); 21030 - setprop(js, glob, js_mkstr(js, "isNaN", 5), js_mkfun(builtin_global_isNaN)); 21031 - setprop(js, glob, js_mkstr(js, "isFinite", 8), js_mkfun(builtin_global_isFinite)); 21032 - setprop(js, glob, js_mkstr(js, "btoa", 4), js_mkfun(builtin_btoa)); 21033 - setprop(js, glob, js_mkstr(js, "atob", 4), js_mkfun(builtin_atob)); 21034 - setprop(js, glob, js_mkstr(js, "NaN", 3), tov(JS_NAN)); 21035 - setprop(js, glob, js_mkstr(js, "Infinity", 8), tov(JS_INF)); 21036 - setprop(js, glob, js_mkstr(js, "undefined", 9), js_mkundef()); 21330 + js_setprop(js, glob, js_mkstr(js, "eval", 4), js_mkfun(builtin_eval)); 21331 + js_setprop(js, glob, js_mkstr(js, "parseInt", 8), js_mkfun(builtin_parseInt)); 21332 + js_setprop(js, glob, js_mkstr(js, "parseFloat", 10), js_mkfun(builtin_parseFloat)); 21333 + js_setprop(js, glob, js_mkstr(js, "isNaN", 5), js_mkfun(builtin_global_isNaN)); 21334 + js_setprop(js, glob, js_mkstr(js, "isFinite", 8), js_mkfun(builtin_global_isFinite)); 21335 + js_setprop(js, glob, js_mkstr(js, "btoa", 4), js_mkfun(builtin_btoa)); 21336 + js_setprop(js, glob, js_mkstr(js, "atob", 4), js_mkfun(builtin_atob)); 21337 + js_setprop(js, glob, js_mkstr(js, "NaN", 3), tov(JS_NAN)); 21338 + js_setprop(js, glob, js_mkstr(js, "Infinity", 8), tov(JS_INF)); 21339 + js_setprop(js, glob, js_mkstr(js, "undefined", 9), js_mkundef()); 21037 21340 21038 21341 jsval_t math_obj = mkobj(js, 0); 21039 21342 set_proto(js, math_obj, object_proto); 21040 - setprop(js, math_obj, js_mkstr(js, "E", 1), tov(M_E)); 21041 - setprop(js, math_obj, js_mkstr(js, "LN10", 4), tov(M_LN10)); 21042 - setprop(js, math_obj, js_mkstr(js, "LN2", 3), tov(M_LN2)); 21043 - setprop(js, math_obj, js_mkstr(js, "LOG10E", 6), tov(M_LOG10E)); 21044 - setprop(js, math_obj, js_mkstr(js, "LOG2E", 5), tov(M_LOG2E)); 21045 - setprop(js, math_obj, js_mkstr(js, "PI", 2), tov(M_PI)); 21046 - setprop(js, math_obj, js_mkstr(js, "SQRT1_2", 7), tov(M_SQRT1_2)); 21047 - setprop(js, math_obj, js_mkstr(js, "SQRT2", 5), tov(M_SQRT2)); 21048 - setprop(js, math_obj, js_mkstr(js, "abs", 3), js_mkfun(builtin_Math_abs)); 21049 - setprop(js, math_obj, js_mkstr(js, "acos", 4), js_mkfun(builtin_Math_acos)); 21050 - setprop(js, math_obj, js_mkstr(js, "acosh", 5), js_mkfun(builtin_Math_acosh)); 21051 - setprop(js, math_obj, js_mkstr(js, "asin", 4), js_mkfun(builtin_Math_asin)); 21052 - setprop(js, math_obj, js_mkstr(js, "asinh", 5), js_mkfun(builtin_Math_asinh)); 21053 - setprop(js, math_obj, js_mkstr(js, "atan", 4), js_mkfun(builtin_Math_atan)); 21054 - setprop(js, math_obj, js_mkstr(js, "atanh", 5), js_mkfun(builtin_Math_atanh)); 21055 - setprop(js, math_obj, js_mkstr(js, "atan2", 5), js_mkfun(builtin_Math_atan2)); 21056 - setprop(js, math_obj, js_mkstr(js, "cbrt", 4), js_mkfun(builtin_Math_cbrt)); 21057 - setprop(js, math_obj, js_mkstr(js, "ceil", 4), js_mkfun(builtin_Math_ceil)); 21058 - setprop(js, math_obj, js_mkstr(js, "clz32", 5), js_mkfun(builtin_Math_clz32)); 21059 - setprop(js, math_obj, js_mkstr(js, "cos", 3), js_mkfun(builtin_Math_cos)); 21060 - setprop(js, math_obj, js_mkstr(js, "cosh", 4), js_mkfun(builtin_Math_cosh)); 21061 - setprop(js, math_obj, js_mkstr(js, "exp", 3), js_mkfun(builtin_Math_exp)); 21062 - setprop(js, math_obj, js_mkstr(js, "expm1", 5), js_mkfun(builtin_Math_expm1)); 21063 - setprop(js, math_obj, js_mkstr(js, "floor", 5), js_mkfun(builtin_Math_floor)); 21064 - setprop(js, math_obj, js_mkstr(js, "fround", 6), js_mkfun(builtin_Math_fround)); 21065 - setprop(js, math_obj, js_mkstr(js, "hypot", 5), js_mkfun(builtin_Math_hypot)); 21066 - setprop(js, math_obj, js_mkstr(js, "imul", 4), js_mkfun(builtin_Math_imul)); 21067 - setprop(js, math_obj, js_mkstr(js, "log", 3), js_mkfun(builtin_Math_log)); 21068 - setprop(js, math_obj, js_mkstr(js, "log1p", 5), js_mkfun(builtin_Math_log1p)); 21069 - setprop(js, math_obj, js_mkstr(js, "log10", 5), js_mkfun(builtin_Math_log10)); 21070 - setprop(js, math_obj, js_mkstr(js, "log2", 4), js_mkfun(builtin_Math_log2)); 21071 - setprop(js, math_obj, js_mkstr(js, "max", 3), js_mkfun(builtin_Math_max)); 21072 - setprop(js, math_obj, js_mkstr(js, "min", 3), js_mkfun(builtin_Math_min)); 21073 - setprop(js, math_obj, js_mkstr(js, "pow", 3), js_mkfun(builtin_Math_pow)); 21074 - setprop(js, math_obj, js_mkstr(js, "random", 6), js_mkfun(builtin_Math_random)); 21075 - setprop(js, math_obj, js_mkstr(js, "round", 5), js_mkfun(builtin_Math_round)); 21076 - setprop(js, math_obj, js_mkstr(js, "sign", 4), js_mkfun(builtin_Math_sign)); 21077 - setprop(js, math_obj, js_mkstr(js, "sin", 3), js_mkfun(builtin_Math_sin)); 21078 - setprop(js, math_obj, js_mkstr(js, "sinh", 4), js_mkfun(builtin_Math_sinh)); 21079 - setprop(js, math_obj, js_mkstr(js, "sqrt", 4), js_mkfun(builtin_Math_sqrt)); 21080 - setprop(js, math_obj, js_mkstr(js, "tan", 3), js_mkfun(builtin_Math_tan)); 21081 - setprop(js, math_obj, js_mkstr(js, "tanh", 4), js_mkfun(builtin_Math_tanh)); 21082 - setprop(js, math_obj, js_mkstr(js, "trunc", 5), js_mkfun(builtin_Math_trunc)); 21083 - setprop(js, glob, js_mkstr(js, "Math", 4), math_obj); 21343 + js_setprop(js, math_obj, js_mkstr(js, "E", 1), tov(M_E)); 21344 + js_setprop(js, math_obj, js_mkstr(js, "LN10", 4), tov(M_LN10)); 21345 + js_setprop(js, math_obj, js_mkstr(js, "LN2", 3), tov(M_LN2)); 21346 + js_setprop(js, math_obj, js_mkstr(js, "LOG10E", 6), tov(M_LOG10E)); 21347 + js_setprop(js, math_obj, js_mkstr(js, "LOG2E", 5), tov(M_LOG2E)); 21348 + js_setprop(js, math_obj, js_mkstr(js, "PI", 2), tov(M_PI)); 21349 + js_setprop(js, math_obj, js_mkstr(js, "SQRT1_2", 7), tov(M_SQRT1_2)); 21350 + js_setprop(js, math_obj, js_mkstr(js, "SQRT2", 5), tov(M_SQRT2)); 21351 + js_setprop(js, math_obj, js_mkstr(js, "abs", 3), js_mkfun(builtin_Math_abs)); 21352 + js_setprop(js, math_obj, js_mkstr(js, "acos", 4), js_mkfun(builtin_Math_acos)); 21353 + js_setprop(js, math_obj, js_mkstr(js, "acosh", 5), js_mkfun(builtin_Math_acosh)); 21354 + js_setprop(js, math_obj, js_mkstr(js, "asin", 4), js_mkfun(builtin_Math_asin)); 21355 + js_setprop(js, math_obj, js_mkstr(js, "asinh", 5), js_mkfun(builtin_Math_asinh)); 21356 + js_setprop(js, math_obj, js_mkstr(js, "atan", 4), js_mkfun(builtin_Math_atan)); 21357 + js_setprop(js, math_obj, js_mkstr(js, "atanh", 5), js_mkfun(builtin_Math_atanh)); 21358 + js_setprop(js, math_obj, js_mkstr(js, "atan2", 5), js_mkfun(builtin_Math_atan2)); 21359 + js_setprop(js, math_obj, js_mkstr(js, "cbrt", 4), js_mkfun(builtin_Math_cbrt)); 21360 + js_setprop(js, math_obj, js_mkstr(js, "ceil", 4), js_mkfun(builtin_Math_ceil)); 21361 + js_setprop(js, math_obj, js_mkstr(js, "clz32", 5), js_mkfun(builtin_Math_clz32)); 21362 + js_setprop(js, math_obj, js_mkstr(js, "cos", 3), js_mkfun(builtin_Math_cos)); 21363 + js_setprop(js, math_obj, js_mkstr(js, "cosh", 4), js_mkfun(builtin_Math_cosh)); 21364 + js_setprop(js, math_obj, js_mkstr(js, "exp", 3), js_mkfun(builtin_Math_exp)); 21365 + js_setprop(js, math_obj, js_mkstr(js, "expm1", 5), js_mkfun(builtin_Math_expm1)); 21366 + js_setprop(js, math_obj, js_mkstr(js, "floor", 5), js_mkfun(builtin_Math_floor)); 21367 + js_setprop(js, math_obj, js_mkstr(js, "fround", 6), js_mkfun(builtin_Math_fround)); 21368 + js_setprop(js, math_obj, js_mkstr(js, "hypot", 5), js_mkfun(builtin_Math_hypot)); 21369 + js_setprop(js, math_obj, js_mkstr(js, "imul", 4), js_mkfun(builtin_Math_imul)); 21370 + js_setprop(js, math_obj, js_mkstr(js, "log", 3), js_mkfun(builtin_Math_log)); 21371 + js_setprop(js, math_obj, js_mkstr(js, "log1p", 5), js_mkfun(builtin_Math_log1p)); 21372 + js_setprop(js, math_obj, js_mkstr(js, "log10", 5), js_mkfun(builtin_Math_log10)); 21373 + js_setprop(js, math_obj, js_mkstr(js, "log2", 4), js_mkfun(builtin_Math_log2)); 21374 + js_setprop(js, math_obj, js_mkstr(js, "max", 3), js_mkfun(builtin_Math_max)); 21375 + js_setprop(js, math_obj, js_mkstr(js, "min", 3), js_mkfun(builtin_Math_min)); 21376 + js_setprop(js, math_obj, js_mkstr(js, "pow", 3), js_mkfun(builtin_Math_pow)); 21377 + js_setprop(js, math_obj, js_mkstr(js, "random", 6), js_mkfun(builtin_Math_random)); 21378 + js_setprop(js, math_obj, js_mkstr(js, "round", 5), js_mkfun(builtin_Math_round)); 21379 + js_setprop(js, math_obj, js_mkstr(js, "sign", 4), js_mkfun(builtin_Math_sign)); 21380 + js_setprop(js, math_obj, js_mkstr(js, "sin", 3), js_mkfun(builtin_Math_sin)); 21381 + js_setprop(js, math_obj, js_mkstr(js, "sinh", 4), js_mkfun(builtin_Math_sinh)); 21382 + js_setprop(js, math_obj, js_mkstr(js, "sqrt", 4), js_mkfun(builtin_Math_sqrt)); 21383 + js_setprop(js, math_obj, js_mkstr(js, "tan", 3), js_mkfun(builtin_Math_tan)); 21384 + js_setprop(js, math_obj, js_mkstr(js, "tanh", 4), js_mkfun(builtin_Math_tanh)); 21385 + js_setprop(js, math_obj, js_mkstr(js, "trunc", 5), js_mkfun(builtin_Math_trunc)); 21386 + js_setprop(js, glob, js_mkstr(js, "Math", 4), math_obj); 21084 21387 21085 21388 jsval_t import_obj = mkobj(js, 0); 21086 21389 set_proto(js, import_obj, function_proto); 21087 21390 21088 21391 set_slot(js, import_obj, SLOT_CFUNC, js_mkfun(builtin_import)); 21089 - setprop(js, glob, js_mkstr(js, "import", 6), mkval(T_FUNC, vdata(import_obj))); 21392 + js_setprop(js, glob, js_mkstr(js, "import", 6), mkval(T_FUNC, vdata(import_obj))); 21090 21393 js->module_ns = js_mkundef(); 21091 21394 21092 - setprop(js, object_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(obj_func_obj))); 21395 + js_setprop(js, object_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(obj_func_obj))); 21093 21396 js_set_descriptor(js, object_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21094 21397 21095 - setprop(js, function_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(func_ctor_obj))); 21398 + js_setprop(js, function_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(func_ctor_obj))); 21096 21399 js_set_descriptor(js, function_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21097 21400 21098 - setprop(js, array_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(arr_ctor_obj))); 21401 + js_setprop(js, array_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(arr_ctor_obj))); 21099 21402 js_set_descriptor(js, array_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21100 21403 21101 - setprop(js, string_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(str_ctor_obj))); 21404 + js_setprop(js, string_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(str_ctor_obj))); 21102 21405 js_set_descriptor(js, string_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21103 21406 21104 - setprop(js, number_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(number_ctor_obj))); 21407 + js_setprop(js, number_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(number_ctor_obj))); 21105 21408 js_set_descriptor(js, number_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21106 21409 21107 - setprop(js, boolean_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(bool_ctor_obj))); 21410 + js_setprop(js, boolean_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(bool_ctor_obj))); 21108 21411 js_set_descriptor(js, boolean_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21109 21412 21110 - setprop(js, date_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(date_ctor_obj))); 21413 + js_setprop(js, date_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(date_ctor_obj))); 21111 21414 js_set_descriptor(js, date_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21112 21415 21113 - setprop(js, regexp_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(regex_ctor_obj))); 21416 + js_setprop(js, regexp_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(regex_ctor_obj))); 21114 21417 js_set_descriptor(js, regexp_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21115 21418 21116 21419 set_proto(js, glob, object_proto); 21117 21420 21421 + js->object = object_proto; 21118 21422 js->owns_mem = false; 21119 21423 js->max_size = 0; 21120 21424 ··· 21297 21601 return false; 21298 21602 } 21299 21603 21300 - jsval_t js_get(struct js *js, jsval_t obj, const char *key) { 21604 + static bool js_try_get(struct js *js, jsval_t obj, const char *key, jsval_t *out) { 21301 21605 size_t key_len = strlen(key); 21302 21606 21303 21607 if (vtype(obj) == T_FUNC) { 21304 21608 jsval_t func_obj = mkval(T_OBJ, vdata(obj)); 21305 21609 jsoff_t off = lkp(js, func_obj, key, key_len); 21306 - return off == 0 ? js_mkundef() : resolveprop(js, mkval(T_PROP, off)); 21610 + if (off == 0) return false; 21611 + *out = resolveprop(js, mkval(T_PROP, off)); 21612 + return true; 21307 21613 } 21308 21614 21309 21615 if (vtype(obj) == T_ARR) { 21310 21616 jsval_t arr_obj = mkval(T_OBJ, vdata(obj)); 21311 21617 jsoff_t off = lkp(js, arr_obj, key, key_len); 21312 - return off == 0 ? js_mkundef() : resolveprop(js, mkval(T_PROP, off)); 21618 + if (off == 0) return false; 21619 + *out = resolveprop(js, mkval(T_PROP, off)); 21620 + return true; 21313 21621 } 21314 21622 21315 21623 uint8_t t = vtype(obj); 21316 21624 bool is_promise = (t == T_PROMISE); 21317 21625 if (is_promise) obj = mkval(T_OBJ, vdata(obj)); 21318 - else if (t != T_OBJ) return js_mkundef(); 21626 + else if (t != T_OBJ) return false; 21319 21627 jsoff_t off = lkp(js, obj, key, key_len); 21320 21628 21321 21629 if (off == 0) { 21322 21630 jsval_t result = try_dynamic_getter(js, obj, key, key_len); 21323 - if (vtype(result) != T_UNDEF) return result; 21631 + if (vtype(result) != T_UNDEF) { *out = result; return true; } 21324 21632 } 21325 21633 21326 21634 if (off == 0 && is_promise) { 21327 21635 jsval_t promise_proto = get_ctor_proto(js, "Promise", 7); 21328 21636 if (vtype(promise_proto) != T_UNDEF && vtype(promise_proto) != T_NULL) { 21329 21637 off = lkp(js, promise_proto, key, key_len); 21330 - if (off != 0) return resolveprop(js, mkval(T_PROP, off)); 21638 + if (off != 0) { *out = resolveprop(js, mkval(T_PROP, off)); return true; } 21331 21639 } 21332 21640 } 21333 21641 21334 - return off == 0 ? js_mkundef() : resolveprop(js, mkval(T_PROP, off)); 21642 + if (off == 0) return false; 21643 + *out = resolveprop(js, mkval(T_PROP, off)); 21644 + return true; 21645 + } 21646 + 21647 + jsval_t js_get(struct js *js, jsval_t obj, const char *key) { 21648 + jsval_t val; 21649 + if (js_try_get(js, obj, key, &val)) return val; 21650 + return js_mkundef(); 21335 21651 } 21336 21652 21337 21653 jsval_t js_getprop_proto(struct js *js, jsval_t obj, const char *key) { ··· 21340 21656 return off == 0 ? js_mkundef() : resolveprop(js, mkval(T_PROP, off)); 21341 21657 } 21342 21658 21659 + jsval_t js_getprop_fallback(struct js *js, jsval_t obj, const char *name) { 21660 + jsval_t val; 21661 + if (js_try_get(js, obj, name, &val)) return val; 21662 + return js_getprop_proto(js, obj, name); 21663 + } 21664 + 21343 21665 typedef struct { 21344 21666 bool (*callback)(struct js *js, jsval_t value, void *udata); 21345 21667 void *udata; 21346 21668 } js_iter_ctx_t; 21347 21669 21348 21670 static iter_action_t js_iter_cb(struct js *js, jsval_t value, void *ctx, jsval_t *out) { 21349 - (void)out; 21350 21671 js_iter_ctx_t *ictx = (js_iter_ctx_t *)ctx; 21351 21672 return ictx->callback(js, value, ictx->udata) ? ITER_CONTINUE : ITER_BREAK; 21352 21673 } ··· 21374 21695 jsoff_t koff = loadoff(js, next + (jsoff_t) sizeof(next)); 21375 21696 jsval_t val = loadval(js, next + (jsoff_t) (sizeof(next) + sizeof(koff))); 21376 21697 21377 - setprop(js, dst, mkval(T_STR, koff), val); 21698 + js_setprop(js, dst, mkval(T_STR, koff), val); 21378 21699 next = next_prop(header); 21379 21700 } 21380 21701 } ··· 21490 21811 op_val(c, &c->js->for_let_stack[i].body_scope); 21491 21812 op_off(c, &c->js->for_let_stack[i].prop_off); 21492 21813 } 21814 + 21815 + op_val(c, &c->js->object); 21816 + op_val(c, &c->js->tval); 21817 + op_val(c, &c->js->scope); 21818 + op_val(c, &c->js->this_val); 21819 + op_val(c, &c->js->super_val); 21820 + op_val(c, &c->js->new_target); 21821 + op_val(c, &c->js->module_ns); 21822 + op_val(c, &c->js->current_func); 21823 + op_val(c, &c->js->thrown_value); 21493 21824 21494 21825 for (jshdl_t i = 0; i < c->js->gc_roots_len; i++) op_val(c, &c->js->gc_roots[i]); 21495 21826 if (c->js->ascii_cache_init) for (int i = 0; i < 128; i++) op_val(c, &c->js->ascii_char_cache[i]); ··· 21787 22118 if (vtype(v) == T_UNDEF && pp->default_len > 0) { 21788 22119 v = js_eval_str(js, &fn[pp->default_start], pp->default_len); 21789 22120 } 21790 - setprop(js, js->scope, js_mkstr(js, &fn[pp->name_off], pp->name_len), v); 22121 + js_setprop(js, js->scope, js_mkstr(js, &fn[pp->name_off], pp->name_len), v); 21791 22122 } 21792 22123 } 21793 22124 ··· 21799 22130 char idxstr[16]; 21800 22131 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)idx); 21801 22132 jsval_t key = js_mkstr(js, idxstr, idxlen); 21802 - setprop(js, rest_array, key, final_args[arg_idx]); 22133 + js_setprop(js, rest_array, key, final_args[arg_idx]); 21803 22134 idx++; 21804 22135 arg_idx++; 21805 22136 } 21806 22137 jsval_t len_key = js_mkstr(js, "length", 6); 21807 - setprop(js, rest_array, len_key, tov((double) idx)); 22138 + js_setprop(js, rest_array, len_key, tov((double) idx)); 21808 22139 rest_array = mkval(T_ARR, vdata(rest_array)); 21809 - setprop(js, js->scope, js_mkstr(js, &fn[pf->rest_param_start], pf->rest_param_len), rest_array); 22140 + js_setprop(js, js->scope, js_mkstr(js, &fn[pf->rest_param_start], pf->rest_param_len), rest_array); 21810 22141 } 21811 22142 } 21812 22143 ··· 21942 22273 jsoff_t js_loadoff(struct js *js, jsoff_t off) { return loadoff(js, off); } 21943 22274 21944 22275 void js_set_getter(struct js *js, jsval_t obj, js_getter_fn getter) { 21945 - if (vtype(obj) != T_OBJ) return; 22276 + if (!is_object_type(obj)) return; 22277 + if (vtype(obj) != T_OBJ) obj = mkval(T_OBJ, vdata(obj)); 21946 22278 jsoff_t obj_off = (jsoff_t)vdata(obj); 21947 22279 dynamic_accessors_t *entry = NULL; 21948 22280 HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), entry); ··· 21952 22284 entry->obj_offset = obj_off; 21953 22285 entry->getter = NULL; 21954 22286 entry->setter = NULL; 22287 + entry->keys = NULL; 21955 22288 HASH_ADD(hh, accessor_registry, obj_offset, sizeof(jsoff_t), entry); 21956 22289 } 21957 22290 entry->getter = getter; 21958 22291 } 21959 22292 21960 22293 void js_set_setter(struct js *js, jsval_t obj, js_setter_fn setter) { 21961 - if (vtype(obj) != T_OBJ) return; 22294 + if (!is_object_type(obj)) return; 22295 + if (vtype(obj) != T_OBJ) obj = mkval(T_OBJ, vdata(obj)); 21962 22296 jsoff_t obj_off = (jsoff_t)vdata(obj); 21963 22297 dynamic_accessors_t *entry = NULL; 21964 22298 HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), entry); ··· 21968 22302 entry->obj_offset = obj_off; 21969 22303 entry->getter = NULL; 21970 22304 entry->setter = NULL; 22305 + entry->keys = NULL; 21971 22306 HASH_ADD(hh, accessor_registry, obj_offset, sizeof(jsoff_t), entry); 21972 22307 } 21973 22308 entry->setter = setter; 22309 + } 22310 + 22311 + void js_set_keys(struct js *js, jsval_t obj, js_keys_fn keys) { 22312 + if (!is_object_type(obj)) return; 22313 + if (vtype(obj) != T_OBJ) obj = mkval(T_OBJ, vdata(obj)); 22314 + jsoff_t obj_off = (jsoff_t)vdata(obj); 22315 + dynamic_accessors_t *entry = NULL; 22316 + HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), entry); 22317 + if (!entry) { 22318 + entry = (dynamic_accessors_t *)malloc(sizeof(dynamic_accessors_t)); 22319 + if (!entry) return; 22320 + entry->obj_offset = obj_off; 22321 + entry->getter = NULL; 22322 + entry->setter = NULL; 22323 + entry->keys = NULL; 22324 + HASH_ADD(hh, accessor_registry, obj_offset, sizeof(jsoff_t), entry); 22325 + } 22326 + entry->keys = keys; 21974 22327 } 21975 22328 21976 22329 static inline uint64_t make_desc_key(jsoff_t obj_off, const char *key, size_t klen) {
+28 -8
src/modules/buffer.c
··· 520 520 } 521 521 522 522 size_t element_size = get_element_size(type); 523 + 524 + if (byte_offset > buffer->length) { 525 + return js_mkerr(js, "Start offset is outside the bounds of the buffer"); 526 + } 527 + 523 528 if (nargs > 2 && vtype(args[2]) == T_NUM) { 524 529 length = (size_t)js_getnum(args[2]); 525 - } else { 526 - length = (buffer->length - byte_offset) / element_size; 527 - } 530 + size_t available = buffer->length - byte_offset; 531 + if (length > available / element_size) { 532 + return js_mkerr(js, "Invalid TypedArray length"); 533 + } 534 + } else length = (buffer->length - byte_offset) / element_size; 528 535 529 536 return create_typed_array_with_buffer(js, type, buffer, byte_offset, length, type_name, args[0]); 530 537 } ··· 894 901 byte_offset = (size_t)js_getnum(args[1]); 895 902 } 896 903 904 + if (byte_offset > buffer->length) { 905 + return js_mkerr(js, "Start offset is outside the bounds of the buffer"); 906 + } 907 + 897 908 if (nargs > 2 && vtype(args[2]) == T_NUM) { 898 909 byte_length = (size_t)js_getnum(args[2]); 899 - } else { 900 - byte_length = buffer->length - byte_offset; 901 - } 910 + if (byte_length > buffer->length - byte_offset) { 911 + return js_mkerr(js, "Invalid DataView length"); 912 + } 913 + } else byte_length = buffer->length - byte_offset; 902 914 903 915 DataViewData *dv_data = ta_arena_alloc(sizeof(DataViewData)); 904 916 if (!dv_data) return js_mkerr(js, "Failed to allocate DataView"); ··· 1659 1671 } 1660 1672 1661 1673 void init_buffer_module() { 1662 - struct js *js = rt->js; 1663 - jsval_t glob = js_glob(js); 1674 + ant_t *js = rt->js; 1664 1675 1676 + jsval_t glob = js->global; 1677 + jsval_t object_proto = js->object; 1678 + 1665 1679 jsval_t arraybuffer_ctor_obj = js_mkobj(js); 1666 1680 jsval_t arraybuffer_proto = js_mkobj(js); 1681 + js_set_proto(js, arraybuffer_proto, object_proto); 1667 1682 1668 1683 js_set(js, arraybuffer_proto, "slice", js_mkfun(js_arraybuffer_slice)); 1669 1684 js_set(js, arraybuffer_proto, "transfer", js_mkfun(js_arraybuffer_transfer)); ··· 1678 1693 js_set(js, glob, "ArrayBuffer", js_obj_to_func(arraybuffer_ctor_obj)); 1679 1694 1680 1695 jsval_t typedarray_proto = js_mkobj(js); 1696 + js_set_proto(js, typedarray_proto, object_proto); 1697 + 1681 1698 js_set(js, typedarray_proto, "slice", js_mkfun(js_typedarray_slice)); 1682 1699 js_set(js, typedarray_proto, "subarray", js_mkfun(js_typedarray_subarray)); 1683 1700 js_set(js, typedarray_proto, "fill", js_mkfun(js_typedarray_fill)); ··· 1710 1727 1711 1728 jsval_t dataview_ctor_obj = js_mkobj(js); 1712 1729 jsval_t dataview_proto = js_mkobj(js); 1730 + js_set_proto(js, dataview_proto, object_proto); 1713 1731 1714 1732 js_set(js, dataview_proto, "getUint8", js_mkfun(js_dataview_getUint8)); 1715 1733 js_set(js, dataview_proto, "setUint8", js_mkfun(js_dataview_setUint8)); ··· 1731 1749 1732 1750 jsval_t sharedarraybuffer_ctor_obj = js_mkobj(js); 1733 1751 jsval_t sharedarraybuffer_proto = js_mkobj(js); 1752 + js_set_proto(js, sharedarraybuffer_proto, object_proto); 1734 1753 1735 1754 js_set(js, sharedarraybuffer_proto, "slice", js_mkfun(js_arraybuffer_slice)); 1736 1755 js_set(js, sharedarraybuffer_proto, get_toStringTag_sym_key(), js_mkstr(js, "SharedArrayBuffer", 17)); ··· 1743 1762 1744 1763 jsval_t buffer_ctor_obj = js_mkobj(js); 1745 1764 jsval_t buffer_proto = js_mkobj(js); 1765 + js_set_proto(js, buffer_proto, object_proto); 1746 1766 1747 1767 js_set(js, buffer_proto, "toString", js_mkfun(js_buffer_toString)); 1748 1768 js_set(js, buffer_proto, "toBase64", js_mkfun(js_buffer_toBase64));
+16 -8
src/modules/collections.c
··· 675 675 676 676 char idx[16]; 677 677 size_t idx_len = uint_to_str(idx, sizeof(idx), 0); 678 - setprop(js, entry, js_mkstr(js, idx, idx_len), target); 678 + js_setprop(js, entry, js_mkstr(js, idx, idx_len), target); 679 679 idx_len = uint_to_str(idx, sizeof(idx), 1); 680 - setprop(js, entry, js_mkstr(js, idx, idx_len), held_value); 680 + js_setprop(js, entry, js_mkstr(js, idx, idx_len), held_value); 681 681 idx_len = uint_to_str(idx, sizeof(idx), 2); 682 - setprop(js, entry, js_mkstr(js, idx, idx_len), unregister_token); 683 - setprop(js, entry, js_mkstr(js, "length", 6), tov(3.0)); 682 + js_setprop(js, entry, js_mkstr(js, idx, idx_len), unregister_token); 683 + js_setprop(js, entry, js_mkstr(js, "length", 6), tov(3.0)); 684 684 685 685 idx_len = uint_to_str(idx, sizeof(idx), len); 686 - setprop(js, registrations, js_mkstr(js, idx, idx_len), entry); 687 - setprop(js, registrations, js_mkstr(js, "length", 6), tov((double)(len + 1))); 686 + js_setprop(js, registrations, js_mkstr(js, idx, idx_len), entry); 687 + js_setprop(js, registrations, js_mkstr(js, "length", 6), tov((double)(len + 1))); 688 688 689 689 return js_mkundef(); 690 690 } ··· 711 711 if (vtype(entry_token) == T_OBJ && vdata(entry_token) == vdata(token)) { 712 712 char idx[16]; 713 713 size_t idx_len = uint_to_str(idx, sizeof(idx), i); 714 - setprop(js, registrations, js_mkstr(js, idx, idx_len), js_mkundef()); 714 + js_setprop(js, registrations, js_mkstr(js, idx, idx_len), js_mkundef()); 715 715 removed = true; 716 716 } 717 717 } ··· 886 886 887 887 void init_collections_module(void) { 888 888 ant_t *js = rt->js; 889 - jsval_t glob = js_glob(js); 889 + 890 + jsval_t glob = js->global; 891 + jsval_t object_proto = js->object; 890 892 891 893 const char *iter_key = get_iterator_sym_key(); 892 894 const char *toStringTag_key = get_toStringTag_sym_key(); 893 895 894 896 jsval_t map_proto = js_mkobj(js); 897 + js_set_proto(js, map_proto, object_proto); 895 898 js_set(js, map_proto, "set", js_mkfun(map_set)); 896 899 js_set(js, map_proto, "get", js_mkfun(map_get)); 897 900 js_set(js, map_proto, "has", js_mkfun(map_has)); ··· 913 916 js_set(js, glob, "Map", js_obj_to_func(map_ctor)); 914 917 915 918 jsval_t set_proto = js_mkobj(js); 919 + js_set_proto(js, set_proto, object_proto); 916 920 js_set(js, set_proto, "add", js_mkfun(set_add)); 917 921 js_set(js, set_proto, "has", js_mkfun(set_has)); 918 922 js_set(js, set_proto, "delete", js_mkfun(set_delete)); ··· 933 937 js_set(js, glob, "Set", js_obj_to_func(set_ctor)); 934 938 935 939 jsval_t weakmap_proto = js_mkobj(js); 940 + js_set_proto(js, weakmap_proto, object_proto); 936 941 js_set(js, weakmap_proto, "set", js_mkfun(weakmap_set)); 937 942 js_set(js, weakmap_proto, "get", js_mkfun(weakmap_get)); 938 943 js_set(js, weakmap_proto, "has", js_mkfun(weakmap_has)); ··· 947 952 js_set(js, glob, "WeakMap", js_obj_to_func(weakmap_ctor)); 948 953 949 954 jsval_t weakset_proto = js_mkobj(js); 955 + js_set_proto(js, weakset_proto, object_proto); 950 956 js_set(js, weakset_proto, "add", js_mkfun(weakset_add)); 951 957 js_set(js, weakset_proto, "has", js_mkfun(weakset_has)); 952 958 js_set(js, weakset_proto, "delete", js_mkfun(weakset_delete)); ··· 960 966 js_set(js, glob, "WeakSet", js_obj_to_func(weakset_ctor)); 961 967 962 968 jsval_t weakref_proto = js_mkobj(js); 969 + js_set_proto(js, weakref_proto, object_proto); 963 970 js_set(js, weakref_proto, "deref", js_mkfun(weakref_deref)); 964 971 js_set(js, weakref_proto, toStringTag_key, js_mkstr(js, "WeakRef", 7)); 965 972 ··· 971 978 js_set(js, glob, "WeakRef", js_obj_to_func(weakref_ctor)); 972 979 973 980 jsval_t finreg_proto = js_mkobj(js); 981 + js_set_proto(js, finreg_proto, object_proto); 974 982 js_set(js, finreg_proto, "register", js_mkfun(finreg_register)); 975 983 js_set(js, finreg_proto, "unregister", js_mkfun(finreg_unregister)); 976 984 js_set(js, finreg_proto, toStringTag_key, js_mkstr(js, "FinalizationRegistry", 20));
+123 -17
src/modules/process.c
··· 31 31 #include "config.h" 32 32 #include "internal.h" 33 33 #include "runtime.h" 34 + #include "utils.h" 34 35 35 36 #include "modules/process.h" 36 37 #include "modules/symbol.h" ··· 1264 1265 } 1265 1266 #endif 1266 1267 1267 - static jsval_t env_getter(ant_t *js, jsval_t obj, const char *key, size_t key_len) { 1268 - char *key_str = (char *)malloc(key_len + 1); 1268 + static jsval_t env_getter(ant_t *js, jsval_t obj, const char *key, size_t key_len) { 1269 + CSTR_BUF(buf, 256); 1270 + char *key_str = CSTR_INIT(buf, key, key_len); 1269 1271 if (!key_str) return js_mkundef(); 1270 1272 1271 - memcpy(key_str, key, key_len); 1272 - key_str[key_len] = '\0'; 1273 - 1274 1273 char *value = getenv(key_str); 1275 - free(key_str); 1274 + cstr_free(&buf); 1276 1275 1277 1276 if (value == NULL) return js_mkundef(); 1278 1277 return js_mkstr(js, value, strlen(value)); 1278 + } 1279 + 1280 + static bool env_setter(ant_t *js, jsval_t obj, const char *key, size_t key_len, jsval_t value) { 1281 + jsval_t str_val = coerce_to_str(js, value); 1282 + if (is_err(str_val)) return false; 1283 + setprop_cstr(js, obj, key, key_len, str_val); 1284 + 1285 + CSTR_BUF(buf, 256); 1286 + char *key_str = CSTR_INIT(buf, key, key_len); 1287 + if (key_str) { 1288 + size_t val_len; 1289 + char *val_str = js_getstr(js, str_val, &val_len); 1290 + if (val_str) setenv(key_str, val_str, 1); 1291 + cstr_free(&buf); 1292 + } 1293 + 1294 + return true; 1279 1295 } 1280 1296 1281 1297 static void load_dotenv_file(ant_t *js, jsval_t env_obj) { ··· 1340 1356 return js_mkundef(); 1341 1357 } 1342 1358 1343 - static jsval_t env_to_object(ant_t *js, jsval_t *args, int nargs) { 1344 - jsval_t obj = js_mkobj(js); 1345 - 1359 + typedef struct { 1360 + char *buf; 1361 + size_t pos; 1362 + size_t cap; 1363 + } env_str_ctx; 1364 + 1365 + typedef void (*env_iter_cb)( 1366 + ant_t *js, 1367 + const char *key, 1368 + size_t key_len, 1369 + const char *value, 1370 + size_t val_len, 1371 + void *ctx 1372 + ); 1373 + 1374 + static void env_foreach(ant_t *js, jsval_t env_obj, env_iter_cb cb, void *ctx) { 1346 1375 for (char **env = environ; *env != NULL; env++) { 1347 1376 char *entry = *env; 1348 1377 char *equals = strchr(entry, '='); ··· 1350 1379 1351 1380 size_t key_len = (size_t)(equals - entry); 1352 1381 char *value = equals + 1; 1382 + cb(js, entry, key_len, value, strlen(value), ctx); 1383 + } 1384 + 1385 + ant_iter_t iter = js_prop_iter_begin(js, env_obj); 1386 + const char *key; size_t key_len; jsval_t value; 1387 + 1388 + while (js_prop_iter_next(&iter, &key, &key_len, &value)) { 1389 + if (key_len >= 2 && key[0] == '_' && key[1] == '_') continue; 1390 + if (vtype(value) != T_STR) continue; 1353 1391 1354 - char *key = malloc(key_len + 1); 1355 - if (!key) continue; 1356 - memcpy(key, entry, key_len); 1357 - key[key_len] = '\0'; 1392 + CSTR_BUF(buf, 256); 1393 + char *key_str = CSTR_INIT(buf, key, key_len); 1394 + if (!key_str) continue; 1395 + 1396 + if (getenv(key_str)) { 1397 + cstr_free(&buf); 1398 + continue; 1399 + } cstr_free(&buf); 1358 1400 1359 - js_set(js, obj, key, js_mkstr(js, value, strlen(value))); 1360 - free(key); 1401 + size_t val_len; 1402 + char *val_str = js_getstr(js, value, &val_len); 1403 + cb(js, key, key_len, val_str ? val_str : "", val_str ? val_len : 0, ctx); 1361 1404 } 1362 1405 1406 + js_prop_iter_end(&iter); 1407 + } 1408 + 1409 + static void env_to_object_cb(ant_t *js, const char *key, size_t key_len, const char *value, size_t val_len, void *ctx) { 1410 + jsval_t obj = *(jsval_t *)ctx; 1411 + CSTR_BUF(buf, 256); 1412 + char *key_str = CSTR_INIT(buf, key, key_len); 1413 + if (!key_str) return; 1414 + js_set(js, obj, key_str, js_mkstr(js, value, val_len)); 1415 + cstr_free(&buf); 1416 + } 1417 + 1418 + static jsval_t env_to_object(ant_t *js, jsval_t *args, int nargs) { 1419 + jsval_t obj = js_mkobj(js); 1420 + env_foreach(js, js->this_val, env_to_object_cb, &obj); 1363 1421 return obj; 1422 + } 1423 + 1424 + static void env_tostring_cb(ant_t *js, const char *key, size_t key_len, const char *value, size_t val_len, void *ctx) { 1425 + env_str_ctx *c = ctx; 1426 + size_t entry_len = key_len + 1 + val_len; 1427 + 1428 + if (c->pos + entry_len + 2 >= c->cap) { 1429 + size_t new_cap = c->cap * 2 + entry_len; 1430 + char *new_buf = realloc(c->buf, new_cap); 1431 + if (!new_buf) return; 1432 + c->buf = new_buf; 1433 + c->cap = new_cap; 1434 + } 1435 + 1436 + if (c->pos > 0) c->buf[c->pos++] = '\n'; 1437 + memcpy(c->buf + c->pos, key, key_len); 1438 + c->pos += key_len; 1439 + c->buf[c->pos++] = '='; 1440 + memcpy(c->buf + c->pos, value, val_len); 1441 + c->pos += val_len; 1442 + } 1443 + 1444 + static jsval_t env_toString(ant_t *js, jsval_t *args, int nargs) { 1445 + env_str_ctx ctx = { .buf = malloc(4096), .pos = 0, .cap = 4096 }; 1446 + if (!ctx.buf) return js_mkstr(js, "", 0); 1447 + 1448 + env_foreach(js, js->this_val, env_tostring_cb, &ctx); 1449 + ctx.buf[ctx.pos] = '\0'; 1450 + 1451 + jsval_t ret = js_mkstr(js, ctx.buf, ctx.pos); 1452 + free(ctx.buf); 1453 + return ret; 1454 + } 1455 + 1456 + static void env_keys_cb(ant_t *js, const char *key, size_t key_len, const char *value, size_t val_len, void *ctx) { 1457 + jsval_t arr = *(jsval_t *)ctx; 1458 + js_arr_push(js, arr, js_mkstr(js, key, key_len)); 1459 + } 1460 + 1461 + static jsval_t env_keys(ant_t *js, jsval_t obj) { 1462 + jsval_t arr = js_mkarr(js); 1463 + env_foreach(js, obj, env_keys_cb, &arr); 1464 + return arr; 1364 1465 } 1365 1466 1366 1467 static jsval_t process_cwd(ant_t *js, jsval_t *args, int nargs) { ··· 1565 1666 js_set(js, process_proto, get_toStringTag_sym_key(), js_mkstr(js, "process", 7)); 1566 1667 1567 1668 jsval_t process_obj = js_mkobj(js); 1669 + jsval_t env_obj = js_mkobj(js); 1568 1670 js_set_proto(js, process_obj, process_proto); 1569 - 1570 - jsval_t env_obj = js_mkobj(js); 1671 + 1571 1672 load_dotenv_file(js, env_obj); 1673 + js_set_keys(js, env_obj, env_keys); 1674 + 1572 1675 js_set_getter(js, env_obj, env_getter); 1676 + js_set_setter(js, env_obj, env_setter); 1677 + 1573 1678 js_set(js, env_obj, "toObject", js_mkfun(env_to_object)); 1679 + js_set(js, env_obj, "toString", js_mkfun(env_toString)); 1574 1680 js_set(js, process_obj, "env", env_obj); 1575 1681 1576 1682 jsval_t argv_arr = js_mkarr(js);
+104 -45
src/modules/symbol.c
··· 8 8 #include "internal.h" 9 9 #include "modules/symbol.h" 10 10 11 - static jsval_t g_iterator_sym = 0; 12 - static jsval_t g_asyncIterator_sym = 0; 13 - static jsval_t g_toStringTag_sym = 0; 14 - static jsval_t g_hasInstance_sym = 0; 15 - static jsval_t g_observable_sym = 0; 11 + typedef struct { 12 + jsval_t sym; 13 + char key[32]; 14 + } wellknown_sym_t; 15 + 16 + static wellknown_sym_t g_iterator = {0}; 17 + static wellknown_sym_t g_asyncIterator = {0}; 18 + static wellknown_sym_t g_toStringTag = {0}; 19 + static wellknown_sym_t g_hasInstance = {0}; 20 + static wellknown_sym_t g_observable = {0}; 21 + static wellknown_sym_t g_toPrimitive = {0}; 16 22 17 - static char g_iter_sym_key[32] = {0}; 18 - static char g_asyncIter_sym_key[32] = {0}; 19 - static char g_toStringTag_sym_key[32] = {0}; 20 - static char g_observable_sym_key[32] = {0}; 23 + jsval_t get_iterator_symbol(void) { return g_iterator.sym; } 24 + jsval_t get_asyncIterator_symbol(void) { return g_asyncIterator.sym; } 25 + jsval_t get_observable_symbol(void) { return g_observable.sym; } 26 + 27 + const char *get_iterator_sym_key(void) { return g_iterator.key; } 28 + const char *get_asyncIterator_sym_key(void) { return g_asyncIterator.key; } 29 + const char *get_toStringTag_sym_key(void) { return g_toStringTag.key; } 30 + const char *get_observable_sym_key(void) { return g_observable.key; } 31 + const char *get_toPrimitive_sym_key(void) { return g_toPrimitive.key; } 32 + const char *get_hasInstance_sym_key(void) { return g_hasInstance.key; } 33 + 34 + static const struct { jsval_t *sym; const char *name; } sym_table[] = { 35 + { &g_iterator.sym, "Symbol.iterator" }, 36 + { &g_asyncIterator.sym, "Symbol.asyncIterator" }, 37 + { &g_toStringTag.sym, "Symbol.toStringTag" }, 38 + { &g_hasInstance.sym, "Symbol.hasInstance" }, 39 + { &g_observable.sym, "Symbol.observable" }, 40 + { &g_toPrimitive.sym, "Symbol.toPrimitive" }, 41 + }; 21 42 22 - jsval_t get_iterator_symbol(void) { return g_iterator_sym; } 23 - jsval_t get_asyncIterator_symbol(void) { return g_asyncIterator_sym; } 24 - jsval_t get_observable_symbol(void) { return g_observable_sym; } 43 + const char *get_symbol_description_from_key(const char *sym_key, size_t key_len) { 44 + if (key_len < 9 || memcmp(sym_key, "__sym_", 6) != 0) return NULL; 45 + 46 + uint64_t id = 0; 47 + for (const char *p = sym_key + 6; *p >= '0' && *p <= '9'; p++) id = id * 10 + (*p - '0'); 48 + 49 + for (size_t i = 0; i < sizeof(sym_table) / sizeof(sym_table[0]); i++) { 50 + if (js_sym_id(*sym_table[i].sym) == id) return sym_table[i].name; 51 + } 52 + 53 + return "Symbol()"; 54 + } 25 55 26 - const char *get_iterator_sym_key(void) { return g_iter_sym_key; } 27 - const char *get_asyncIterator_sym_key(void) { return g_asyncIter_sym_key; } 28 - const char *get_toStringTag_sym_key(void) { return g_toStringTag_sym_key; } 29 - const char *get_observable_sym_key(void) { return g_observable_sym_key; } 56 + static inline void init_symbol(struct js *js, wellknown_sym_t *sym_var, const char *name) { 57 + sym_var->sym = js_mksym(js, name); 58 + snprintf(sym_var->key, sizeof(sym_var->key), "__sym_%llu__", (unsigned long long)js_sym_id(sym_var->sym)); 59 + } 30 60 31 61 static jsval_t builtin_Symbol(struct js *js, jsval_t *args, int nargs) { 32 62 const char *desc = NULL; ··· 58 88 return js_mkstr(js, key, strlen(key)); 59 89 } 60 90 91 + static jsval_t builtin_Symbol_toString(struct js *js, jsval_t *args, int nargs) { 92 + jsval_t this_val = js_getthis(js); 93 + 94 + if (vtype(this_val) != T_SYMBOL) { 95 + return js_mkerr(js, "Symbol.prototype.toString requires a symbol"); 96 + } 97 + 98 + return js_symbol_to_string(js, this_val); 99 + } 100 + 61 101 static jsval_t iterator_next(struct js *js, jsval_t *args, int nargs) { 62 - (void)args; (void)nargs; 63 102 jsval_t this_val = js_getthis(js); 64 103 65 104 jsval_t arr = js_get(js, this_val, "__arr"); ··· 87 126 } 88 127 89 128 static jsval_t array_iterator(struct js *js, jsval_t *args, int nargs) { 90 - (void)args; (void)nargs; 91 129 jsval_t arr = js_getthis(js); 92 130 93 131 jsval_t len_val = js_get(js, arr, "length"); ··· 103 141 } 104 142 105 143 static jsval_t string_iterator_next(struct js *js, jsval_t *args, int nargs) { 106 - (void)args; (void)nargs; 107 144 jsval_t this_val = js_getthis(js); 108 145 109 146 jsval_t str = js_get(js, this_val, "__str"); ··· 145 182 return iter; 146 183 } 147 184 148 - const char *get_symbol_description_from_key(const char *sym_key, size_t key_len) { 149 - if ( 150 - key_len < 9 || sym_key[0] != '_' || sym_key[1] != '_' || 151 - sym_key[2] != 's' || sym_key[3] != 'y' || sym_key[4] != 'm' || sym_key[5] != '_' 152 - ) return NULL; 185 + static jsval_t date_toPrimitive(struct js *js, jsval_t *args, int nargs) { 186 + jsval_t this_val = js_getthis(js); 187 + 188 + const char *hint = "default"; 189 + if (nargs > 0 && vtype(args[0]) == T_STR) { 190 + hint = js_getstr(js, args[0], NULL); 191 + } bool prefer_string = (hint == NULL || strcmp(hint, "number") != 0); 192 + 193 + const char *methods[2] = { 194 + prefer_string ? "toString" : "valueOf", 195 + prefer_string ? "valueOf" : "toString" 196 + }; 153 197 154 - if (g_iter_sym_key[0] && strncmp(sym_key, g_iter_sym_key, key_len) == 0 && g_iter_sym_key[key_len] == '\0') return "Symbol.iterator"; 155 - if (g_toStringTag_sym_key[0] && strncmp(sym_key, g_toStringTag_sym_key, key_len) == 0 && g_toStringTag_sym_key[key_len] == '\0') return "Symbol.toStringTag"; 198 + for (int i = 0; i < 2; i++) { 199 + jsval_t method = js_getprop_fallback(js, this_val, methods[i]); 200 + if (vtype(method) == T_FUNC || vtype(method) == T_CFUNC) { 201 + jsval_t result = js_call_with_this(js, method, this_val, NULL, 0); 202 + if (is_err(result) || !is_object_type(result)) return result; 203 + } 204 + } 156 205 157 - return "Symbol()"; 206 + return js_mkerr(js, "Cannot convert object to primitive value"); 158 207 } 159 208 209 + 160 210 void init_symbol_module(void) { 161 211 struct js *js = rt->js; 162 212 163 - g_iterator_sym = js_mksym(js, "Symbol.iterator"); 164 - g_asyncIterator_sym = js_mksym(js, "Symbol.asyncIterator"); 165 - g_toStringTag_sym = js_mksym(js, "Symbol.toStringTag"); 166 - g_hasInstance_sym = js_mksym(js, "Symbol.hasInstance"); 167 - g_observable_sym = js_mksym(js, "Symbol.observable"); 168 - 169 - snprintf(g_iter_sym_key, sizeof(g_iter_sym_key), "__sym_%llu__", (unsigned long long)js_sym_id(g_iterator_sym)); 170 - snprintf(g_asyncIter_sym_key, sizeof(g_asyncIter_sym_key), "__sym_%llu__", (unsigned long long)js_sym_id(g_asyncIterator_sym)); 171 - snprintf(g_toStringTag_sym_key, sizeof(g_toStringTag_sym_key), "__sym_%llu__", (unsigned long long)js_sym_id(g_toStringTag_sym)); 172 - snprintf(g_observable_sym_key, sizeof(g_observable_sym_key), "__sym_%llu__", (unsigned long long)js_sym_id(g_observable_sym)); 213 + init_symbol(js, &g_iterator, "Symbol.iterator"); 214 + init_symbol(js, &g_asyncIterator, "Symbol.asyncIterator"); 215 + init_symbol(js, &g_toStringTag, "Symbol.toStringTag"); 216 + init_symbol(js, &g_observable, "Symbol.observable"); 217 + init_symbol(js, &g_toPrimitive, "Symbol.toPrimitive"); 218 + init_symbol(js, &g_hasInstance, "Symbol.hasInstance"); 219 + 220 + jsval_t symbol_proto = js_mkobj(js); 221 + js_set(js, symbol_proto, "toString", js_mkfun(builtin_Symbol_toString)); 173 222 174 223 jsval_t symbol_ctor = js_mkobj(js); 175 224 js_set_slot(js, symbol_ctor, SLOT_CFUNC, js_mkfun(builtin_Symbol)); 176 225 js_setprop(js, symbol_ctor, js_mkstr(js, "for", 3), js_mkfun(builtin_Symbol_for)); 177 226 js_set(js, symbol_ctor, "keyFor", js_mkfun(builtin_Symbol_keyFor)); 227 + js_set(js, symbol_ctor, "prototype", symbol_proto); 178 228 179 - js_set(js, symbol_ctor, "iterator", g_iterator_sym); 180 - js_set(js, symbol_ctor, "asyncIterator", g_asyncIterator_sym); 181 - js_set(js, symbol_ctor, "toStringTag", g_toStringTag_sym); 182 - js_set(js, symbol_ctor, "hasInstance", g_hasInstance_sym); 183 - js_set(js, symbol_ctor, "observable", g_observable_sym); 229 + js_set(js, symbol_ctor, "iterator", g_iterator.sym); 230 + js_set(js, symbol_ctor, "asyncIterator", g_asyncIterator.sym); 231 + js_set(js, symbol_ctor, "toStringTag", g_toStringTag.sym); 232 + js_set(js, symbol_ctor, "hasInstance", g_hasInstance.sym); 233 + js_set(js, symbol_ctor, "observable", g_observable.sym); 234 + js_set(js, symbol_ctor, "toPrimitive", g_toPrimitive.sym); 184 235 185 236 jsval_t func_symbol = js_obj_to_func(symbol_ctor); 186 237 js_set(js, js_glob(js), "Symbol", func_symbol); 187 238 188 - // set internal types before module ready 239 + // set internal types before ant module snapshot 189 240 js_set(js, rt->ant_obj, get_toStringTag_sym_key(), js_mkstr(js, "Ant", 3)); 190 241 191 242 jsval_t array_ctor = js_get(js, js_glob(js), "Array"); 192 243 jsval_t array_proto = js_get(js, array_ctor, "prototype"); 193 - js_set(js, array_proto, g_iter_sym_key, js_mkfun(array_iterator)); 244 + js_set(js, array_proto, g_iterator.key, js_mkfun(array_iterator)); 194 245 195 246 jsval_t string_ctor = js_get(js, js_glob(js), "String"); 196 247 jsval_t string_proto = js_get(js, string_ctor, "prototype"); 197 - js_set(js, string_proto, g_iter_sym_key, js_mkfun(string_iterator)); 248 + js_set(js, string_proto, g_iterator.key, js_mkfun(string_iterator)); 249 + 250 + jsval_t date_ctor = js_get(js, js_glob(js), "Date"); 251 + jsval_t date_proto = js_get(js, date_ctor, "prototype"); 252 + js_set(js, date_proto, g_toPrimitive.key, js_mkfun(date_toPrimitive)); 253 + 254 + jsval_t promise_ctor = js_get(js, js_glob(js), "Promise"); 255 + jsval_t promise_proto = js_get(js, promise_ctor, "prototype"); 256 + js_set(js, promise_proto, g_toStringTag.key, js_mkstr(js, "Promise", 7)); 198 257 }
+42 -52
src/repl.c
··· 416 416 } while (1); 417 417 } 418 418 419 + typedef struct { 420 + int paren, bracket, brace; 421 + int *templates; 422 + int template_count, template_cap; 423 + char string_char; 424 + bool in_string, escaped; 425 + } parse_state_t; 426 + 427 + static void push_template(parse_state_t *s) { 428 + if (s->template_count >= s->template_cap) { 429 + s->template_cap = s->template_cap ? s->template_cap * 2 : 8; 430 + int *new_templates = realloc(s->templates, s->template_cap * sizeof(int)); 431 + if (!new_templates) { return; } s->templates = new_templates; 432 + } 433 + s->templates[s->template_count++] = s->brace; 434 + } 435 + 436 + static bool in_template_text(parse_state_t *s) { 437 + return s->template_count > 0 && s->brace == s->templates[s->template_count - 1]; 438 + } 439 + 419 440 static bool is_incomplete_input(const char *code, size_t len) { 420 - int paren_depth = 0; 421 - int bracket_depth = 0; 422 - int brace_depth = 0; 423 - 424 - bool in_string = false; 425 - bool in_template = false; 426 - char string_char = 0; 427 - bool escape_next = false; 441 + parse_state_t s = {0}; 428 442 429 443 for (size_t i = 0; i < len; i++) { 430 444 char c = code[i]; 431 445 432 - if (escape_next) { 433 - escape_next = false; 434 - continue; 435 - } 446 + if (s.escaped) { s.escaped = false; continue; } 447 + if (c == '\\' && (s.in_string || s.template_count > 0)) { s.escaped = true; continue; } 448 + if (s.in_string) { if (c == s.string_char) s.in_string = false; continue; } 436 449 437 - if (c == '\\' && (in_string || in_template)) { 438 - escape_next = true; 439 - continue; 440 - } 441 - 442 - if (in_string) { 443 - if (c == string_char) in_string = false; 450 + if (in_template_text(&s)) { 451 + if (c == '`') s.template_count--; 452 + else if (c == '$' && i + 1 < len && code[i + 1] == '{') { s.brace++; i++; } 444 453 continue; 445 454 } 446 455 447 - if (in_template) { 448 - if (c == '`') { 449 - in_template = false; 450 - } else if (c == '$' && i + 1 < len && code[i + 1] == '{') { 451 - brace_depth++; i++; 456 + if (c == '/' && i + 1 < len) { 457 + if (code[i + 1] == '/') { while (i < len && code[i] != '\n') i++; continue; } 458 + if (code[i + 1] == '*') { 459 + for (i += 2; i + 1 < len && !(code[i] == '*' && code[i + 1] == '/'); i++); 460 + if (i + 1 >= len) { free(s.templates); return true; } 461 + i++; continue; 452 462 } 453 - continue; 454 - } 455 - 456 - if (c == '/' && i + 1 < len && code[i + 1] == '/') { 457 - while (i < len && code[i] != '\n') i++; 458 - continue; 459 - } 460 - 461 - if (c == '/' && i + 1 < len && code[i + 1] == '*') { 462 - i += 2; 463 - while (i + 1 < len && !(code[i] == '*' && code[i + 1] == '/')) i++; 464 - if (i + 1 >= len) return true; 465 - i++; continue; 466 463 } 467 464 468 465 switch (c) { 469 - case '"': 470 - case '\'': 471 - in_string = true; 472 - string_char = c; 473 - break; 474 - case '`': 475 - in_template = true; 476 - break; 477 - case '(': paren_depth++; break; 478 - case ')': paren_depth--; break; 479 - case '[': bracket_depth++; break; 480 - case ']': bracket_depth--; break; 481 - case '{': brace_depth++; break; 482 - case '}': brace_depth--; break; 466 + case '"': case '\'': s.in_string = true; s.string_char = c; break; 467 + case '`': push_template(&s); break; 468 + case '(': s.paren++; break; case ')': s.paren--; break; 469 + case '[': s.bracket++; break; case ']': s.bracket--; break; 470 + case '{': s.brace++; break; case '}': s.brace--; break; 483 471 } 484 472 } 485 473 486 - return in_string || in_template || paren_depth > 0 || bracket_depth > 0 || brace_depth > 0; 474 + bool incomplete = s.in_string || s.template_count > 0 || s.paren > 0 || s.bracket > 0 || s.brace > 0; 475 + free(s.templates); 476 + return incomplete; 487 477 } 488 478 489 479 void ant_repl_run() {
+2 -4
src/runtime.c
··· 92 92 code_arena_current = NULL; 93 93 } 94 94 95 - struct ant_runtime *ant_runtime_init(struct js *js, int argc, char **argv, struct arg_file *ls_p) { 95 + struct ant_runtime *ant_runtime_init(ant_t *js, int argc, char **argv, struct arg_file *ls_p) { 96 96 runtime = (struct ant_runtime){ 97 97 .js = js, 98 98 .ant_obj = js_newobj(js), 99 - .flags = 0, 100 - .argc = argc, 101 - .argv = argv, 99 + .flags = 0, .argc = argc, .argv = argv, 102 100 .ls_fp = (ls_p && ls_p->count > 0) ? ls_p->filename[0] : NULL, 103 101 }; 104 102
+18
src/utils.c
··· 112 112 fputs("Error: out of memory\n", stderr); 113 113 exit(EXIT_FAILURE); 114 114 } return p; 115 + } 116 + 117 + void cstr_free(cstr_buf_t *buf) { 118 + if (buf->heap) free(buf->heap); 119 + } 120 + 121 + char *cstr_init(cstr_buf_t *buf, char *stack, size_t stack_size, const char *src, size_t len) { 122 + if (len < stack_size) { 123 + buf->ptr = stack; 124 + buf->heap = NULL; 125 + } else { 126 + buf->heap = malloc(len + 1); 127 + if (!buf->heap) return NULL; 128 + buf->ptr = buf->heap; 129 + } 130 + memcpy(buf->ptr, src, len); 131 + buf->ptr[len] = '\0'; 132 + return buf->ptr; 115 133 }
+1 -1
tests/loop.async.js
··· 13 13 await server(); 14 14 } 15 15 16 - for (let i = 0; i < 100000; i++) { 16 + for (let i = 0; i < 10000; i++) { 17 17 void main(); 18 18 } 19 19
+42
tests/sym_date.js
··· 1 + let d = new Date(); 2 + 3 + // Test 1: Default behavior 4 + console.log(d[Symbol.toPrimitive]('default')); // Should call toString 5 + 6 + // Test 2: String hint 7 + console.log(d[Symbol.toPrimitive]('string')); // Should call toString 8 + 9 + // Test 3: Number hint 10 + console.log(d[Symbol.toPrimitive]('number')); // Should call valueOf (timestamp) 11 + 12 + // Test 4: Coercion tests 13 + console.log(d + ''); // Uses default hint -> string 14 + console.log(+d); // Uses number hint -> number 15 + console.log(d - 0); // Uses number hint -> number 16 + 17 + // Test 5: Verify order - SAVE ORIGINAL METHODS FIRST 18 + const originalValueOf = Date.prototype.valueOf; 19 + const originalToString = Date.prototype.toString; 20 + 21 + Date.prototype.valueOf = function () { 22 + console.log('valueOf called'); 23 + return originalValueOf.call(this); // Call the SAVED original 24 + }; 25 + Date.prototype.toString = function () { 26 + console.log('toString called'); 27 + return originalToString.call(this); // Call the SAVED original 28 + }; 29 + 30 + let d2 = new Date(); 31 + console.log('\nTesting string hint:'); 32 + d2[Symbol.toPrimitive]('string'); // Should log: toString only (returns primitive) 33 + 34 + console.log('\nTesting number hint:'); 35 + d2[Symbol.toPrimitive]('number'); // Should log: valueOf only (returns primitive) 36 + 37 + console.log('\nTesting default hint:'); 38 + d2[Symbol.toPrimitive]('default'); // Should log: toString only (returns primitive) 39 + 40 + // Restore original methods 41 + Date.prototype.valueOf = originalValueOf; 42 + Date.prototype.toString = originalToString;
+35
tests/sym_id.js
··· 1 + console.log('=== SYMBOL KEY STRINGIFICATION TEST ===\n'); 2 + 3 + const obj = {}; 4 + 5 + obj[Symbol.iterator] = 'iter-value'; 6 + obj[Symbol.asyncIterator] = 'async-iter-value'; 7 + obj[Symbol.toStringTag] = 'tag-value'; 8 + obj[Symbol.hasInstance] = 'has-instance-value'; 9 + obj[Symbol.observable] = 'observable-value'; 10 + obj[Symbol.toPrimitive] = 'to-primitive-value'; 11 + obj[Symbol('custom')] = 'custom-value'; 12 + obj[Symbol()] = 'anonymous-value'; 13 + obj.normalKey = 'normal-value'; 14 + 15 + console.log('Object with symbol keys:'); 16 + console.log(obj); 17 + 18 + console.log('\nIndividual access:'); 19 + console.log(' [Symbol.iterator]: ' + obj[Symbol.iterator]); 20 + console.log(' [Symbol.toStringTag]: ' + obj[Symbol.toStringTag]); 21 + 22 + console.log('\nObject.keys (should NOT include symbols):'); 23 + console.log(Object.keys(obj)); 24 + 25 + console.log('\nObject.getOwnPropertySymbols (if supported):'); 26 + try { 27 + console.log(Object.getOwnPropertySymbols(obj)); 28 + } catch (e) { 29 + console.log(' Not supported: ' + e.message); 30 + } 31 + 32 + console.log('\nJSON.stringify (symbols should be skipped):'); 33 + console.log(JSON.stringify(obj)); 34 + 35 + console.log('\n=== DONE ===');
+139
tests/test-coercion-matrix.js
··· 1 + // ============================================ 2 + // TEST: String coercion comparison matrix 3 + // ============================================ 4 + // Compares: concat, template, String(), toString() 5 + // ============================================ 6 + 7 + console.log("=== STRING COERCION MATRIX ===\n"); 8 + 9 + function safe(fn) { 10 + try { 11 + const result = fn(); 12 + if (result === undefined) return "undefined"; 13 + if (result === null) return "null"; 14 + return result; 15 + } catch (e) { 16 + return "ERROR:" + e.name; 17 + } 18 + } 19 + 20 + function test(name, value) { 21 + console.log(name + ":"); 22 + console.log(" concat: " + safe(function() { return "" + value; })); 23 + console.log(" template: " + safe(function() { return `${value}`; })); 24 + console.log(" String(): " + safe(function() { return String(value); })); 25 + if (value !== null && value !== undefined) { 26 + console.log(" toString: " + safe(function() { return value.toString(); })); 27 + } 28 + console.log(""); 29 + } 30 + 31 + // Primitives 32 + console.log("--- PRIMITIVES ---\n"); 33 + test("number 42", 42); 34 + test("number 0", 0); 35 + test("number -1", -1); 36 + test("number NaN", NaN); 37 + test("number Infinity", Infinity); 38 + test("string 'hello'", "hello"); 39 + test("string ''", ""); 40 + test("boolean true", true); 41 + test("boolean false", false); 42 + test("null", null); 43 + test("undefined", undefined); 44 + test("BigInt 123n", 123n); 45 + 46 + // Symbol 47 + console.log("--- SYMBOL ---\n"); 48 + test("Symbol('test')", Symbol("test")); 49 + 50 + // Arrays 51 + console.log("--- ARRAYS ---\n"); 52 + test("[]", []); 53 + test("[1, 2, 3]", [1, 2, 3]); 54 + test("[[1,2], [3,4]]", [[1, 2], [3, 4]]); 55 + test("[null, undefined]", [null, undefined]); 56 + test("['a', 'b']", ["a", "b"]); 57 + 58 + // Functions 59 + console.log("--- FUNCTIONS ---\n"); 60 + test("() => 1", () => 1); 61 + test("function() {}", function() {}); 62 + function namedFn() { return 1; } 63 + test("named function", namedFn); 64 + test("async () => 1", async () => 1); 65 + 66 + // Objects 67 + console.log("--- OBJECTS ---\n"); 68 + test("{}", {}); 69 + test("{ a: 1 }", { a: 1 }); 70 + test("{ a: 1, b: 2 }", { a: 1, b: 2 }); 71 + 72 + // Built-in objects 73 + console.log("--- BUILT-IN OBJECTS ---\n"); 74 + test("new Date(0)", new Date(0)); 75 + test("new Date()", new Date()); 76 + test("/test/gi", /test/gi); 77 + test("new Error('oops')", new Error("oops")); 78 + test("new TypeError('bad')", new TypeError("bad")); 79 + test("new Map([['a',1]])", new Map([["a", 1]])); 80 + test("new Set([1,2,3])", new Set([1, 2, 3])); 81 + test("new WeakMap()", new WeakMap()); 82 + test("new WeakSet()", new WeakSet()); 83 + test("new ArrayBuffer(8)", new ArrayBuffer(8)); 84 + test("new Uint8Array([1,2])", new Uint8Array([1, 2])); 85 + test("Promise.resolve(1)", Promise.resolve(1)); 86 + 87 + // Custom toString 88 + console.log("--- CUSTOM toString (CRASH TESTS) ---\n"); 89 + 90 + console.log("native toString (should work):"); 91 + test("{ toString: Object.prototype.toString }", { toString: Object.prototype.toString }); 92 + 93 + console.log("user toString (may crash):"); 94 + const userToString = { toString: function() { return "custom"; } }; 95 + console.log(" direct call works: " + userToString.toString()); 96 + test("{ toString: fn => 'custom' }", userToString); 97 + 98 + console.log("arrow toString (may crash):"); 99 + const arrowToString = { toString: () => "arrow" }; 100 + console.log(" direct call works: " + arrowToString.toString()); 101 + test("{ toString: () => 'arrow' }", arrowToString); 102 + 103 + // Custom valueOf 104 + console.log("--- CUSTOM valueOf ---\n"); 105 + test("{ valueOf: fn => 42 }", { valueOf: function() { return 42; } }); 106 + test("{ valueOf: fn => 'val' }", { valueOf: function() { return "val"; } }); 107 + 108 + // Symbol.toPrimitive 109 + console.log("--- Symbol.toPrimitive ---\n"); 110 + const withPrimitive = {}; 111 + withPrimitive[Symbol.toPrimitive] = function(hint) { return "hint:" + hint; }; 112 + test("{ [Symbol.toPrimitive]: fn }", withPrimitive); 113 + 114 + // Class instances 115 + console.log("--- CLASS INSTANCES ---\n"); 116 + 117 + class WithToString { 118 + toString() { return "class-toString"; } 119 + } 120 + console.log("class with toString method:"); 121 + const inst1 = new WithToString(); 122 + console.log(" direct call works: " + inst1.toString()); 123 + test("new WithToString()", inst1); 124 + 125 + class WithValueOf { 126 + valueOf() { return "class-valueOf"; } 127 + } 128 + test("new WithValueOf()", new WithValueOf()); 129 + 130 + class PlainClass {} 131 + test("new PlainClass()", new PlainClass()); 132 + 133 + console.log("=== SUMMARY ===\n"); 134 + console.log("Check for:"); 135 + console.log("1. Missing output after test name = SILENT CRASH"); 136 + console.log("2. '[Function: ...]' instead of function source = INSPECT BUG"); 137 + console.log("3. '{ ... }' or '[ ... ]' with spaces = INSPECT BUG"); 138 + console.log("4. Different results between concat and template = BUG"); 139 + console.log("");
+80
tests/test-concat-crash.js
··· 1 + // ============================================ 2 + // TEST: Concatenation crashes with user-defined toString 3 + // ============================================ 4 + // Bug: "" + obj crashes silently when obj has user-defined toString 5 + // ============================================ 6 + 7 + console.log("=== CONCAT CRASH TESTS ===\n"); 8 + 9 + // --- BASELINE (should work) --- 10 + 11 + console.log("1. No custom toString:"); 12 + const obj1 = {}; 13 + console.log(" result: " + ("" + obj1)); 14 + 15 + console.log("\n2. toString = native function:"); 16 + const obj2 = { toString: Object.prototype.toString }; 17 + console.log(" result: " + ("" + obj2)); 18 + 19 + console.log("\n3. toString = Array.prototype.toString:"); 20 + const obj3 = { toString: Array.prototype.toString }; 21 + console.log(" result: " + ("" + obj3)); 22 + 23 + console.log("\n4. toString = console.log (native):"); 24 + const obj4 = { toString: console.log }; 25 + console.log(" result: " + ("" + obj4)); 26 + 27 + // --- CRASH TESTS (these crash silently) --- 28 + 29 + console.log("\n5. toString = user function:"); 30 + const obj5 = { toString: function() { return "custom"; } }; 31 + console.log(" expected: custom"); 32 + console.log(" direct call: " + obj5.toString()); 33 + const result5 = "" + obj5; 34 + console.log(" concat: " + result5); 35 + console.log(" (if missing, CRASH)"); 36 + 37 + console.log("\n6. toString = arrow function:"); 38 + const obj6 = { toString: () => "arrow" }; 39 + console.log(" expected: arrow"); 40 + console.log(" direct call: " + obj6.toString()); 41 + const result6 = "" + obj6; 42 + console.log(" concat: " + result6); 43 + console.log(" (if missing, CRASH)"); 44 + 45 + console.log("\n7. toString = user function returning number:"); 46 + const obj7 = { toString: function() { return 42; } }; 47 + console.log(" expected: 42"); 48 + console.log(" direct call: " + obj7.toString()); 49 + const result7 = "" + obj7; 50 + console.log(" concat: " + result7); 51 + console.log(" (if missing, CRASH)"); 52 + 53 + console.log("\n8. Inherited toString from prototype:"); 54 + function MyClass() {} 55 + MyClass.prototype.toString = function() { return "inherited"; }; 56 + const obj8 = new MyClass(); 57 + console.log(" expected: inherited"); 58 + console.log(" direct call: " + obj8.toString()); 59 + const result8 = "" + obj8; 60 + console.log(" concat: " + result8); 61 + console.log(" (if missing, CRASH)"); 62 + 63 + console.log("\n9. toString as getter returning function:"); 64 + const obj9 = { get toString() { return function() { return "getter"; }; } }; 65 + console.log(" expected: getter"); 66 + const result9 = "" + obj9; 67 + console.log(" concat: " + result9); 68 + 69 + console.log("\n10. toString = non-function value:"); 70 + const obj10 = { toString: "not a function" }; 71 + console.log(" expected: TypeError"); 72 + try { 73 + const result10 = "" + obj10; 74 + console.log(" concat: " + result10); 75 + console.log(" ERROR: should have thrown TypeError!"); 76 + } catch (e) { 77 + console.log(" threw: " + e.name + " (correct)"); 78 + } 79 + 80 + console.log("\n=== DONE ===");
+158
tests/test-string-constructor.js
··· 1 + // ============================================ 2 + // TEST: String() uses inspect instead of toString 3 + // ============================================ 4 + // Bug: String(obj) uses inspect-style output instead of calling toString() 5 + // ============================================ 6 + 7 + console.log("=== String() CONSTRUCTOR TESTS ===\n"); 8 + 9 + // --- PRIMITIVES --- 10 + 11 + console.log("1. Primitives:"); 12 + console.log(" String(42): expected '42', got '" + String(42) + "'"); 13 + console.log(" String('hi'): expected 'hi', got '" + String("hi") + "'"); 14 + console.log(" String(true): expected 'true', got '" + String(true) + "'"); 15 + console.log(" String(false): expected 'false', got '" + String(false) + "'"); 16 + console.log(" String(null): expected 'null', got '" + String(null) + "'"); 17 + console.log(" String(undefined): expected 'undefined', got '" + String(undefined) + "'"); 18 + console.log(" String(123n): expected '123', got '" + String(123n) + "'"); 19 + 20 + // --- ARRAYS --- 21 + 22 + console.log("\n2. Array [1, 2, 3]:"); 23 + const arr1 = [1, 2, 3]; 24 + console.log(" expected: '1,2,3'"); 25 + console.log(" String(): '" + String(arr1) + "'"); 26 + console.log(" toString: '" + arr1.toString() + "'"); 27 + 28 + console.log("\n3. Nested array [[1,2], [3,4]]:"); 29 + const arr2 = [[1, 2], [3, 4]]; 30 + console.log(" expected: '1,2,3,4'"); 31 + console.log(" String(): '" + String(arr2) + "'"); 32 + console.log(" toString: '" + arr2.toString() + "'"); 33 + 34 + console.log("\n4. Empty array []:"); 35 + const arr3 = []; 36 + console.log(" expected: ''"); 37 + console.log(" String(): '" + String(arr3) + "'"); 38 + 39 + console.log("\n5. Array with objects:"); 40 + const arr4 = [{ a: 1 }, { b: 2 }]; 41 + console.log(" expected: '[object Object],[object Object]'"); 42 + console.log(" String(): '" + String(arr4) + "'"); 43 + 44 + // --- FUNCTIONS --- 45 + 46 + console.log("\n6. Arrow function:"); 47 + const fn1 = () => 1; 48 + console.log(" expected: '() => 1'"); 49 + console.log(" String(): '" + String(fn1) + "'"); 50 + console.log(" toString: '" + fn1.toString() + "'"); 51 + 52 + console.log("\n7. Named function:"); 53 + function namedFn() { return 1; } 54 + console.log(" expected: 'function namedFn() { return 1; }'"); 55 + console.log(" String(): '" + String(namedFn) + "'"); 56 + console.log(" toString: '" + namedFn.toString() + "'"); 57 + 58 + console.log("\n8. Async function:"); 59 + async function asyncFn() { return 1; } 60 + console.log(" expected: 'async function asyncFn() { return 1; }'"); 61 + console.log(" String(): '" + String(asyncFn) + "'"); 62 + console.log(" toString: '" + asyncFn.toString() + "'"); 63 + 64 + // --- OBJECTS --- 65 + 66 + console.log("\n9. Plain object {}:"); 67 + const obj1 = {}; 68 + console.log(" expected: '[object Object]'"); 69 + console.log(" String(): '" + String(obj1) + "'"); 70 + 71 + console.log("\n10. Object with properties:"); 72 + const obj2 = { a: 1, b: 2 }; 73 + console.log(" expected: '[object Object]'"); 74 + console.log(" String(): '" + String(obj2) + "'"); 75 + 76 + console.log("\n11. Object with custom toString:"); 77 + const obj3 = { toString: function() { return "custom-toString"; } }; 78 + console.log(" expected: 'custom-toString'"); 79 + console.log(" toString: '" + obj3.toString() + "'"); 80 + console.log(" String(): '" + String(obj3) + "'"); 81 + 82 + console.log("\n12. Object with valueOf only:"); 83 + const obj4 = { valueOf: function() { return "custom-valueOf"; } }; 84 + console.log(" expected: 'custom-valueOf' or '[object Object]'"); 85 + console.log(" String(): '" + String(obj4) + "'"); 86 + 87 + console.log("\n13. Object with both toString and valueOf:"); 88 + const obj5 = { 89 + toString: function() { return "from-toString"; }, 90 + valueOf: function() { return "from-valueOf"; } 91 + }; 92 + console.log(" expected: 'from-toString' (toString has priority)"); 93 + console.log(" String(): '" + String(obj5) + "'"); 94 + 95 + // --- BUILT-IN OBJECTS --- 96 + 97 + console.log("\n14. Date:"); 98 + const date = new Date(0); 99 + console.log(" expected: date string like 'Thu Jan 01 1970...'"); 100 + console.log(" String(): '" + String(date) + "'"); 101 + console.log(" toString: '" + date.toString() + "'"); 102 + 103 + console.log("\n15. RegExp:"); 104 + const re = /test/gi; 105 + console.log(" expected: '/test/gi'"); 106 + console.log(" String(): '" + String(re) + "'"); 107 + console.log(" toString: '" + re.toString() + "'"); 108 + 109 + console.log("\n16. Error:"); 110 + const err = new Error("oops"); 111 + console.log(" expected: 'Error: oops'"); 112 + console.log(" String(): '" + String(err) + "'"); 113 + console.log(" toString: '" + err.toString() + "'"); 114 + 115 + console.log("\n17. Map:"); 116 + const map = new Map([["a", 1]]); 117 + console.log(" expected: '[object Map]'"); 118 + console.log(" String(): '" + String(map) + "'"); 119 + 120 + console.log("\n18. Set:"); 121 + const set = new Set([1, 2, 3]); 122 + console.log(" expected: '[object Set]'"); 123 + console.log(" String(): '" + String(set) + "'"); 124 + 125 + // --- SYMBOL --- 126 + 127 + console.log("\n19. Symbol:"); 128 + const sym = Symbol("test"); 129 + console.log(" expected: 'Symbol(test)'"); 130 + console.log(" String(): '" + String(sym) + "'"); 131 + console.log(" toString: '" + sym.toString() + "'"); 132 + 133 + // --- Symbol.toPrimitive --- 134 + 135 + console.log("\n20. Object with Symbol.toPrimitive:"); 136 + const obj6 = {}; 137 + obj6[Symbol.toPrimitive] = function(hint) { return "toPrimitive-" + hint; }; 138 + console.log(" expected: 'toPrimitive-string'"); 139 + console.log(" String(): '" + String(obj6) + "'"); 140 + 141 + // --- CLASS INSTANCES --- 142 + 143 + console.log("\n21. Class instance with toString:"); 144 + class MyClass { 145 + toString() { return "MyClass instance"; } 146 + } 147 + const inst = new MyClass(); 148 + console.log(" expected: 'MyClass instance'"); 149 + console.log(" toString: '" + inst.toString() + "'"); 150 + console.log(" String(): '" + String(inst) + "'"); 151 + 152 + console.log("\n22. Class instance without toString:"); 153 + class PlainClass {} 154 + const inst2 = new PlainClass(); 155 + console.log(" expected: '[object Object]'"); 156 + console.log(" String(): '" + String(inst2) + "'"); 157 + 158 + console.log("\n=== DONE ===");
+135
tests/test-template-literal.js
··· 1 + // ============================================ 2 + // TEST: Template literals use inspect instead of toString 3 + // ============================================ 4 + // Bug: `${obj}` uses inspect-style output instead of calling toString() 5 + // ============================================ 6 + 7 + console.log("=== TEMPLATE LITERAL TESTS ===\n"); 8 + 9 + // --- PRIMITIVES --- 10 + 11 + console.log("1. Primitives:"); 12 + console.log(" number: expected '42', got '" + `${42}` + "'"); 13 + console.log(" string: expected 'hi', got '" + `${"hi"}` + "'"); 14 + console.log(" boolean: expected 'true', got '" + `${true}` + "'"); 15 + console.log(" null: expected 'null', got '" + `${null}` + "'"); 16 + console.log(" undefined: expected 'undefined', got '" + `${undefined}` + "'"); 17 + console.log(" BigInt: expected '123', got '" + `${123n}` + "'"); 18 + 19 + // --- ARRAYS --- 20 + 21 + console.log("\n2. Array [1, 2, 3]:"); 22 + const arr1 = [1, 2, 3]; 23 + console.log(" expected: '1,2,3'"); 24 + console.log(" concat: '" + ("" + arr1) + "'"); 25 + console.log(" template: '" + `${arr1}` + "'"); 26 + console.log(" toString: '" + arr1.toString() + "'"); 27 + 28 + console.log("\n3. Nested array [[1,2], [3,4]]:"); 29 + const arr2 = [[1, 2], [3, 4]]; 30 + console.log(" expected: '1,2,3,4'"); 31 + console.log(" concat: '" + ("" + arr2) + "'"); 32 + console.log(" template: '" + `${arr2}` + "'"); 33 + console.log(" toString: '" + arr2.toString() + "'"); 34 + 35 + console.log("\n4. Empty array []:"); 36 + const arr3 = []; 37 + console.log(" expected: ''"); 38 + console.log(" concat: '" + ("" + arr3) + "'"); 39 + console.log(" template: '" + `${arr3}` + "'"); 40 + 41 + // --- FUNCTIONS --- 42 + 43 + console.log("\n5. Arrow function:"); 44 + const fn1 = () => 1; 45 + console.log(" expected: '() => 1'"); 46 + console.log(" concat: '" + ("" + fn1) + "'"); 47 + console.log(" template: '" + `${fn1}` + "'"); 48 + console.log(" toString: '" + fn1.toString() + "'"); 49 + 50 + console.log("\n6. Named function:"); 51 + function namedFn() { return 1; } 52 + console.log(" expected: 'function namedFn() { return 1; }'"); 53 + console.log(" concat: '" + ("" + namedFn) + "'"); 54 + console.log(" template: '" + `${namedFn}` + "'"); 55 + 56 + console.log("\n7. Function expression:"); 57 + const fn2 = function() { return 1; }; 58 + console.log(" expected: 'function() { return 1; }'"); 59 + console.log(" concat: '" + ("" + fn2) + "'"); 60 + console.log(" template: '" + `${fn2}` + "'"); 61 + 62 + // --- OBJECTS --- 63 + 64 + console.log("\n8. Plain object {}:"); 65 + const obj1 = {}; 66 + console.log(" expected: '[object Object]'"); 67 + console.log(" concat: '" + ("" + obj1) + "'"); 68 + console.log(" template: '" + `${obj1}` + "'"); 69 + 70 + console.log("\n9. Object with properties {a:1, b:2}:"); 71 + const obj2 = { a: 1, b: 2 }; 72 + console.log(" expected: '[object Object]'"); 73 + console.log(" concat: '" + ("" + obj2) + "'"); 74 + console.log(" template: '" + `${obj2}` + "'"); 75 + 76 + console.log("\n10. Object with custom toString:"); 77 + const obj3 = { toString: function() { return "custom"; } }; 78 + console.log(" expected: 'custom'"); 79 + console.log(" toString: '" + obj3.toString() + "'"); 80 + console.log(" template: '" + `${obj3}` + "'"); 81 + 82 + // --- BUILT-IN OBJECTS --- 83 + 84 + console.log("\n11. Date:"); 85 + const date = new Date(0); 86 + console.log(" expected: 'Thu Jan 01 1970...' (locale date string)"); 87 + console.log(" concat: '" + ("" + date) + "'"); 88 + console.log(" template: '" + `${date}` + "'"); 89 + 90 + console.log("\n12. RegExp /test/gi:"); 91 + const re = /test/gi; 92 + console.log(" expected: '/test/gi'"); 93 + console.log(" concat: '" + ("" + re) + "'"); 94 + console.log(" template: '" + `${re}` + "'"); 95 + 96 + console.log("\n13. Error:"); 97 + const err = new Error("oops"); 98 + console.log(" expected: 'Error: oops'"); 99 + console.log(" concat: '" + ("" + err) + "'"); 100 + console.log(" template: '" + `${err}` + "'"); 101 + 102 + console.log("\n14. Map:"); 103 + const map = new Map([["a", 1]]); 104 + console.log(" expected: '[object Map]'"); 105 + console.log(" concat: '" + ("" + map) + "'"); 106 + console.log(" template: '" + `${map}` + "'"); 107 + 108 + console.log("\n15. Set:"); 109 + const set = new Set([1, 2, 3]); 110 + console.log(" expected: '[object Set]'"); 111 + console.log(" concat: '" + ("" + set) + "'"); 112 + console.log(" template: '" + `${set}` + "'"); 113 + 114 + // --- SYMBOL (should throw) --- 115 + 116 + console.log("\n16. Symbol (should throw TypeError):"); 117 + const sym = Symbol("test"); 118 + console.log(" toString: '" + sym.toString() + "'"); 119 + try { 120 + console.log(" template: '" + `${sym}` + "'"); 121 + console.log(" ERROR: should have thrown!"); 122 + } catch (e) { 123 + console.log(" template: threw " + e.name + " (correct)"); 124 + } 125 + 126 + // --- QUINE TEST --- 127 + 128 + console.log("\n17. Quine test (self-referencing function):"); 129 + const $ = function(_) { return "$=" + $ + ";$()"; }; 130 + console.log(" expected: '$=function(_) { return \"$=\" + $ + \";$()\"; };$()'"); 131 + console.log(" concat: '" + $() + "'"); 132 + const $2 = function(_) { return `$=${$2};$()`; }; 133 + console.log(" template: '" + $2() + "'"); 134 + 135 + console.log("\n=== DONE ===");
+243
tests/test-valueof-toprimitive.js
··· 1 + // ============================================ 2 + // TEST: valueOf and Symbol.toPrimitive behavior 3 + // ============================================ 4 + // Bug: valueOf is never called, toPrimitive may not work 5 + // ============================================ 6 + 7 + console.log('=== valueOf AND Symbol.toPrimitive TESTS ===\n'); 8 + 9 + // --- valueOf TESTS --- 10 + 11 + console.log('SECTION 1: valueOf\n'); 12 + 13 + console.log('1. Only valueOf, returns string:'); 14 + const obj1 = { 15 + valueOf: function () { 16 + return 'from-valueOf'; 17 + } 18 + }; 19 + console.log(" expected concat: 'from-valueOf'"); 20 + console.log(" concat: '" + ('' + obj1) + "'"); 21 + console.log(" String(): '" + String(obj1) + "'"); 22 + 23 + console.log('\n2. Only valueOf, returns number:'); 24 + const obj2 = { 25 + valueOf: function () { 26 + return 42; 27 + } 28 + }; 29 + console.log(" expected concat: '42'"); 30 + console.log(" concat: '" + ('' + obj2) + "'"); 31 + console.log(" String(): '" + String(obj2) + "'"); 32 + 33 + console.log('\n3. Only valueOf, returns boolean:'); 34 + const obj3 = { 35 + valueOf: function () { 36 + return true; 37 + } 38 + }; 39 + console.log(" expected concat: 'true'"); 40 + console.log(" concat: '" + ('' + obj3) + "'"); 41 + 42 + console.log('\n4. valueOf returns object (should fallback to toString):'); 43 + const obj4 = { 44 + valueOf: function () { 45 + return {}; 46 + } 47 + }; 48 + console.log(" expected: '[object Object]' (fallback)"); 49 + console.log(" concat: '" + ('' + obj4) + "'"); 50 + 51 + console.log('\n5. valueOf returns null:'); 52 + const obj5 = { 53 + valueOf: function () { 54 + return null; 55 + } 56 + }; 57 + console.log(" expected: 'null'"); 58 + console.log(" concat: '" + ('' + obj5) + "'"); 59 + 60 + console.log('\n6. valueOf returns undefined:'); 61 + const obj6 = { 62 + valueOf: function () { 63 + return undefined; 64 + } 65 + }; 66 + console.log(" expected: 'undefined'"); 67 + console.log(" concat: '" + ('' + obj6) + "'"); 68 + 69 + // --- toString + valueOf priority --- 70 + 71 + console.log('\n\nSECTION 2: toString vs valueOf priority\n'); 72 + 73 + console.log('7. Both toString and valueOf (user functions):'); 74 + const obj7 = { 75 + toString: function () { 76 + return 'from-toString'; 77 + }, 78 + valueOf: function () { 79 + return 'from-valueOf'; 80 + } 81 + }; 82 + console.log(" expected: 'from-toString' (toString has priority for string hint)"); 83 + console.log(" direct toString: '" + obj7.toString() + "'"); 84 + console.log(" direct valueOf: '" + obj7.valueOf() + "'"); 85 + const result7 = '' + obj7; 86 + console.log(" concat: '" + result7 + "'"); 87 + console.log(' (if missing, CRASH)'); 88 + 89 + console.log('\n8. toString throws, valueOf works:'); 90 + const obj8 = { 91 + toString: function () { 92 + throw new Error('toString error'); 93 + }, 94 + valueOf: function () { 95 + return 'from-valueOf'; 96 + } 97 + }; 98 + console.log(" expected: 'from-valueOf' (fallback) or Error"); 99 + try { 100 + console.log(" concat: '" + ('' + obj8) + "'"); 101 + } catch (e) { 102 + console.log(' error: ' + e.message); 103 + } 104 + 105 + console.log('\n9. toString returns object, valueOf returns string:'); 106 + const obj9 = { 107 + toString: function () { 108 + return {}; 109 + }, 110 + valueOf: function () { 111 + return 'from-valueOf'; 112 + } 113 + }; 114 + console.log(" expected: 'from-valueOf' (fallback)"); 115 + try { 116 + console.log(" concat: '" + ('' + obj9) + "'"); 117 + } catch (e) { 118 + console.log(' error: ' + e.message); 119 + } 120 + 121 + console.log('\n10. Both return objects (should throw TypeError):'); 122 + const obj10 = { 123 + toString: function () { 124 + return {}; 125 + }, 126 + valueOf: function () { 127 + return {}; 128 + } 129 + }; 130 + console.log(' expected: TypeError'); 131 + try { 132 + console.log(" concat: '" + ('' + obj10) + "'"); 133 + } catch (e) { 134 + console.log(' error: ' + e.name + ': ' + e.message); 135 + } 136 + 137 + // --- Symbol.toPrimitive --- 138 + 139 + console.log('\n\nSECTION 3: Symbol.toPrimitive\n'); 140 + 141 + console.log('11. toPrimitive returns string:'); 142 + const obj11 = {}; 143 + obj11[Symbol.toPrimitive] = function (hint) { 144 + return 'primitive-' + hint; 145 + }; 146 + console.log(" expected concat: 'primitive-default' or 'primitive-string'"); 147 + console.log(" concat: '" + ('' + obj11) + "'"); 148 + console.log(" String(): '" + String(obj11) + "'"); 149 + console.log(" template: '" + `${obj11}` + "'"); 150 + 151 + console.log('\n12. toPrimitive returns number:'); 152 + const obj12 = {}; 153 + obj12[Symbol.toPrimitive] = function (hint) { 154 + return 99; 155 + }; 156 + console.log(" expected: '99'"); 157 + console.log(" concat: '" + ('' + obj12) + "'"); 158 + 159 + console.log('\n13. toPrimitive overrides toString and valueOf:'); 160 + const obj13 = { 161 + toString: function () { 162 + return 'from-toString'; 163 + }, 164 + valueOf: function () { 165 + return 'from-valueOf'; 166 + } 167 + }; 168 + obj13[Symbol.toPrimitive] = function (hint) { 169 + return 'from-toPrimitive'; 170 + }; 171 + console.log(" expected: 'from-toPrimitive' (toPrimitive has highest priority)"); 172 + console.log(" concat: '" + ('' + obj13) + "'"); 173 + 174 + console.log('\n14. toPrimitive returns object (should throw):'); 175 + const obj14 = {}; 176 + obj14[Symbol.toPrimitive] = function (hint) { 177 + return {}; 178 + }; 179 + console.log(' expected: TypeError'); 180 + try { 181 + console.log(" concat: '" + ('' + obj14) + "'"); 182 + } catch (e) { 183 + console.log(' error: ' + e.name + ': ' + e.message); 184 + } 185 + 186 + console.log('\n15. toPrimitive throws:'); 187 + const obj15 = {}; 188 + obj15[Symbol.toPrimitive] = function (hint) { 189 + throw new Error('toPrimitive error'); 190 + }; 191 + console.log(' expected: Error: toPrimitive error'); 192 + try { 193 + console.log(" concat: '" + ('' + obj15) + "'"); 194 + } catch (e) { 195 + if (e && e.message) { 196 + console.log(' error: ' + e.message); 197 + } else { 198 + console.log(' error: ' + String(e)); 199 + } 200 + } 201 + 202 + console.log('\n16. toPrimitive is not a function:'); 203 + const obj16 = {}; 204 + obj16[Symbol.toPrimitive] = 'not a function'; 205 + console.log(' expected: TypeError or fallback to toString'); 206 + try { 207 + console.log(" concat: '" + ('' + obj16) + "'"); 208 + } catch (e) { 209 + console.log(' error: ' + e.name + ': ' + e.message); 210 + } 211 + 212 + // --- Hint values --- 213 + 214 + console.log('\n\nSECTION 4: Hint values\n'); 215 + 216 + console.log('17. Check hint values:'); 217 + const hints = []; 218 + const obj17 = {}; 219 + obj17[Symbol.toPrimitive] = function (hint) { 220 + hints.push(hint); 221 + return 'ok'; 222 + }; 223 + 224 + console.log(" concat '' + obj:"); 225 + let r1 = '' + obj17; 226 + console.log(" hint was: '" + hints[hints.length - 1] + "'"); 227 + 228 + console.log(' String(obj):'); 229 + let r2 = String(obj17); 230 + console.log(" hint was: '" + hints[hints.length - 1] + "'"); 231 + 232 + console.log(' template `${obj}`:'); 233 + let r3 = `${obj17}`; 234 + console.log(" hint was: '" + hints[hints.length - 1] + "'"); 235 + 236 + console.log(' +obj (unary plus, number hint):'); 237 + let r4 = +obj17; 238 + console.log(" hint was: '" + hints[hints.length - 1] + "'"); 239 + 240 + console.log('\n All hints collected: [' + hints.join(', ') + ']'); 241 + console.log(" Expected: ['default', 'string', 'string', 'number']"); 242 + 243 + console.log('\n=== DONE ===');