MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix array prototype regressions in classes

+45 -20
-1
include/internal.h
··· 378 378 ant_offset_t vstrlen(ant_t *js, ant_value_t value); 379 379 ant_offset_t str_len_fast(ant_t *js, ant_value_t str); 380 380 381 - ant_value_t mkarr(ant_t *js); 382 381 ant_value_t mkval(uint8_t type, uint64_t data); 383 382 ant_value_t mkobj(ant_t *js, ant_offset_t parent); 384 383 ant_value_t js_mkobj_with_inobj_limit(ant_t *js, uint8_t inobj_limit);
+10 -6
src/ant.c
··· 2349 2349 return mkobj_with_inobj_limit(js, 0, inobj_limit); 2350 2350 } 2351 2351 2352 - ant_value_t mkarr(ant_t *js) { 2352 + static ant_value_t alloc_array_with_proto(ant_t *js, ant_value_t proto) { 2353 2353 ant_object_t *obj = obj_alloc(js, T_ARR, (uint8_t)ANT_INOBJ_MAX_SLOTS); 2354 2354 if (!obj) return js_mkerr(js, "oom"); 2355 + 2355 2356 ant_value_t arr = mkval(T_ARR, (uintptr_t)obj); 2356 - ant_value_t array_proto = js->array_proto; 2357 - if (vtype(array_proto) == T_OBJ) js_set_proto_init(arr, array_proto); 2357 + if (is_object_type(proto)) js_set_proto_init(arr, proto); 2358 2358 2359 2359 obj->u.array.cap = MAX_DENSE_INITIAL_CAP; 2360 2360 obj->u.array.len = 0; 2361 2361 obj->u.array.data = malloc(sizeof(*obj->u.array.data) * (size_t)obj->u.array.cap); 2362 + 2362 2363 if (obj->u.array.data) { 2363 2364 for (uint32_t i = 0; i < obj->u.array.cap; i++) obj->u.array.data[i] = T_EMPTY; 2364 2365 obj->fast_array = 1; ··· 2369 2370 } 2370 2371 2371 2372 return arr; 2373 + } 2374 + 2375 + static inline ant_value_t mkarr(ant_t *js) { 2376 + return alloc_array_with_proto(js, js->array_proto); 2372 2377 } 2373 2378 2374 2379 ant_value_t js_mkarr(ant_t *js) { ··· 12488 12493 ant_value_t function_proto = js_obj_to_func(function_proto_obj); 12489 12494 set_slot(glob, SLOT_FUNC_PROTO, function_proto); 12490 12495 12491 - ant_value_t array_proto = js_mkobj(js); 12492 - set_proto(js, array_proto, object_proto); 12496 + ant_value_t array_proto = alloc_array_with_proto(js, object_proto); 12493 12497 12494 12498 defmethod(js, array_proto, "push", 4, js_mkfun(builtin_array_push)); 12495 12499 defmethod(js, array_proto, "pop", 3, js_mkfun(builtin_array_pop)); ··· 12814 12818 js_set_descriptor(js, js_as_obj(function_proto), "constructor", 11, JS_DESC_W | JS_DESC_C); 12815 12819 12816 12820 js_setprop(js, array_proto, js_mkstr(js, "constructor", 11), arr_ctor_func); 12817 - js_set_descriptor(js, array_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 12821 + js_set_descriptor(js, js_as_obj(array_proto), "constructor", 11, JS_DESC_W | JS_DESC_C); 12818 12822 12819 12823 js_setprop(js, string_proto, js_mkstr(js, "constructor", 11), str_ctor_func); 12820 12824 js_set_descriptor(js, string_proto, "constructor", 11, JS_DESC_W | JS_DESC_C);
+2 -2
src/errors.c
··· 917 917 static bool callsite_visit_frame(ant_t *js, const js_vm_frame_view_t *view, void *ctx) { 918 918 callsite_build_ctx_t *c = (callsite_build_ctx_t *)ctx; 919 919 920 - ant_value_t data = mkarr(js); 920 + ant_value_t data = js_mkarr(js); 921 921 js_arr_push(js, data, js_mkstr(js, view->file, strlen(view->file))); 922 922 js_arr_push(js, data, js_mknum((double)view->line)); 923 923 js_arr_push(js, data, js_mknum((double)view->col)); ··· 948 948 js_set(js, proto, "getThis", js_mkfun(callsite_getThis)); 949 949 js_set(js, proto, "toString", js_mkfun(callsite_toString)); 950 950 951 - ant_value_t arr = mkarr(js); 951 + ant_value_t arr = js_mkarr(js); 952 952 callsite_build_ctx_t ctx = { js, arr, proto }; 953 953 954 954 const char *file = (js->errsite.valid && js->errsite.filename)
+2 -2
src/modules/collections.c
··· 713 713 ant_value_t fr_proto = js_get_ctor_proto(js, "FinalizationRegistry", 20); 714 714 if (is_special_object(fr_proto)) js_set_proto_init(fr_obj, fr_proto); 715 715 716 - js_set_slot(fr_obj, SLOT_MAP, mkarr(js)); 716 + js_set_slot(fr_obj, SLOT_MAP, js_mkarr(js)); 717 717 js_set_slot(fr_obj, SLOT_DATA, args[0]); 718 718 719 719 return fr_obj; ··· 738 738 ant_value_t registrations = js_get_slot(this_val, SLOT_MAP); 739 739 if (vtype(registrations) != T_ARR) return js_mkundef(); 740 740 741 - ant_value_t entry = mkarr(js); 741 + ant_value_t entry = js_mkarr(js); 742 742 ant_offset_t len = js_arr_len(js, registrations); 743 743 744 744 char idx[16];
+4 -5
src/modules/reflect.c
··· 249 249 ant_value_t target = args[0]; 250 250 ant_value_t proto = args[1]; 251 251 252 - int t = vtype(target); 253 - if (t != T_OBJ && t != T_FUNC) return js_false; 254 - 255 - int pt = vtype(proto); 256 - if (pt != T_OBJ && pt != T_FUNC && pt != T_NULL) return js_false; 252 + if (!is_object_type(target)) return js_false; 253 + if (!is_object_type(proto) && vtype(proto) != T_NULL) return js_false; 254 + if (vtype(proto) != T_NULL && proto_chain_contains(js, proto, target)) return js_false; 257 255 258 256 js_set_proto_wb(js, target, proto); 257 + 259 258 return js_true; 260 259 } 261 260
+3 -3
src/modules/regex.c
··· 1010 1010 bool full_unicode = js_truthy(js, unicode_val); 1011 1011 js_setprop(js, rx, js_mkstr(js, "lastIndex", 9), tov(0)); 1012 1012 1013 - ant_value_t A = mkarr(js); 1013 + ant_value_t A = js_mkarr(js); 1014 1014 if (is_err(A)) return A; 1015 1015 ant_offset_t n = 0; 1016 1016 ··· 1179 1179 js_setprop(js, rx, js_mkstr(js, "lastIndex", 9), tov(0)); 1180 1180 } 1181 1181 1182 - ant_value_t results = mkarr(js); 1182 + ant_value_t results = js_mkarr(js); 1183 1183 if (is_err(results)) return results; 1184 1184 ant_offset_t nresults = 0; 1185 1185 ··· 1374 1374 ant_value_t splitter = regexp_species_construct(js, rx, C, ctor_args, 2); 1375 1375 if (is_err(splitter)) return splitter; 1376 1376 1377 - ant_value_t A = mkarr(js); 1377 + ant_value_t A = js_mkarr(js); 1378 1378 if (is_err(A)) return A; 1379 1379 ant_offset_t lengthA = 0; 1380 1380
+2 -1
src/silver/ops/objects.h
··· 260 260 261 261 if (vtype(ctor) == T_FUNC) js_mark_constructor(js_func_obj(ctor), true); 262 262 setprop_interned(js, proto, "constructor", 11, ctor); 263 - setprop_interned(js, ctor, "prototype", 9, proto); 263 + ant_value_t ctor_obj = (vtype(ctor) == T_FUNC) ? js_func_obj(ctor) : ctor; 264 + js_mkprop_fast(js, ctor_obj, "prototype", 9, proto); 264 265 if (a && a->len > 0) 265 266 setprop_cstr(js, ctor, "name", 4, js_mkstr(js, a->str, a->len)); 266 267
+22
tests/test_array_proto_subclassing.cjs
··· 1 + function assert(cond, msg) { 2 + if (!cond) throw new Error(msg); 3 + } 4 + 5 + console.log("array prototype and subclassing regression"); 6 + 7 + assert(Array.isArray(Array.prototype), "Array.prototype should be an array exotic"); 8 + assert(Object.getPrototypeOf(Array.prototype) === Object.prototype, "Array.prototype should inherit from Object.prototype"); 9 + 10 + class C extends Array {} 11 + const c = new C(1, 2, 3); 12 + 13 + assert(c instanceof C, "Array subclass instances should preserve subclass identity"); 14 + assert(c instanceof Array, "Array subclass instances should still be arrays"); 15 + assert(c.concat(4) instanceof C, "concat should preserve Array subclass"); 16 + assert(c.map(x => x) instanceof C, "map should preserve Array subclass"); 17 + assert(c.filter(() => true) instanceof C, "filter should preserve Array subclass"); 18 + assert(c.slice(0) instanceof C, "slice should preserve Array subclass"); 19 + assert(C.from([1, 2]) instanceof C, "Array.from on subclass should preserve subclass"); 20 + assert(C.of(1, 2) instanceof C, "Array.of on subclass should preserve subclass"); 21 + 22 + console.log("PASS");