Skip to content

Commit feebfbc

Browse files
authoredNov 16, 2023
Add Array.prototype.toSpliced (#64)
1 parent ab53412 commit feebfbc

File tree

2 files changed

+97
-60
lines changed

2 files changed

+97
-60
lines changed
 

‎quickjs.c

+97-2
Original file line numberDiff line numberDiff line change
@@ -36817,8 +36817,7 @@ static JSValue js_array_slice(JSContext *ctx, JSValueConst this_val,
3681736817
if (argc == 0) {
3681836818
item_count = 0;
3681936819
del_count = 0;
36820-
} else
36821-
if (argc == 1) {
36820+
} else if (argc == 1) {
3682236821
item_count = 0;
3682336822
del_count = len - start;
3682436823
} else {
@@ -36903,6 +36902,101 @@ static JSValue js_array_slice(JSContext *ctx, JSValueConst this_val,
3690336902
return JS_EXCEPTION;
3690436903
}
3690536904

36905+
static JSValue js_array_toSpliced(JSContext *ctx, JSValueConst this_val,
36906+
int argc, JSValueConst *argv)
36907+
{
36908+
JSValue arr, obj, ret, *arrp, *pval, *last;
36909+
JSObject *p;
36910+
int64_t i, j, len, newlen, start, add, del;
36911+
uint32_t count32;
36912+
36913+
pval = NULL;
36914+
last = NULL;
36915+
ret = JS_EXCEPTION;
36916+
arr = JS_UNDEFINED;
36917+
36918+
obj = JS_ToObject(ctx, this_val);
36919+
if (js_get_length64(ctx, &len, obj))
36920+
goto exception;
36921+
36922+
start = 0;
36923+
if (argc > 0)
36924+
if (JS_ToInt64Clamp(ctx, &start, argv[0], 0, len, len))
36925+
goto exception;
36926+
36927+
del = 0;
36928+
if (argc > 0)
36929+
del = len - start;
36930+
if (argc > 1)
36931+
if (JS_ToInt64Clamp(ctx, &del, argv[1], 0, del, 0))
36932+
goto exception;
36933+
36934+
add = 0;
36935+
if (argc > 2)
36936+
add = argc - 2;
36937+
36938+
newlen = len + add - del;
36939+
if (newlen > UINT32_MAX) {
36940+
// Per spec: TypeError if newlen >= 2**53, RangeError below
36941+
if (newlen > MAX_SAFE_INTEGER) {
36942+
JS_ThrowTypeError(ctx, "invalid array length");
36943+
} else {
36944+
JS_ThrowRangeError(ctx, "invalid array length");
36945+
}
36946+
goto exception;
36947+
}
36948+
36949+
arr = JS_NewArray(ctx);
36950+
if (JS_IsException(arr))
36951+
goto exception;
36952+
36953+
if (newlen <= 0)
36954+
goto done;
36955+
36956+
p = JS_VALUE_GET_OBJ(arr);
36957+
if (expand_fast_array(ctx, p, newlen) < 0)
36958+
goto exception;
36959+
36960+
p->u.array.count = newlen;
36961+
pval = &p->u.array.u.values[0];
36962+
last = &p->u.array.u.values[newlen];
36963+
36964+
if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) {
36965+
for (i = 0; i < start; i++, pval++)
36966+
*pval = JS_DupValue(ctx, arrp[i]);
36967+
for (j = 0; j < add; j++, pval++)
36968+
*pval = JS_DupValue(ctx, argv[2 + j]);
36969+
for (i += del; i < len; i++, pval++)
36970+
*pval = JS_DupValue(ctx, arrp[i]);
36971+
} else {
36972+
for (i = 0; i < start; i++, pval++)
36973+
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval))
36974+
goto exception;
36975+
for (j = 0; j < add; j++, pval++)
36976+
*pval = JS_DupValue(ctx, argv[2 + j]);
36977+
for (i += del; i < len; i++, pval++)
36978+
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval))
36979+
goto exception;
36980+
}
36981+
36982+
assert(pval == last);
36983+
36984+
if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, newlen)) < 0)
36985+
goto exception;
36986+
36987+
done:
36988+
ret = arr;
36989+
arr = JS_UNDEFINED;
36990+
36991+
exception:
36992+
while (pval != last)
36993+
*pval++ = JS_UNDEFINED;
36994+
36995+
JS_FreeValue(ctx, arr);
36996+
JS_FreeValue(ctx, obj);
36997+
return ret;
36998+
}
36999+
3690637000
static JSValue js_array_copyWithin(JSContext *ctx, JSValueConst this_val,
3690737001
int argc, JSValueConst *argv)
3690837002
{
@@ -37458,6 +37552,7 @@ static const JSCFunctionListEntry js_array_proto_funcs[] = {
3745837552
JS_CFUNC_DEF("toSorted", 1, js_array_toSorted ),
3745937553
JS_CFUNC_MAGIC_DEF("slice", 2, js_array_slice, 0 ),
3746037554
JS_CFUNC_MAGIC_DEF("splice", 2, js_array_slice, 1 ),
37555+
JS_CFUNC_DEF("toSpliced", 2, js_array_toSpliced ),
3746137556
JS_CFUNC_DEF("copyWithin", 2, js_array_copyWithin ),
3746237557
JS_CFUNC_MAGIC_DEF("flatMap", 1, js_array_flatten, 1 ),
3746337558
JS_CFUNC_MAGIC_DEF("flat", 0, js_array_flatten, 0 ),

‎test262_errors.txt

-58
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,6 @@
11
test262/test/annexB/language/eval-code/direct/script-decl-lex-collision-in-sloppy-mode.js:13: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
22
test262/test/built-ins/Array/prototype/Symbol.unscopables/change-array-by-copy.js:19: Test262Error: obj should have an own property toReversed
33
test262/test/built-ins/Array/prototype/Symbol.unscopables/change-array-by-copy.js:19: strict mode: Test262Error: obj should have an own property toReversed
4-
test262/test/built-ins/Array/prototype/toSpliced/deleteCount-clamped-between-zero-and-remaining-count.js:20: TypeError: not a function
5-
test262/test/built-ins/Array/prototype/toSpliced/deleteCount-clamped-between-zero-and-remaining-count.js:20: strict mode: TypeError: not a function
6-
test262/test/built-ins/Array/prototype/toSpliced/deleteCount-missing.js:18: TypeError: not a function
7-
test262/test/built-ins/Array/prototype/toSpliced/deleteCount-missing.js:18: strict mode: TypeError: not a function
8-
test262/test/built-ins/Array/prototype/toSpliced/deleteCount-undefined.js:27: TypeError: not a function
9-
test262/test/built-ins/Array/prototype/toSpliced/deleteCount-undefined.js:27: strict mode: TypeError: not a function
10-
test262/test/built-ins/Array/prototype/toSpliced/discarded-element-not-read.js:51: TypeError: cannot read property 'call' of undefined
11-
test262/test/built-ins/Array/prototype/toSpliced/discarded-element-not-read.js:51: strict mode: TypeError: cannot read property 'call' of undefined
12-
test262/test/built-ins/Array/prototype/toSpliced/elements-read-in-order.js:45: TypeError: cannot read property 'call' of undefined
13-
test262/test/built-ins/Array/prototype/toSpliced/elements-read-in-order.js:45: strict mode: TypeError: cannot read property 'call' of undefined
14-
test262/test/built-ins/Array/prototype/toSpliced/frozen-this-value.js:13: TypeError: not a function
15-
test262/test/built-ins/Array/prototype/toSpliced/frozen-this-value.js:13: strict mode: TypeError: not a function
16-
test262/test/built-ins/Array/prototype/toSpliced/holes-not-preserved.js:33: TypeError: not a function
17-
test262/test/built-ins/Array/prototype/toSpliced/holes-not-preserved.js:33: strict mode: TypeError: not a function
18-
test262/test/built-ins/Array/prototype/toSpliced/ignores-species.js:21: TypeError: not a function
19-
test262/test/built-ins/Array/prototype/toSpliced/ignores-species.js:21: strict mode: TypeError: not a function
20-
test262/test/built-ins/Array/prototype/toSpliced/immutable.js:13: TypeError: not a function
21-
test262/test/built-ins/Array/prototype/toSpliced/immutable.js:13: strict mode: TypeError: not a function
22-
test262/test/built-ins/Array/prototype/toSpliced/length-casted-to-zero.js:19: TypeError: cannot read property 'call' of undefined
23-
test262/test/built-ins/Array/prototype/toSpliced/length-casted-to-zero.js:19: strict mode: TypeError: cannot read property 'call' of undefined
24-
test262/test/built-ins/Array/prototype/toSpliced/length-clamped-to-2pow53minus1.js:31: TypeError: cannot read property 'call' of undefined
25-
test262/test/built-ins/Array/prototype/toSpliced/length-clamped-to-2pow53minus1.js:31: strict mode: TypeError: cannot read property 'call' of undefined
26-
test262/test/built-ins/Array/prototype/toSpliced/length-decreased-while-iterating.js:44: TypeError: not a function
27-
test262/test/built-ins/Array/prototype/toSpliced/length-decreased-while-iterating.js:44: strict mode: TypeError: not a function
28-
test262/test/built-ins/Array/prototype/toSpliced/length-exceeding-array-length-limit.js:28: Test262Error: Expected a RangeError but got a TypeError
29-
test262/test/built-ins/Array/prototype/toSpliced/length-exceeding-array-length-limit.js:28: strict mode: Test262Error: Expected a RangeError but got a TypeError
30-
test262/test/built-ins/Array/prototype/toSpliced/length-increased-while-iterating.js:37: TypeError: not a function
31-
test262/test/built-ins/Array/prototype/toSpliced/length-increased-while-iterating.js:37: strict mode: TypeError: not a function
32-
test262/test/built-ins/Array/prototype/toSpliced/length-tolength.js:18: TypeError: cannot read property 'call' of undefined
33-
test262/test/built-ins/Array/prototype/toSpliced/length-tolength.js:18: strict mode: TypeError: cannot read property 'call' of undefined
34-
test262/test/built-ins/Array/prototype/toSpliced/metadata/length.js:30: TypeError: cannot convert to object
35-
test262/test/built-ins/Array/prototype/toSpliced/metadata/length.js:30: strict mode: TypeError: cannot convert to object
36-
test262/test/built-ins/Array/prototype/toSpliced/metadata/name.js:28: TypeError: cannot convert to object
37-
test262/test/built-ins/Array/prototype/toSpliced/metadata/name.js:28: strict mode: TypeError: cannot convert to object
38-
test262/test/built-ins/Array/prototype/toSpliced/metadata/property-descriptor.js:18: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
39-
test262/test/built-ins/Array/prototype/toSpliced/metadata/property-descriptor.js:18: strict mode: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
40-
test262/test/built-ins/Array/prototype/toSpliced/mutate-while-iterating.js:50: TypeError: not a function
41-
test262/test/built-ins/Array/prototype/toSpliced/mutate-while-iterating.js:50: strict mode: TypeError: not a function
42-
test262/test/built-ins/Array/prototype/toSpliced/not-a-constructor.js:30: Test262Error: isConstructor invoked with a non-function value
43-
test262/test/built-ins/Array/prototype/toSpliced/not-a-constructor.js:30: strict mode: Test262Error: isConstructor invoked with a non-function value
44-
test262/test/built-ins/Array/prototype/toSpliced/start-and-deleteCount-missing.js:23: TypeError: not a function
45-
test262/test/built-ins/Array/prototype/toSpliced/start-and-deleteCount-missing.js:23: strict mode: TypeError: not a function
46-
test262/test/built-ins/Array/prototype/toSpliced/start-and-deleteCount-undefineds.js:25: TypeError: not a function
47-
test262/test/built-ins/Array/prototype/toSpliced/start-and-deleteCount-undefineds.js:25: strict mode: TypeError: not a function
48-
test262/test/built-ins/Array/prototype/toSpliced/start-bigger-than-length.js:22: TypeError: not a function
49-
test262/test/built-ins/Array/prototype/toSpliced/start-bigger-than-length.js:22: strict mode: TypeError: not a function
50-
test262/test/built-ins/Array/prototype/toSpliced/start-neg-infinity-is-zero.js:21: TypeError: not a function
51-
test262/test/built-ins/Array/prototype/toSpliced/start-neg-infinity-is-zero.js:21: strict mode: TypeError: not a function
52-
test262/test/built-ins/Array/prototype/toSpliced/start-neg-less-than-minus-length-is-zero.js:21: TypeError: not a function
53-
test262/test/built-ins/Array/prototype/toSpliced/start-neg-less-than-minus-length-is-zero.js:21: strict mode: TypeError: not a function
54-
test262/test/built-ins/Array/prototype/toSpliced/start-neg-subtracted-from-length.js:21: TypeError: not a function
55-
test262/test/built-ins/Array/prototype/toSpliced/start-neg-subtracted-from-length.js:21: strict mode: TypeError: not a function
56-
test262/test/built-ins/Array/prototype/toSpliced/start-undefined-and-deleteCount-missing.js:24: TypeError: not a function
57-
test262/test/built-ins/Array/prototype/toSpliced/start-undefined-and-deleteCount-missing.js:24: strict mode: TypeError: not a function
58-
test262/test/built-ins/Array/prototype/toSpliced/this-value-boolean.js:18: TypeError: cannot read property 'call' of undefined
59-
test262/test/built-ins/Array/prototype/toSpliced/this-value-boolean.js:18: strict mode: TypeError: cannot read property 'call' of undefined
60-
test262/test/built-ins/Array/prototype/toSpliced/unmodified.js:13: TypeError: not a function
61-
test262/test/built-ins/Array/prototype/toSpliced/unmodified.js:13: strict mode: TypeError: not a function
624
test262/test/built-ins/AsyncGeneratorPrototype/return/return-state-completed-broken-promise.js:53: TypeError: $DONE() not called
635
test262/test/built-ins/AsyncGeneratorPrototype/return/return-state-completed-broken-promise.js:53: strict mode: TypeError: $DONE() not called
646
test262/test/built-ins/AsyncGeneratorPrototype/return/return-suspendedStart-broken-promise.js:34: TypeError: $DONE() not called

0 commit comments

Comments
 (0)