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.

fixed the ES2016 conformance regressions

+237 -23
+5 -5
examples/results.txt
··· 1191 1191 compat-table/es6/well-known.toStringTag.misc-builtins.js: OK 1192 1192 compat-table/es6/well-known.toStringTag.new-builtins.js: failed 1193 1193 compat-table/es6/well-known.unscopables.js: OK 1194 - compat-table/es2016/Array.prototype.includes.generic.js: failed 1194 + compat-table/es2016/Array.prototype.includes.generic.js: OK 1195 1195 compat-table/es2016/Array.prototype.includes.js: OK 1196 - compat-table/es2016/Array.prototype.includes.sparse.js: failed 1197 - compat-table/es2016/Array.prototype.includes.typed-array.js: TypeError: undefined is not a function 1196 + compat-table/es2016/Array.prototype.includes.sparse.js: OK 1197 + compat-table/es2016/Array.prototype.includes.typed-array.js: OK 1198 1198 compat-table/es2016/exponentiation.assignment.js: OK 1199 1199 compat-table/es2016/exponentiation.basic.js: OK 1200 1200 compat-table/es2016/exponentiation.unary-negation-error.js: OK 1201 - compat-table/es2016/misc.Proxy-Array-includes.js: failed 1201 + compat-table/es2016/misc.Proxy-Array-includes.js: OK 1202 1202 compat-table/es2016/misc.Proxy-enumerate-removed.js: OK 1203 1203 compat-table/es2016/misc.generator-no-new.js: OK 1204 1204 compat-table/es2016/misc.generator-throw-inner.js: OK 1205 1205 compat-table/es2016/misc.nested-rest-destructuring-decl.js: OK 1206 1206 compat-table/es2016/misc.nested-rest-destructuring-params.js: OK 1207 - compat-table/es2016/misc.strict-fn-non-simple-params-error.js: failed 1207 + compat-table/es2016/misc.strict-fn-non-simple-params-error.js: OK 1208 1208 compat-table/es2017/Atomics.add.js: OK 1209 1209 compat-table/es2017/Atomics.and.js: OK 1210 1210 compat-table/es2017/Atomics.compareExchange.js: OK
+84 -18
src/ant.c
··· 8340 8340 free(result); return ret; 8341 8341 } 8342 8342 8343 - static ant_value_t builtin_array_includes(ant_t *js, ant_value_t *args, int nargs) { 8344 - ant_value_t arr = js->this_val; 8343 + static inline bool array_includes_same_value_zero(ant_t *js, ant_value_t val, ant_value_t search) { 8344 + return ( 8345 + vtype(val) == T_NUM && 8346 + vtype(search) == T_NUM && 8347 + isnan(tod(val)) && 8348 + isnan(tod(search)) 8349 + ) || strict_eq_values(js, val, search); 8350 + } 8351 + 8352 + static inline ant_offset_t array_includes_length_from_number(double len_num) { 8353 + if (isnan(len_num) || len_num <= 0) return 0; 8354 + if (len_num >= (double)UINT32_MAX) return UINT32_MAX; 8355 + return (ant_offset_t)len_num; 8356 + } 8357 + 8358 + static inline ant_offset_t array_includes_start_index(ant_t *js, ant_value_t *args, int nargs, ant_offset_t len) { 8359 + int64_t start = 0; 8345 8360 8346 - if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) 8347 - return js_mkerr(js, "includes called on non-array"); 8348 - 8349 - if (nargs == 0) return mkval(T_BOOL, 0); 8350 - ant_value_t search = args[0]; 8351 - 8361 + if (nargs >= 2 && vtype(args[1]) != T_UNDEF) { 8362 + double from_index_num = js_to_number(js, args[1]); 8363 + if (!isnan(from_index_num)) start = (int64_t)from_index_num; 8364 + if (start < 0) { 8365 + start += (int64_t)len; 8366 + if (start < 0) start = 0; 8367 + }} 8368 + 8369 + if ((uint64_t)start >= (uint64_t)len) return len; 8370 + return (ant_offset_t)start; 8371 + } 8372 + 8373 + static ant_value_t array_includes_dense_fast( 8374 + ant_t *js, ant_value_t arr, ant_value_t search, ant_value_t *args, int nargs 8375 + ) { 8376 + if (!array_obj_ptr(arr) || is_proxy(arr)) return js_mkundef(); 8377 + 8352 8378 ant_offset_t len = get_array_length(js, arr); 8353 8379 if (len == 0) return mkval(T_BOOL, 0); 8354 - 8355 - ant_offset_t start = 0; 8356 - if (nargs >= 2 && vtype(args[1]) == T_NUM) { 8357 - int s = (int) tod(args[1]); 8358 - if (s < 0) s = (int)len + s; 8359 - if (s < 0) s = 0; 8360 - start = (ant_offset_t) s; 8380 + 8381 + ant_offset_t doff = get_dense_buf(arr); 8382 + if (!doff) return js_mkundef(); 8383 + 8384 + ant_offset_t dense_len = dense_iterable_length(js, arr); 8385 + if (dense_len != len) return js_mkundef(); 8386 + 8387 + ant_offset_t start = array_includes_start_index(js, args, nargs, len); 8388 + if (start >= len) return mkval(T_BOOL, 0); 8389 + 8390 + for (ant_offset_t i = start; i < len; i++) { 8391 + ant_value_t val = dense_get(doff, i); 8392 + if (is_empty_slot(val)) return js_mkundef(); 8393 + if (array_includes_same_value_zero(js, val, search)) return mkval(T_BOOL, 1); 8361 8394 } 8395 + 8396 + return mkval(T_BOOL, 0); 8397 + } 8398 + 8399 + static ant_value_t array_includes_generic( 8400 + ant_t *js, ant_value_t arr, ant_value_t search, ant_value_t *args, int nargs 8401 + ) { 8402 + ant_value_t len_val = js_getprop_fallback(js, arr, "length"); 8403 + if (is_err(len_val)) return len_val; 8404 + 8405 + ant_offset_t len = array_includes_length_from_number(js_to_number(js, len_val)); 8406 + if (len == 0) return mkval(T_BOOL, 0); 8362 8407 8408 + ant_offset_t start = array_includes_start_index(js, args, nargs, len); 8409 + if (start >= len) return mkval(T_BOOL, 0); 8410 + 8363 8411 for (ant_offset_t i = start; i < len; i++) { 8364 - ant_value_t val = arr_get(js, arr, i); 8365 - if (vtype(val) == T_NUM && vtype(search) == T_NUM && isnan(tod(val)) && isnan(tod(search))) return mkval(T_BOOL, 1); 8366 - if (strict_eq_values(js, val, search)) return mkval(T_BOOL, 1); 8412 + char idxstr[24]; 8413 + size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (uint64_t)i); 8414 + idxstr[idxlen] = '\0'; 8415 + 8416 + ant_value_t val = js_getprop_fallback(js, arr, idxstr); 8417 + if (is_err(val)) return val; 8418 + if (array_includes_same_value_zero(js, val, search)) return mkval(T_BOOL, 1); 8367 8419 } 8368 8420 8369 8421 return mkval(T_BOOL, 0); 8422 + } 8423 + 8424 + static ant_value_t builtin_array_includes(ant_t *js, ant_value_t *args, int nargs) { 8425 + ant_value_t arr = js->this_val; 8426 + 8427 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) 8428 + return js_mkerr(js, "includes called on non-array"); 8429 + 8430 + ant_value_t search = (nargs > 0) ? args[0] : js_mkundef(); 8431 + 8432 + ant_value_t fast = array_includes_dense_fast(js, arr, search, args, nargs); 8433 + if (vtype(fast) != T_UNDEF) return fast; 8434 + 8435 + return array_includes_generic(js, arr, search, args, nargs); 8370 8436 } 8371 8437 8372 8438 static ant_value_t builtin_array_every(ant_t *js, ant_value_t *args, int nargs) {
+65
src/modules/buffer.c
··· 2230 2230 return js_mknum(-1); 2231 2231 } 2232 2232 2233 + static ant_value_t js_typedarray_includes(ant_t *js, ant_value_t *args, int nargs) { 2234 + ant_value_t this_val = js_getthis(js); 2235 + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); 2236 + 2237 + if (!ta_data || !ta_data->buffer || ta_data->buffer->is_detached) { 2238 + return js_mkerr(js, "Invalid TypedArray"); 2239 + } 2240 + 2241 + size_t len = ta_data->length; 2242 + ant_value_t search = (nargs > 0) ? args[0] : js_mkundef(); 2243 + 2244 + if (len == 0) return js_false; 2245 + int64_t from_index = 0; 2246 + 2247 + if (nargs > 1 && vtype(args[1]) != T_UNDEF) { 2248 + double from_index_num = js_to_number(js, args[1]); 2249 + if (!isnan(from_index_num)) from_index = (int64_t)from_index_num; 2250 + if (from_index < 0) { 2251 + from_index += (int64_t)len; 2252 + if (from_index < 0) from_index = 0; 2253 + }} 2254 + 2255 + if ((size_t)from_index >= len) return js_false; 2256 + 2257 + if (ta_data->type == TYPED_ARRAY_BIGINT64) { 2258 + int64_t needle = 0; 2259 + if (vtype(search) == T_BIGINT) { 2260 + if (!bigint_to_int64_wrapping(js, search, &needle)) return js_false; 2261 + } else needle = (int64_t)js_to_number(js, search); 2262 + 2263 + int64_t *data = (int64_t *)(ta_data->buffer->data + ta_data->byte_offset); 2264 + for (size_t i = (size_t)from_index; i < len; i++) { 2265 + if (data[i] == needle) return js_true; 2266 + } 2267 + 2268 + return js_false; 2269 + } 2270 + 2271 + if (ta_data->type == TYPED_ARRAY_BIGUINT64) { 2272 + uint64_t needle = 0; 2273 + if (vtype(search) == T_BIGINT) { 2274 + if (!bigint_to_uint64_wrapping(js, search, &needle)) return js_false; 2275 + } else needle = (uint64_t)js_to_number(js, search); 2276 + 2277 + uint64_t *data = (uint64_t *)(ta_data->buffer->data + ta_data->byte_offset); 2278 + for (size_t i = (size_t)from_index; i < len; i++) { 2279 + if (data[i] == needle) return js_true; 2280 + } 2281 + 2282 + return js_false; 2283 + } 2284 + 2285 + double needle = js_to_number(js, search); 2286 + for (size_t i = (size_t)from_index; i < len; i++) { 2287 + double value = 0; 2288 + if (!typedarray_read_number(ta_data, i, &value)) return js_false; 2289 + if (isnan(value) && isnan(needle)) return js_true; 2290 + if (value == needle) return js_true; 2291 + } 2292 + 2293 + return js_false; 2294 + } 2295 + 2233 2296 // Buffer.prototype.toString(encoding) 2234 2297 static ant_value_t js_buffer_slice(ant_t *js, ant_value_t *args, int nargs) { 2235 2298 return js_typedarray_subarray(js, args, nargs); ··· 2698 2761 js_set(js, typedarray_proto, "toString", js_mkfun(js_typedarray_toString)); 2699 2762 js_set(js, typedarray_proto, "join", js_mkfun(js_typedarray_join)); 2700 2763 js_set(js, typedarray_proto, "indexOf", js_mkfun(js_typedarray_indexOf)); 2764 + js_set(js, typedarray_proto, "includes", js_mkfun(js_typedarray_includes)); 2701 2765 js_set_sym(js, typedarray_proto, get_toStringTag_sym(), js_mkstr(js, "TypedArray", 10)); 2702 2766 2703 2767 g_typedarray_iter_proto = js_mkobj(js); ··· 2710 2774 js_set(js, typedarray_proto, "entries", js_mkfun(ta_entries)); 2711 2775 js_set_sym(js, typedarray_proto, get_iterator_sym(), js_get(js, typedarray_proto, "values")); 2712 2776 2777 + // TODO: find a better way of doing this, macro is code smell 2713 2778 #define SETUP_TYPEDARRAY(name) \ 2714 2779 do { \ 2715 2780 ant_value_t name##_ctor_obj = js_mkobj(js); \
+7
src/silver/compiler.c
··· 4303 4303 sv_ast_t *p = node->args.items[i]; 4304 4304 if (p->type != N_IDENT) { has_non_simple_params = true; break; } 4305 4305 } 4306 + 4307 + if (comp.is_strict && has_non_simple_params) { 4308 + js_mkerr_typed( 4309 + comp.js, JS_ERR_SYNTAX, 4310 + "Illegal 'use strict' directive in function with non-simple parameter list"); 4311 + return NULL; 4312 + } 4306 4313 4307 4314 bool repl_top = is_repl_top_level(&comp); 4308 4315 if (!has_non_simple_params && node->body) {
+76
tests/test_es2016_includes_and_strict.cjs
··· 1 + const assert = require("node:assert"); 2 + 3 + let passed = 0; 4 + assert.strictEqual([].includes.call({ 5 + get "0"() { 6 + passed = NaN; 7 + return "foo"; 8 + }, 9 + get "11"() { 10 + passed += 1; 11 + return 0; 12 + }, 13 + get "19"() { 14 + passed += 1; 15 + return "foo"; 16 + }, 17 + get "21"() { 18 + passed = NaN; 19 + return "foo"; 20 + }, 21 + get length() { 22 + passed += 1; 23 + return 24; 24 + } 25 + }, "foo", 6), true); 26 + assert.strictEqual(passed, 3); 27 + 28 + assert.strictEqual([,].includes(), true); 29 + assert.strictEqual(Array(1).includes(), true); 30 + 31 + let getLog = []; 32 + let proxy = new Proxy({ length: 3, 0: "", 1: "", 2: "", 3: "" }, { 33 + get(target, key) { 34 + getLog.push(String(key)); 35 + return target[key]; 36 + } 37 + }); 38 + Array.prototype.includes.call(proxy, {}); 39 + assert.deepStrictEqual(getLog, ["length", "0", "1", "2"]); 40 + 41 + getLog = []; 42 + proxy = new Proxy({ length: 4, 0: NaN, 1: "", 2: NaN, 3: "" }, { 43 + get(target, key) { 44 + getLog.push(String(key)); 45 + return target[key]; 46 + } 47 + }); 48 + Array.prototype.includes.call(proxy, NaN, 1); 49 + assert.deepStrictEqual(getLog, ["length", "1", "2"]); 50 + 51 + [ 52 + Int8Array, 53 + Uint8Array, 54 + Uint8ClampedArray, 55 + Int16Array, 56 + Uint16Array, 57 + Int32Array, 58 + Uint32Array, 59 + Float32Array, 60 + Float64Array 61 + ].forEach((TypedArray) => { 62 + const view = new TypedArray([1, 2, 3]); 63 + assert.strictEqual(view.includes(1), true); 64 + assert.strictEqual(view.includes(4), false); 65 + assert.strictEqual(view.includes(1, 1), false); 66 + }); 67 + 68 + let threw = false; 69 + try { 70 + Function("function bar(...a) {'use strict';}")(); 71 + } catch (_err) { 72 + threw = true; 73 + } 74 + assert.strictEqual(threw, true); 75 + 76 + console.log("ES2016 includes and strict-mode regressions pass");