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 object enumeration handling for exotic objects

+89 -38
+89 -38
src/ant.c
··· 5252 5252 enum obj_enum_mode { 5253 5253 OBJ_ENUM_KEYS, 5254 5254 OBJ_ENUM_VALUES, 5255 - OBJ_ENUM_ENTRIES, 5256 - OBJ_ENUM_KEYS_ALL 5255 + OBJ_ENUM_ENTRIES 5257 5256 }; 5258 5257 5259 5258 static ant_value_t map_to_entry(ant_t *js, ant_value_t key, ant_value_t val) { ··· 5290 5289 char idxstr[16]; size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)i); 5291 5290 ant_value_t key_val = js_mkstr(js, idxstr, idxlen); 5292 5291 5293 - if (mode == OBJ_ENUM_KEYS || mode == OBJ_ENUM_KEYS_ALL) arr_set(js, arr, idx, key_val); 5292 + if (mode == OBJ_ENUM_KEYS) arr_set(js, arr, idx, key_val); 5294 5293 else if (mode == OBJ_ENUM_VALUES) arr_set(js, arr, idx, v); 5295 5294 else arr_set(js, arr, idx, map_to_entry(js, key_val, v)); 5296 5295 ··· 5310 5309 5311 5310 if (is_internal_prop(key, klen)) continue; 5312 5311 if (is_arr && is_array_index(key, klen)) { 5313 - ant_offset_t doff = get_dense_buf(obj); 5314 - if (doff) { 5315 - unsigned long pidx = 0; 5316 - for (ant_offset_t ci = 0; ci < klen; ci++) pidx = pidx * 10 + (key[ci] - '0'); 5317 - if (pidx < dense_iterable_length(js, obj)) continue; 5318 - } 5319 - } 5320 - 5321 - if (mode != OBJ_ENUM_KEYS_ALL) { 5322 - bool should_include = (ant_shape_get_attrs(ptr->shape, i) & ANT_PROP_ATTR_ENUMERABLE) != 0; 5323 - if (should_include && ptr->is_exotic) { 5324 - descriptor_entry_t *desc = lookup_descriptor(js_as_obj(obj), key, (size_t)klen); 5325 - if (desc) should_include = desc->enumerable; 5326 - } 5327 - if (!should_include) continue; 5312 + ant_offset_t doff = get_dense_buf(obj); 5313 + if (doff) { 5314 + unsigned long pidx = 0; 5315 + for (ant_offset_t ci = 0; ci < klen; ci++) pidx = pidx * 10 + (key[ci] - '0'); 5316 + if (pidx < dense_iterable_length(js, obj)) continue; 5317 + }} 5318 + 5319 + bool should_include = (ant_shape_get_attrs(ptr->shape, i) & ANT_PROP_ATTR_ENUMERABLE) != 0; 5320 + if (should_include && ptr->is_exotic) { 5321 + descriptor_entry_t *desc = lookup_descriptor(js_as_obj(obj), key, (size_t)klen); 5322 + if (desc) should_include = desc->enumerable; 5328 5323 } 5324 + if (!should_include) continue; 5329 5325 5330 5326 ant_value_t key_val = js_mkstr(js, key, (size_t)klen); 5331 - if (mode == OBJ_ENUM_KEYS || mode == OBJ_ENUM_KEYS_ALL) arr_set(js, arr, idx, key_val); 5327 + if (mode == OBJ_ENUM_KEYS) arr_set(js, arr, idx, key_val); 5332 5328 else if (mode == OBJ_ENUM_VALUES) arr_set(js, arr, idx, val); 5333 5329 else arr_set(js, arr, idx, map_to_entry(js, key_val, val)); 5334 5330 ··· 5439 5435 5440 5436 for (int depth = 0; is_object_type(cur) && depth < MAX_PROTO_CHAIN_DEPTH; depth++) { 5441 5437 GC_ROOT_SAVE(iter_mark, js); 5442 - ant_value_t all_keys = object_enum(js, cur, OBJ_ENUM_KEYS_ALL); 5443 - GC_ROOT_PIN(js, all_keys); 5444 - 5445 - if (is_err(all_keys)) { GC_ROOT_RESTORE(js, iter_mark); return all_keys; } 5446 - if (vtype(all_keys) != T_ARR) goto next; 5447 - 5448 - ant_offset_t len = js_arr_len(js, all_keys); 5449 - for (ant_offset_t i = 0; i < len; i++) { 5450 - ant_value_t key = js_arr_get(js, all_keys, i); 5438 + ant_value_t as_cur = (vtype(cur) == T_FUNC) ? js_func_obj(cur) : cur; 5439 + ant_object_t *cur_ptr = js_obj_ptr(as_cur); 5440 + ant_value_t key, r, proto; 5441 + ant_offset_t doff, dense_len, klen; 5442 + bool is_arr; 5443 + 5444 + if (!cur_ptr) goto next_proto; 5445 + if (!cur_ptr->is_exotic || !cur_ptr->exotic_keys) goto shape_props; 5446 + 5447 + { 5448 + ant_value_t ekeys = cur_ptr->exotic_keys(js, as_cur); 5449 + GC_ROOT_PIN(js, ekeys); 5450 + if (vtype(ekeys) != T_ARR) goto next_proto; 5451 + ant_offset_t elen = js_arr_len(js, ekeys); 5452 + for (ant_offset_t i = 0; i < elen; i++) { 5453 + key = js_arr_get(js, ekeys, i); 5454 + GC_ROOT_PIN(js, key); 5455 + r = for_in_keys_add(js, out, seen, key); 5456 + if (is_err(r)) goto err; 5457 + } 5458 + } 5459 + goto next_proto; 5460 + 5461 + shape_props: 5462 + if (!cur_ptr->shape) goto next_proto; 5463 + is_arr = (vtype(as_cur) == T_ARR); 5464 + if (!is_arr) goto shape_iter; 5465 + 5466 + doff = get_dense_buf(as_cur); 5467 + dense_len = doff ? dense_iterable_length(js, as_cur) : 0; 5468 + for (ant_offset_t i = 0; i < dense_len; i++) { 5469 + if (is_empty_slot(dense_get(doff, i))) continue; 5470 + char idxstr[16]; 5471 + size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)i); 5472 + key = js_mkstr(js, idxstr, idxlen); 5473 + GC_ROOT_PIN(js, key); 5474 + r = for_in_keys_add(js, out, seen, key); 5475 + if (is_err(r)) goto err; 5476 + } 5477 + 5478 + shape_iter: 5479 + for (uint32_t i = 0; i < ant_shape_count(cur_ptr->shape); i++) { 5480 + const ant_shape_prop_t *prop = ant_shape_prop_at(cur_ptr->shape, i); 5481 + if (!prop || prop->type == ANT_SHAPE_KEY_SYMBOL) continue; 5482 + if (i >= cur_ptr->prop_count) continue; 5483 + 5484 + const char *kstr = prop->key.interned; 5485 + klen = (ant_offset_t)strlen(kstr); 5486 + if (is_internal_prop(kstr, klen)) continue; 5487 + 5488 + if (is_arr && is_array_index(kstr, klen)) { 5489 + doff = get_dense_buf(as_cur); 5490 + if (doff) { 5491 + unsigned long pidx = 0; 5492 + for (ant_offset_t ci = 0; ci < klen; ci++) pidx = pidx * 10 + (kstr[ci] - '0'); 5493 + if (pidx < (unsigned long)dense_iterable_length(js, as_cur)) continue; 5494 + }} 5495 + 5496 + bool enumerable = (ant_shape_get_attrs(cur_ptr->shape, i) & ANT_PROP_ATTR_ENUMERABLE) != 0; 5497 + if (cur_ptr->is_exotic) { 5498 + descriptor_entry_t *desc = lookup_descriptor(js_as_obj(as_cur), kstr, (size_t)klen); 5499 + if (desc) enumerable = desc->enumerable; 5500 + } 5501 + 5502 + key = js_mkstr(js, kstr, (size_t)klen); 5451 5503 GC_ROOT_PIN(js, key); 5452 - 5453 - prop_meta_t meta; 5454 - ant_offset_t klen = 0; 5455 - const char *kptr = (const char *)(uintptr_t)vstr(js, key, &klen); 5456 - bool enumerable = lookup_string_prop_meta(js, cur, kptr, klen, &meta) && meta.enumerable; 5457 - 5458 - ant_value_t r = for_in_keys_add(js, enumerable ? out : js_mkundef(), seen, key); 5459 - if (is_err(r)) { GC_ROOT_RESTORE(js, iter_mark); return r; } 5504 + r = for_in_keys_add(js, enumerable ? out : js_mkundef(), seen, key); 5505 + if (is_err(r)) goto err; 5460 5506 } 5461 5507 5462 - next: 5508 + next_proto: 5463 5509 GC_ROOT_RESTORE(js, iter_mark); 5464 - ant_value_t proto = js_get_proto(js, cur); 5510 + proto = js_get_proto(js, cur); 5465 5511 if (!is_object_type(proto)) break; 5466 5512 cur = proto; 5513 + continue; 5514 + err: 5515 + GC_ROOT_RESTORE(js, iter_mark); 5516 + return r; 5467 5517 } 5518 + 5468 5519 return out; 5469 5520 } 5470 5521