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.

iterable weakmap regression fix

+172 -86
+3 -3
examples/results.txt
··· 463 463 compat-table/es6/Map.constructor-arguments.js: OK 464 464 compat-table/es6/Map.constructor-invokes-set.js: failed 465 465 compat-table/es6/Map.constructor-requires-new.js: OK 466 - compat-table/es6/Map.iterator-closing.js: failed 466 + compat-table/es6/Map.iterator-closing.js: OK 467 467 compat-table/es6/Map.iterator-prototype-chain.js: OK 468 468 compat-table/es6/Map.js: OK 469 469 compat-table/es6/Map.prototype-not-instance.js: failed ··· 624 624 compat-table/es6/WeakMap.constructor-invokes-set.js: failed 625 625 compat-table/es6/WeakMap.constructor-requires-new.js: OK 626 626 compat-table/es6/WeakMap.frozen-keys.js: OK 627 - compat-table/es6/WeakMap.iterator-closing.js: failed 627 + compat-table/es6/WeakMap.iterator-closing.js: OK 628 628 compat-table/es6/WeakMap.js: OK 629 629 compat-table/es6/WeakMap.no-clear.js: OK 630 630 compat-table/es6/WeakMap.prototype-not-instance.js: failed ··· 635 635 compat-table/es6/WeakSet.constructor-arguments.js: OK 636 636 compat-table/es6/WeakSet.constructor-invokes-add.js: failed 637 637 compat-table/es6/WeakSet.constructor-requires-new.js: OK 638 - compat-table/es6/WeakSet.iterator-closing.js: failed 638 + compat-table/es6/WeakSet.iterator-closing.js: OK 639 639 compat-table/es6/WeakSet.js: OK 640 640 compat-table/es6/WeakSet.no-clear.js: OK 641 641 compat-table/es6/WeakSet.prototype-not-instance.js: failed
+139 -83
src/modules/collections.c
··· 182 182 return true; 183 183 } 184 184 185 + static ant_value_t map_init_from_iterable(ant_t *js, map_entry_t **map_head, ant_value_t iterable) { 186 + js_iter_t it; 187 + if (!js_iter_open(js, iterable, &it)) { 188 + return js_mkerr_typed(js, JS_ERR_TYPE, "Map constructor argument is not iterable"); 189 + } 190 + 191 + ant_value_t entry; 192 + while (js_iter_next(js, &it, &entry)) { 193 + uint8_t entry_t = vtype(entry); 194 + if (entry_t != T_ARR && entry_t != T_OBJ) { 195 + js_iter_close(js, &it); 196 + return js_mkerr_typed(js, JS_ERR_TYPE, "Map iterable entries must be pair sequences"); 197 + } 198 + 199 + ant_offset_t entry_len = js_arr_len(js, entry); 200 + if (entry_len < 2) { 201 + js_iter_close(js, &it); 202 + return js_mkerr_typed(js, JS_ERR_TYPE, "Map iterable entries must have at least 2 items"); 203 + } 204 + 205 + ant_value_t key = normalize_map_key(js_arr_get(js, entry, 0)); 206 + ant_value_t value = js_arr_get(js, entry, 1); 207 + if (!map_store_entry(js, map_head, key, key, value)) { 208 + js_iter_close(js, &it); 209 + return js_mkerr(js, "out of memory"); 210 + }} 211 + 212 + return js_mkundef(); 213 + } 214 + 215 + static ant_value_t set_init_from_iterable(ant_t *js, set_entry_t **set_head, ant_value_t iterable) { 216 + js_iter_t it; 217 + if (!js_iter_open(js, iterable, &it)) { 218 + return js_mkerr_typed(js, JS_ERR_TYPE, "Set constructor argument is not iterable"); 219 + } 220 + 221 + ant_value_t value; 222 + while (js_iter_next(js, &it, &value)) if (!set_store_entry(js, set_head, value)) { 223 + js_iter_close(js, &it); 224 + return js_mkerr(js, "out of memory"); 225 + } 226 + 227 + return js_mkundef(); 228 + } 229 + 230 + static ant_value_t weakmap_init_from_iterable(ant_t *js, weakmap_entry_t **wm_head, ant_value_t iterable) { 231 + js_iter_t it; 232 + if (!js_iter_open(js, iterable, &it)) { 233 + return js_mkerr_typed(js, JS_ERR_TYPE, "WeakMap constructor argument is not iterable"); 234 + } 235 + 236 + ant_value_t entry; 237 + while (js_iter_next(js, &it, &entry)) { 238 + uint8_t entry_t = vtype(entry); 239 + if (entry_t != T_ARR && entry_t != T_OBJ) { 240 + js_iter_close(js, &it); 241 + return js_mkerr_typed(js, JS_ERR_TYPE, "WeakMap iterable entries must be pair sequences"); 242 + } 243 + 244 + ant_offset_t entry_len = js_arr_len(js, entry); 245 + if (entry_len < 2) { 246 + js_iter_close(js, &it); 247 + return js_mkerr_typed(js, JS_ERR_TYPE, "WeakMap iterable entries must have at least 2 items"); 248 + } 249 + 250 + ant_value_t key = js_arr_get(js, entry, 0); 251 + ant_value_t value = js_arr_get(js, entry, 1); 252 + if (!is_object_type(key)) { 253 + js_iter_close(js, &it); 254 + return js_mkerr(js, "WeakMap key must be an object"); 255 + } 256 + 257 + weakmap_entry_t *wm_entry; 258 + HASH_FIND(hh, *wm_head, &key, sizeof(ant_value_t), wm_entry); 259 + if (wm_entry) { 260 + wm_entry->value = value; 261 + continue; 262 + } 263 + 264 + wm_entry = ant_calloc(sizeof(weakmap_entry_t)); 265 + if (!wm_entry) { 266 + js_iter_close(js, &it); 267 + return js_mkerr(js, "out of memory"); 268 + } 269 + 270 + wm_entry->key_obj = key; 271 + wm_entry->value = value; 272 + HASH_ADD(hh, *wm_head, key_obj, sizeof(ant_value_t), wm_entry); 273 + } 274 + 275 + return js_mkundef(); 276 + } 277 + 278 + static ant_value_t weakset_init_from_iterable(ant_t *js, weakset_entry_t **ws_head, ant_value_t iterable) { 279 + js_iter_t it; 280 + if (!js_iter_open(js, iterable, &it)) { 281 + return js_mkerr_typed(js, JS_ERR_TYPE, "WeakSet constructor argument is not iterable"); 282 + } 283 + 284 + ant_value_t value; 285 + while (js_iter_next(js, &it, &value)) { 286 + if (!is_object_type(value)) { 287 + js_iter_close(js, &it); 288 + return js_mkerr(js, "WeakSet value must be an object"); 289 + } 290 + 291 + weakset_entry_t *entry; 292 + HASH_FIND(hh, *ws_head, &value, sizeof(ant_value_t), entry); 293 + if (entry) continue; 294 + 295 + entry = ant_calloc(sizeof(weakset_entry_t)); 296 + if (!entry) { 297 + js_iter_close(js, &it); 298 + return js_mkerr(js, "out of memory"); 299 + } 300 + 301 + entry->value_obj = value; 302 + HASH_ADD(hh, *ws_head, value_obj, sizeof(ant_value_t), entry); 303 + } 304 + 305 + return js_mkundef(); 306 + } 307 + 185 308 map_entry_t **get_map_from_obj(ant_t *js, ant_value_t obj) { 186 309 (void)js; 187 310 ant_object_t *ptr = js_obj_ptr(obj); ··· 851 974 if (!map_head) return js_mkerr(js, "out of memory"); 852 975 *map_head = NULL; 853 976 854 - if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) { 977 + if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) 855 978 js_set_slot(map_obj, SLOT_CTOR, js->new_target); 856 - } 857 979 js_set_slot(map_obj, SLOT_DATA, ANT_PTR(map_head)); 858 980 859 - if (nargs == 0 || vtype(args[0]) != T_ARR) return map_obj; 860 - 861 - ant_value_t iterable = args[0]; 862 - ant_offset_t length = js_arr_len(js, iterable); 863 - 864 - for (ant_offset_t i = 0; i < length; i++) { 865 - ant_value_t entry = js_arr_get(js, iterable, i); 866 - if (vtype(entry) != T_ARR) continue; 867 - 868 - ant_offset_t entry_len = js_arr_len(js, entry); 869 - if (entry_len < 2) continue; 870 - 871 - ant_value_t key = normalize_map_key(js_arr_get(js, entry, 0)); 872 - ant_value_t value = js_arr_get(js, entry, 1); 873 - if (!map_store_entry(js, map_head, key, key, value)) 874 - return js_mkerr(js, "out of memory"); 875 - } 981 + if (nargs == 0 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return map_obj; 982 + ant_value_t init_result = map_init_from_iterable(js, map_head, args[0]); 983 + if (is_err(init_result)) return init_result; 876 984 877 985 return map_obj; 878 986 } ··· 896 1004 if (!set_head) return js_mkerr(js, "out of memory"); 897 1005 *set_head = NULL; 898 1006 899 - if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) { 1007 + if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) 900 1008 js_set_slot(set_obj, SLOT_CTOR, js->new_target); 901 - } 902 1009 js_set_slot(set_obj, SLOT_DATA, ANT_PTR(set_head)); 903 1010 904 - if (nargs == 0 || vtype(args[0]) != T_ARR) return set_obj; 905 - 906 - ant_value_t iterable = args[0]; 907 - ant_offset_t length = js_arr_len(js, iterable); 908 - 909 - for (ant_offset_t i = 0; i < length; i++) { 910 - ant_value_t value = js_arr_get(js, iterable, i); 911 - if (!set_store_entry(js, set_head, value)) return js_mkerr(js, "out of memory"); 912 - } 1011 + if (nargs == 0 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return set_obj; 1012 + ant_value_t init_result = set_init_from_iterable(js, set_head, args[0]); 1013 + if (is_err(init_result)) return init_result; 913 1014 914 1015 return set_obj; 915 1016 } ··· 933 1034 if (!wm_head) return js_mkerr(js, "out of memory"); 934 1035 *wm_head = NULL; 935 1036 936 - if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) { 1037 + if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) 937 1038 js_set_slot(wm_obj, SLOT_CTOR, js->new_target); 938 - } 939 1039 js_set_slot(wm_obj, SLOT_DATA, ANT_PTR(wm_head)); 940 1040 941 - if (nargs == 0 || vtype(args[0]) != T_ARR) return wm_obj; 942 - 943 - ant_value_t iterable = args[0]; 944 - ant_offset_t length = js_arr_len(js, iterable); 945 - 946 - for (ant_offset_t i = 0; i < length; i++) { 947 - ant_value_t entry = js_arr_get(js, iterable, i); 948 - if (vtype(entry) != T_ARR) continue; 949 - 950 - ant_offset_t entry_len = js_arr_len(js, entry); 951 - if (entry_len < 2) continue; 952 - 953 - ant_value_t key = js_arr_get(js, entry, 0); 954 - ant_value_t value = js_arr_get(js, entry, 1); 955 - if (!is_object_type(key)) return js_mkerr(js, "WeakMap key must be an object"); 956 - 957 - weakmap_entry_t *wm_entry; 958 - HASH_FIND(hh, *wm_head, &key, sizeof(ant_value_t), wm_entry); 959 - 960 - if (wm_entry) { 961 - wm_entry->value = value; 962 - continue; 963 - } 964 - 965 - wm_entry = ant_calloc(sizeof(weakmap_entry_t)); 966 - if (!wm_entry) return js_mkerr(js, "out of memory"); 967 - 968 - wm_entry->key_obj = key; 969 - wm_entry->value = value; 970 - HASH_ADD(hh, *wm_head, key_obj, sizeof(ant_value_t), wm_entry); 971 - } 1041 + if (nargs == 0 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return wm_obj; 1042 + ant_value_t init_result = weakmap_init_from_iterable(js, wm_head, args[0]); 1043 + if (is_err(init_result)) return init_result; 972 1044 973 1045 return wm_obj; 974 1046 } ··· 992 1064 if (!ws_head) return js_mkerr(js, "out of memory"); 993 1065 *ws_head = NULL; 994 1066 995 - if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) { 1067 + if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) 996 1068 js_set_slot(ws_obj, SLOT_CTOR, js->new_target); 997 - } 998 1069 js_set_slot(ws_obj, SLOT_DATA, ANT_PTR(ws_head)); 999 1070 1000 - if (nargs == 0 || vtype(args[0]) != T_ARR) return ws_obj; 1001 - 1002 - ant_value_t iterable = args[0]; 1003 - ant_offset_t length = js_arr_len(js, iterable); 1004 - 1005 - for (ant_offset_t i = 0; i < length; i++) { 1006 - ant_value_t value = js_arr_get(js, iterable, i); 1007 - if (!is_object_type(value)) return js_mkerr(js, "WeakSet value must be an object"); 1008 - 1009 - weakset_entry_t *entry; 1010 - HASH_FIND(hh, *ws_head, &value, sizeof(ant_value_t), entry); 1011 - if (entry) continue; 1012 - 1013 - entry = ant_calloc(sizeof(weakset_entry_t)); 1014 - if (!entry) return js_mkerr(js, "out of memory"); 1015 - entry->value_obj = value; 1016 - HASH_ADD(hh, *ws_head, value_obj, sizeof(ant_value_t), entry); 1017 - } 1071 + if (nargs == 0 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return ws_obj; 1072 + ant_value_t init_result = weakset_init_from_iterable(js, ws_head, args[0]); 1073 + if (is_err(init_result)) return init_result; 1018 1074 1019 1075 return ws_obj; 1020 1076 }
+30
tests/test_collections_constructor_iterables.cjs
··· 1 + function assert(condition, message) { 2 + if (!condition) throw new Error(message); 3 + } 4 + 5 + const map = new Map([ 6 + ['x', 1], 7 + ['y', 2], 8 + ]); 9 + const mapCopy = new Map(map); 10 + const mapNull = new Map(null); 11 + const mapUndef = new Map(undefined); 12 + 13 + assert(mapCopy.size === 2, `expected copied map size 2, got ${mapCopy.size}`); 14 + assert(mapCopy.get('x') === 1, 'expected copied map to contain x => 1'); 15 + assert(mapCopy.get('y') === 2, 'expected copied map to contain y => 2'); 16 + assert(mapNull.size === 0, `expected null map size 0, got ${mapNull.size}`); 17 + assert(mapUndef.size === 0, `expected undefined map size 0, got ${mapUndef.size}`); 18 + 19 + const set = new Set(['a', 'b']); 20 + const setCopy = new Set(set); 21 + const setNull = new Set(null); 22 + const setUndef = new Set(undefined); 23 + 24 + assert(setCopy.size === 2, `expected copied set size 2, got ${setCopy.size}`); 25 + assert(setCopy.has('a'), 'expected copied set to contain a'); 26 + assert(setCopy.has('b'), 'expected copied set to contain b'); 27 + assert(setNull.size === 0, `expected null set size 0, got ${setNull.size}`); 28 + assert(setUndef.size === 0, `expected undefined set size 0, got ${setUndef.size}`); 29 + 30 + console.log('collections constructor iterables ok');