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.

improve symbols

+84 -170
+7
include/modules/symbol.h
··· 7 7 void init_symbol_module(void); 8 8 void js_define_species_getter(ant_t *js, ant_value_t ctor); 9 9 10 + #define ARR_ITER_PACK(kind, idx) ((uint32_t)(kind) << 28 | (uint32_t)(idx)) 11 + #define ARR_ITER_KIND(v) ((uint32_t)(v) >> 28) 12 + #define ARR_ITER_INDEX(v) ((uint32_t)(v) & 0x0FFFFFFFU) 13 + 14 + enum { ARR_ITER_VALUES = 0, ARR_ITER_KEYS = 1, ARR_ITER_ENTRIES = 2 }; 15 + ant_value_t make_array_iterator(ant_t *js, ant_value_t array, int kind); 16 + 10 17 ant_value_t maybe_call_symbol_method( 11 18 ant_t *js, ant_value_t target, ant_value_t sym, 12 19 ant_value_t this_arg, ant_value_t *args,
+3 -98
src/ant.c
··· 7795 7795 return mkval(T_ARR, vdata(result)); 7796 7796 } 7797 7797 7798 - static ant_value_t arr_values_iter_next(ant_t *js, ant_value_t *args, int nargs) { 7799 - ant_value_t iter = js->this_val; 7800 - ant_value_t array = js_get_slot(iter, SLOT_DATA); 7801 - ant_value_t idx_v = js_get_slot(iter, SLOT_ITER_STATE); 7802 - ant_offset_t idx = (vtype(idx_v) == T_NUM) ? (ant_offset_t)js_getnum(idx_v) : 0; 7803 - ant_value_t result = js_mkobj(js); 7804 - ant_offset_t len = js_arr_len(js, array); 7805 - 7806 - if (idx >= len) { 7807 - js_set(js, result, "done", js_true); 7808 - js_set(js, result, "value", js_mkundef()); 7809 - return result; 7810 - } 7811 - 7812 - js_set_slot(iter, SLOT_ITER_STATE, js_mknum((double)(idx + 1))); 7813 - js_set(js, result, "done", js_false); 7814 - js_set(js, result, "value", js_arr_get(js, array, idx)); 7815 - 7816 - return result; 7817 - } 7818 - 7819 - static ant_value_t arr_keys_iter_next(ant_t *js, ant_value_t *args, int nargs) { 7820 - ant_value_t iter = js->this_val; 7821 - ant_value_t array = js_get_slot(iter, SLOT_DATA); 7822 - ant_value_t idx_v = js_get_slot(iter, SLOT_ITER_STATE); 7823 - ant_offset_t idx = (vtype(idx_v) == T_NUM) ? (ant_offset_t)js_getnum(idx_v) : 0; 7824 - ant_value_t result = js_mkobj(js); 7825 - ant_offset_t len = js_arr_len(js, array); 7826 - 7827 - if (idx >= len) { 7828 - js_set(js, result, "done", js_true); 7829 - js_set(js, result, "value", js_mkundef()); 7830 - return result; 7831 - } 7832 - 7833 - js_set_slot(iter, SLOT_ITER_STATE, js_mknum((double)(idx + 1))); 7834 - js_set(js, result, "done", js_false); 7835 - js_set(js, result, "value", js_mknum((double)idx)); 7836 - 7837 - return result; 7838 - } 7839 - 7840 - static ant_value_t arr_entries_iter_next(ant_t *js, ant_value_t *args, int nargs) { 7841 - ant_value_t iter = js->this_val; 7842 - ant_value_t array = js_get_slot(iter, SLOT_DATA); 7843 - ant_value_t idx_v = js_get_slot(iter, SLOT_ITER_STATE); 7844 - ant_offset_t idx = (vtype(idx_v) == T_NUM) ? (ant_offset_t)js_getnum(idx_v) : 0; 7845 - ant_value_t result = js_mkobj(js); 7846 - ant_offset_t len = js_arr_len(js, array); 7847 - 7848 - if (idx >= len) { 7849 - js_set(js, result, "done", js_true); 7850 - js_set(js, result, "value", js_mkundef()); 7851 - return result; 7852 - } 7853 - 7854 - ant_value_t pair = js_mkarr(js); 7855 - js_arr_push(js, pair, js_mknum((double)idx)); 7856 - js_arr_push(js, pair, js_arr_get(js, array, idx)); 7857 - js_set_slot(iter, SLOT_ITER_STATE, js_mknum((double)(idx + 1))); 7858 - js_set(js, result, "done", js_false); 7859 - js_set(js, result, "value", pair); 7860 - 7861 - return result; 7862 - } 7863 - 7864 - static ant_value_t g_arr_values_iter_proto = 0; 7865 - static ant_value_t g_arr_keys_iter_proto = 0; 7866 - static ant_value_t g_arr_entries_iter_proto = 0; 7867 - 7868 - static void ensure_array_iter_protos(ant_t *js) { 7869 - if (g_arr_values_iter_proto) return; 7870 - 7871 - g_arr_values_iter_proto = js_mkobj(js); 7872 - js_set_proto_init(g_arr_values_iter_proto, js->sym.iterator_proto); 7873 - js_set(js, g_arr_values_iter_proto, "next", js_mkfun(arr_values_iter_next)); 7874 - 7875 - g_arr_keys_iter_proto = js_mkobj(js); 7876 - js_set_proto_init(g_arr_keys_iter_proto, js->sym.iterator_proto); 7877 - js_set(js, g_arr_keys_iter_proto, "next", js_mkfun(arr_keys_iter_next)); 7878 - 7879 - g_arr_entries_iter_proto = js_mkobj(js); 7880 - js_set_proto_init(g_arr_entries_iter_proto, js->sym.iterator_proto); 7881 - js_set(js, g_arr_entries_iter_proto, "next", js_mkfun(arr_entries_iter_next)); 7882 - } 7883 - 7884 - static ant_value_t make_array_iterator(ant_t *js, ant_value_t iter_proto) { 7885 - ensure_array_iter_protos(js); 7886 - ant_value_t iter = js_mkobj(js); 7887 - js_set_slot_wb(js, iter, SLOT_DATA, js->this_val); 7888 - js_set_slot(iter, SLOT_ITER_STATE, js_mknum(0)); 7889 - js_set_proto_init(iter, iter_proto); 7890 - return iter; 7891 - } 7892 - 7893 7798 static ant_value_t builtin_array_keys(ant_t *js, ant_value_t *args, int nargs) { 7894 7799 if (vtype(js->this_val) != T_ARR && vtype(js->this_val) != T_OBJ) 7895 7800 return js_mkerr(js, "keys called on non-array"); 7896 - return make_array_iterator(js, g_arr_keys_iter_proto); 7801 + return make_array_iterator(js, js->this_val, ARR_ITER_KEYS); 7897 7802 } 7898 7803 7899 7804 static ant_value_t builtin_array_values(ant_t *js, ant_value_t *args, int nargs) { 7900 7805 if (vtype(js->this_val) != T_ARR && vtype(js->this_val) != T_OBJ) 7901 7806 return js_mkerr(js, "values called on non-array"); 7902 - return make_array_iterator(js, g_arr_values_iter_proto); 7807 + return make_array_iterator(js, js->this_val, ARR_ITER_VALUES); 7903 7808 } 7904 7809 7905 7810 static ant_value_t builtin_array_entries(ant_t *js, ant_value_t *args, int nargs) { 7906 7811 if (vtype(js->this_val) != T_ARR && vtype(js->this_val) != T_OBJ) 7907 7812 return js_mkerr(js, "entries called on non-array"); 7908 - return make_array_iterator(js, g_arr_entries_iter_proto); 7813 + return make_array_iterator(js, js->this_val, ARR_ITER_ENTRIES); 7909 7814 } 7910 7815 7911 7816 static ant_value_t builtin_array_toString(ant_t *js, ant_value_t *args, int nargs) {
+74 -72
src/modules/symbol.c
··· 64 64 return js_symbol_to_string(js, this_val); 65 65 } 66 66 67 - static ant_value_t iterator_next(ant_t *js, ant_value_t *args, int nargs) { 68 - ant_value_t this_val = js_getthis(js); 67 + static ant_value_t get_iterator_prototype(ant_t *js) { 68 + if (vtype(js->sym.iterator_proto) == T_OBJ) return js->sym.iterator_proto; 69 + 70 + js->sym.iterator_proto = js_mkobj(js); 71 + js_set_proto_init(js->sym.iterator_proto, js->object); 72 + js_set_sym(js, js->sym.iterator_proto, g_iterator, js_mkfun(sym_this_cb)); 69 73 70 - // migrate to slots 71 - ant_value_t arr = js_get(js, this_val, "__arr"); 72 - ant_value_t idx_val = js_get(js, this_val, "__idx"); 73 - ant_value_t len_val = js_get(js, this_val, "__len"); 74 + return js->sym.iterator_proto; 75 + } 76 + 77 + static ant_value_t arr_iter_next(ant_t *js, ant_value_t *args, int nargs) { 78 + ant_value_t iter = js->this_val; 79 + ant_value_t array = js_get_slot(iter, SLOT_DATA); 80 + ant_value_t state_v = js_get_slot(iter, SLOT_ITER_STATE); 74 81 75 - int idx = (int)js_getnum(idx_val); 76 - int len = (int)js_getnum(len_val); 82 + uint32_t state = (vtype(state_v) == T_NUM) ? (uint32_t)js_getnum(state_v) : 0; 83 + uint32_t kind = ARR_ITER_KIND(state); 84 + uint32_t idx = ARR_ITER_INDEX(state); 77 85 78 86 ant_value_t result = js_mkobj(js); 79 - 80 - if (idx >= len) { 87 + ant_offset_t len = js_arr_len(js, array); 88 + 89 + if (idx >= (uint32_t)len) { 81 90 js_set(js, result, "done", js_true); 82 91 js_set(js, result, "value", js_mkundef()); 83 - } else { 84 - char idxstr[16]; 85 - snprintf(idxstr, sizeof(idxstr), "%d", idx); 86 - ant_value_t value = js_get(js, arr, idxstr); 87 - js_set(js, result, "value", value); 88 - js_set(js, result, "done", js_false); 89 - js_set(js, this_val, "__idx", js_mknum(idx + 1)); 92 + return result; 90 93 } 91 - 92 - return result; 93 - } 94 94 95 - static ant_value_t get_iterator_prototype(ant_t *js) { 96 - if (vtype(js->sym.iterator_proto) == T_OBJ) return js->sym.iterator_proto; 95 + ant_value_t value; 96 + switch (kind) { 97 + case ARR_ITER_KEYS: 98 + value = js_mknum((double)idx); 99 + break; 100 + case ARR_ITER_ENTRIES: { 101 + ant_value_t pair = js_mkarr(js); 102 + js_arr_push(js, pair, js_mknum((double)idx)); 103 + js_arr_push(js, pair, js_arr_get(js, array, (ant_offset_t)idx)); 104 + value = pair; 105 + break; 106 + } 107 + default: 108 + value = js_arr_get(js, array, (ant_offset_t)idx); 109 + break; 110 + } 97 111 98 - js->sym.iterator_proto = js_mkobj(js); 99 - js_set_proto_init(js->sym.iterator_proto, js->object); 100 - js_set_sym(js, js->sym.iterator_proto, g_iterator, js_mkfun(sym_this_cb)); 112 + js_set_slot(iter, SLOT_ITER_STATE, js_mknum((double)ARR_ITER_PACK(kind, idx + 1))); 113 + js_set(js, result, "done", js_false); 114 + js_set(js, result, "value", value); 101 115 102 - return js->sym.iterator_proto; 116 + return result; 103 117 } 104 118 105 119 static ant_value_t get_array_iterator_prototype(ant_t *js) { ··· 107 121 108 122 ant_value_t iterator_proto = get_iterator_prototype(js); 109 123 js->sym.array_iterator_proto = js_mkobj(js); 110 - js_set(js, js->sym.array_iterator_proto, "next", js_mkfun(iterator_next)); 124 + js_set(js, js->sym.array_iterator_proto, "next", js_mkfun(arr_iter_next)); 111 125 js_set_proto_init(js->sym.array_iterator_proto, iterator_proto); 112 - 126 + 113 127 return js->sym.array_iterator_proto; 114 128 } 115 129 116 - static ant_value_t array_iterator(ant_t *js, ant_value_t *args, int nargs) { 117 - ant_value_t arr = js_getthis(js); 118 - ant_value_t len_val = js_get(js, arr, "length"); 119 - int len = vtype(len_val) == T_NUM ? (int)js_getnum(len_val) : 0; 120 - 130 + ant_value_t make_array_iterator(ant_t *js, ant_value_t array, int kind) { 121 131 ant_value_t iter = js_mkobj(js); 122 - js_set(js, iter, "__arr", arr); 123 - js_set(js, iter, "__idx", js_mknum(0)); 124 - js_set(js, iter, "__len", js_mknum(len)); 132 + js_set_slot_wb(js, iter, SLOT_DATA, array); 133 + js_set_slot(iter, SLOT_ITER_STATE, js_mknum((double)ARR_ITER_PACK(kind, 0))); 125 134 js_set_proto_init(iter, get_array_iterator_prototype(js)); 126 - 127 135 return iter; 128 136 } 129 137 130 - static ant_value_t string_iterator_next(ant_t *js, ant_value_t *args, int nargs) { 131 - ant_value_t this_val = js_getthis(js); 132 - 133 - ant_value_t str = js_get(js, this_val, "__str"); 134 - ant_value_t idx_val = js_get(js, this_val, "__idx"); 135 - ant_value_t len_val = js_get(js, this_val, "__len"); 136 - 137 - int idx = (int)js_getnum(idx_val); 138 - int len = (int)js_getnum(len_val); 139 - 138 + static ant_value_t str_iter_next(ant_t *js, ant_value_t *args, int nargs) { 139 + ant_value_t iter = js->this_val; 140 + ant_value_t str = js_get_slot(iter, SLOT_DATA); 141 + ant_value_t idx_v = js_get_slot(iter, SLOT_ITER_STATE); 142 + int idx = (vtype(idx_v) == T_NUM) ? (int)js_getnum(idx_v) : 0; 143 + 144 + size_t slen; 145 + char *s = js_getstr(js, str, &slen); 140 146 ant_value_t result = js_mkobj(js); 141 - 142 - if (idx >= len) { 147 + 148 + if (idx >= (int)slen) { 143 149 js_set(js, result, "done", js_true); 144 150 js_set(js, result, "value", js_mkundef()); 145 - } else { 146 - char *s = js_getstr(js, str, NULL); 147 - unsigned char c = (unsigned char)s[idx]; 148 - 149 - int char_bytes = utf8_sequence_length(c); 150 - if (char_bytes < 1) char_bytes = 1; 151 - if (idx + char_bytes > len) char_bytes = len - idx; 152 - 153 - js_set(js, result, "value", js_mkstr(js, s + idx, (ant_offset_t)char_bytes)); 154 - js_set(js, result, "done", js_false); 155 - js_set(js, this_val, "__idx", js_mknum(idx + char_bytes)); 151 + return result; 156 152 } 153 + 154 + unsigned char c = (unsigned char)s[idx]; 155 + int char_bytes = utf8_sequence_length(c); 156 + if (char_bytes < 1) char_bytes = 1; 157 + if (idx + char_bytes > (int)slen) char_bytes = (int)slen - idx; 158 + 159 + js_set(js, result, "value", js_mkstr(js, s + idx, (ant_offset_t)char_bytes)); 160 + js_set(js, result, "done", js_false); 161 + js_set_slot(iter, SLOT_ITER_STATE, js_mknum(idx + char_bytes)); 157 162 158 163 return result; 159 164 } ··· 163 168 164 169 ant_value_t iterator_proto = get_iterator_prototype(js); 165 170 js->sym.string_iterator_proto = js_mkobj(js); 166 - js_set(js, js->sym.string_iterator_proto, "next", js_mkfun(string_iterator_next)); 171 + js_set(js, js->sym.string_iterator_proto, "next", js_mkfun(str_iter_next)); 167 172 js_set_proto_init(js->sym.string_iterator_proto, iterator_proto); 168 - 173 + 169 174 return js->sym.string_iterator_proto; 170 175 } 171 176 172 177 static ant_value_t string_iterator(ant_t *js, ant_value_t *args, int nargs) { 173 - ant_value_t str = js_getthis(js); 174 - size_t len; js_getstr(js, str, &len); 175 - 176 178 ant_value_t iter = js_mkobj(js); 177 - js_set(js, iter, "__str", str); 178 - js_set(js, iter, "__idx", js_mknum(0)); 179 - js_set(js, iter, "__len", js_mknum((double)len)); 179 + 180 + js_set_slot_wb(js, iter, SLOT_DATA, js->this_val); 181 + js_set_slot(iter, SLOT_ITER_STATE, js_mknum(0)); 180 182 js_set_proto_init(iter, get_string_iterator_prototype(js)); 181 183 182 184 return iter; ··· 240 242 241 243 ant_value_t func_symbol = js_obj_to_func(symbol_ctor); 242 244 js_set(js, js_glob(js), "Symbol", func_symbol); 243 - 245 + 244 246 // set internal types before ant module snapshot 245 - js_set_sym(js, rt->ant_obj, g_toStringTag, js_mkstr(js, "Ant", 3)); 246 - 247 247 ant_value_t array_ctor = js_get(js, js_glob(js), "Array"); 248 248 ant_value_t array_proto = js_get(js, array_ctor, "prototype"); 249 249 250 250 (void)get_array_iterator_prototype(js); 251 251 (void)get_string_iterator_prototype(js); 252 - js_set_sym(js, array_proto, g_iterator, js_mkfun(array_iterator)); 252 + 253 + js_set_sym(js, rt->ant_obj, g_toStringTag, js_mkstr(js, "Ant", 3)); 254 + js_set_sym(js, array_proto, g_iterator, js_get(js, array_proto, "values")); 253 255 254 256 ant_value_t array_unscopables = js_mkobj(js); 255 257 js_set(js, array_unscopables, "find", js_true);