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.

add Array.isTemplateObject

+66 -14
+1 -1
examples/results.txt
··· 1469 1469 compat-table/intl/Number.prototype.toLocaleString.js: OK 1470 1470 compat-table/intl/Object.prototype.toLocaleString.js: OK 1471 1471 compat-table/intl/String.prototype.localeCompare.js: OK 1472 - compat-table/next/Array.isTemplateObject.js: TypeError: undefined is not a function 1472 + compat-table/next/Array.isTemplateObject.js: OK 1473 1473 compat-table/next/AsyncDisposableStack.js: OK 1474 1474 compat-table/next/AsyncIterator.extends.js: OK 1475 1475 compat-table/next/AsyncIterator.from.async-iterable.js: OK
+2 -1
include/common.h
··· 133 133 BRAND_EVENTEMITTER, 134 134 BRAND_EVENTTARGET, 135 135 BRAND_DISPOSABLE_STACK, 136 - BRAND_ASYNC_DISPOSABLE_STACK 136 + BRAND_ASYNC_DISPOSABLE_STACK, 137 + BRAND_TEMPLATE_OBJECT 137 138 } object_brand_id_t; 138 139 139 140 static inline void *mantissa_chk(void *p, const char *func) {
+1
include/silver/opcode.h
··· 38 38 OP_DEF( GLOBAL, 1, 0, 1, none) /* push 'globalThis' (js->global) */ 39 39 OP_DEF( OBJECT, 1, 0, 1, none) /* push empty object {} */ 40 40 OP_DEF( ARRAY, 3, 0, 1, npop) /* push array from stack items */ 41 + OP_DEF( SET_BRAND, 2, 1, 1, u8) /* obj -> obj (brand id) */ 41 42 OP_DEF( REGEXP, 1, 2, 1, none) /* pattern flags -> regexp */ 42 43 OP_DEF( CLOSURE, 5, 0, 1, const) /* push closure from func pool */ 43 44
+6
src/ant.c
··· 10152 10152 return mkval(T_BOOL, vtype(args[0]) == T_ARR ? 1 : 0); 10153 10153 } 10154 10154 10155 + static ant_value_t builtin_Array_isTemplateObject(ant_params_t) { 10156 + if (nargs == 0) return js_false; 10157 + return js_bool(vtype(args[0]) == T_ARR && js_check_brand(args[0], BRAND_TEMPLATE_OBJECT)); 10158 + } 10159 + 10155 10160 typedef struct { 10156 10161 ant_value_t write_target; 10157 10162 ant_value_t result; ··· 14817 14822 set_slot(arr_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Array)); 14818 14823 js_setprop_readonly_nonconfigurable(js, arr_ctor_obj, "prototype", 9, array_proto); 14819 14824 defmethod(js, arr_ctor_obj, "isArray", 7, js_mkfun(builtin_Array_isArray)); 14825 + defmethod(js, arr_ctor_obj, "isTemplateObject", 16, js_mkfun(builtin_Array_isTemplateObject)); 14820 14826 defmethod(js, arr_ctor_obj, "from", 4, js_mkfun(builtin_Array_from)); 14821 14827 defmethod(js, arr_ctor_obj, "of", 2, js_mkfun(builtin_Array_of)); 14822 14828 js_setprop(js, arr_ctor_obj, js->length_str, tov(1.0));
+2
src/silver/compiler.c
··· 1709 1709 emit_op(c, OP_ROT3L); 1710 1710 emit_op(c, OP_CALL_METHOD); 1711 1711 emit_u16(c, 1); 1712 + emit_op(c, OP_SET_BRAND); 1713 + emit(c, BRAND_TEMPLATE_OBJECT); 1712 1714 emit_op(c, OP_DUP); 1713 1715 emit_op(c, OP_PUT_CONST); 1714 1716 emit_u32(c, (uint32_t)cache_idx);
+13 -12
src/silver/engine.c
··· 952 952 } 953 953 DISPATCH(); 954 954 955 - L_CONST: { sv_op_const(vm, func, ip); NEXT(5); } 956 - L_CONST_I8: { sv_op_const_i8(vm, ip); NEXT(2); } 957 - L_CONST8: { sv_op_const8(vm, func, ip); NEXT(2); } 958 - L_UNDEF: { sv_op_undef(vm); NEXT(1); } 959 - L_NULL: { sv_op_null(vm); NEXT(1); } 960 - L_TRUE: { sv_op_true(vm); NEXT(1); } 961 - L_FALSE: { sv_op_false(vm); NEXT(1); } 962 - L_THIS: { sv_op_this(vm, frame); NEXT(1); } 963 - L_GLOBAL: { sv_op_global(vm, js); NEXT(1); } 964 - L_OBJECT: { sv_op_object(vm, js, func, ip); NEXT(1); } 965 - L_ARRAY: { sv_op_array(vm, js, ip); NEXT(3); } 955 + L_CONST: { sv_op_const(vm, func, ip); NEXT(5); } 956 + L_CONST_I8: { sv_op_const_i8(vm, ip); NEXT(2); } 957 + L_CONST8: { sv_op_const8(vm, func, ip); NEXT(2); } 958 + L_UNDEF: { sv_op_undef(vm); NEXT(1); } 959 + L_NULL: { sv_op_null(vm); NEXT(1); } 960 + L_TRUE: { sv_op_true(vm); NEXT(1); } 961 + L_FALSE: { sv_op_false(vm); NEXT(1); } 962 + L_THIS: { sv_op_this(vm, frame); NEXT(1); } 963 + L_GLOBAL: { sv_op_global(vm, js); NEXT(1); } 964 + L_OBJECT: { sv_op_object(vm, js, func, ip); NEXT(1); } 965 + L_ARRAY: { sv_op_array(vm, js, ip); NEXT(3); } 966 + L_SET_BRAND: { sv_op_set_brand(vm, ip); NEXT(2); } 966 967 967 - L_REGEXP: { sv_op_regexp(vm, js); NEXT(1); } 968 + L_REGEXP: { sv_op_regexp(vm, js); NEXT(1); } 968 969 L_CLOSURE: { VM_CHECK(sv_op_closure(vm, js, frame, func, ip)); NEXT(5); } 969 970 970 971 L_POP: { sv_op_pop(vm); NEXT(1); }
+8
src/silver/ops/literals.h
··· 86 86 vm->stack[vm->sp++] = arr; 87 87 } 88 88 89 + static inline void sv_op_set_brand(sv_vm_t *vm, uint8_t *ip) { 90 + if (vm->sp <= 0) return; 91 + uint8_t brand = sv_get_u8(ip + 1); 92 + ant_value_t obj = vm->stack[vm->sp - 1]; 93 + if (is_object_type(obj)) 94 + js_set_slot(obj, SLOT_BRAND, js_mknum((double)brand)); 95 + } 96 + 89 97 // TODO: reduce duplication with regex.c 90 98 static inline void sv_op_regexp(sv_vm_t *vm, ant_t *js) { 91 99 ant_value_t pattern = vm->stack[vm->sp - 2];
+33
tests/test_array_is_template_object.cjs
··· 1 + const assert = (cond, msg) => { 2 + if (!cond) throw new Error(msg); 3 + }; 4 + 5 + let captured; 6 + function tag(strings) { 7 + captured = strings; 8 + return strings; 9 + } 10 + 11 + const first = tag`a${1}b`; 12 + const sameTextDifferentSite = tag`a${2}b`; 13 + 14 + function sameSite(value) { 15 + return tag`a${value}b`; 16 + } 17 + 18 + const sameSiteFirst = sameSite(1); 19 + const sameSiteSecond = sameSite(2); 20 + 21 + assert(typeof Array.isTemplateObject === "function", "Array.isTemplateObject should exist"); 22 + assert(Array.isTemplateObject(first) === true, "tagged template strings array should be a template object"); 23 + assert(Array.isTemplateObject(first.raw) === false, "raw array should not be a template object"); 24 + assert(Array.isTemplateObject([]) === false, "ordinary array should not be a template object"); 25 + assert(Array.isTemplateObject(Object.freeze(["a", "b"])) === false, "frozen ordinary array should not be a template object"); 26 + assert(Array.isTemplateObject({ raw: ["a"] }) === false, "ordinary object should not be a template object"); 27 + assert(Array.isTemplateObject("not an array") === false, "primitive should not be a template object"); 28 + assert(Array.isTemplateObject() === false, "missing argument should return false"); 29 + assert(first !== sameTextDifferentSite, "different template sites should not reuse the same object"); 30 + assert(sameSiteFirst === sameSiteSecond, "same template site should reuse the same object"); 31 + assert(captured === sameSiteSecond, "tag should receive cached template object"); 32 + 33 + console.log("Array.isTemplateObject tests ok");