Skip to content

Commit a3a57fe

Browse files
authored
Implement Array.prototype.toReversed (#19)
1 parent e2ae874 commit a3a57fe

File tree

2 files changed

+64
-32
lines changed

2 files changed

+64
-32
lines changed

quickjs.c

+64
Original file line numberDiff line numberDiff line change
@@ -38832,6 +38832,69 @@ static JSValue js_array_reverse(JSContext *ctx, JSValueConst this_val,
3883238832
return JS_EXCEPTION;
3883338833
}
3883438834

38835+
// Note: a.toReversed() is a.slice().reverse() with the twist that a.slice()
38836+
// leaves holes in sparse arrays intact whereas a.toReversed() replaces them
38837+
// with undefined, thus in effect creating a dense array.
38838+
// Does not use Array[@@species], always returns a base Array.
38839+
static JSValue js_array_toReversed(JSContext *ctx, JSValueConst this_val,
38840+
int argc, JSValueConst *argv)
38841+
{
38842+
JSValue arr, obj, ret, *arrp, *pval;
38843+
JSObject *p;
38844+
int64_t i, len;
38845+
uint32_t count32;
38846+
38847+
ret = JS_EXCEPTION;
38848+
arr = JS_UNDEFINED;
38849+
obj = JS_ToObject(ctx, this_val);
38850+
if (js_get_length64(ctx, &len, obj))
38851+
goto exception;
38852+
38853+
if (len > UINT32_MAX) {
38854+
JS_ThrowRangeError(ctx, "invalid array length");
38855+
goto exception;
38856+
}
38857+
38858+
arr = JS_NewArray(ctx);
38859+
if (JS_IsException(arr))
38860+
goto exception;
38861+
38862+
if (len > 0) {
38863+
p = JS_VALUE_GET_OBJ(arr);
38864+
if (expand_fast_array(ctx, p, len) < 0)
38865+
goto exception;
38866+
p->u.array.count = len;
38867+
38868+
i = len - 1;
38869+
pval = p->u.array.u.values;
38870+
if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) {
38871+
for (; i >= 0; i--, pval++)
38872+
*pval = JS_DupValue(ctx, arrp[i]);
38873+
} else {
38874+
// Query order is observable; test262 expects descending order.
38875+
for (; i >= 0; i--, pval++) {
38876+
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) {
38877+
// Exception; initialize remaining elements.
38878+
for (; i >= 0; i--, pval++)
38879+
*pval = JS_UNDEFINED;
38880+
goto exception;
38881+
}
38882+
}
38883+
}
38884+
38885+
if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, len)) < 0)
38886+
goto exception;
38887+
}
38888+
38889+
ret = arr;
38890+
arr = JS_UNDEFINED;
38891+
38892+
exception:
38893+
JS_FreeValue(ctx, arr);
38894+
JS_FreeValue(ctx, obj);
38895+
return ret;
38896+
}
38897+
3883538898
static JSValue js_array_slice(JSContext *ctx, JSValueConst this_val,
3883638899
int argc, JSValueConst *argv, int splice)
3883738900
{
@@ -39417,6 +39480,7 @@ static const JSCFunctionListEntry js_array_proto_funcs[] = {
3941739480
JS_CFUNC_MAGIC_DEF("shift", 0, js_array_pop, 1 ),
3941839481
JS_CFUNC_MAGIC_DEF("unshift", 1, js_array_push, 1 ),
3941939482
JS_CFUNC_DEF("reverse", 0, js_array_reverse ),
39483+
JS_CFUNC_DEF("toReversed", 0, js_array_toReversed ),
3942039484
JS_CFUNC_DEF("sort", 1, js_array_sort ),
3942139485
JS_CFUNC_MAGIC_DEF("slice", 2, js_array_slice, 0 ),
3942239486
JS_CFUNC_MAGIC_DEF("splice", 2, js_array_slice, 1 ),

test262_errors.txt

-32
Original file line numberDiff line numberDiff line change
@@ -1,38 +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/toReversed/frozen-this-value.js:13: TypeError: not a function
5-
test262/test/built-ins/Array/prototype/toReversed/frozen-this-value.js:13: strict mode: TypeError: not a function
6-
test262/test/built-ins/Array/prototype/toReversed/get-descending-order.js:37: TypeError: cannot read property 'call' of undefined
7-
test262/test/built-ins/Array/prototype/toReversed/get-descending-order.js:37: strict mode: TypeError: cannot read property 'call' of undefined
8-
test262/test/built-ins/Array/prototype/toReversed/holes-not-preserved.js:27: TypeError: not a function
9-
test262/test/built-ins/Array/prototype/toReversed/holes-not-preserved.js:27: strict mode: TypeError: not a function
10-
test262/test/built-ins/Array/prototype/toReversed/ignores-species.js:21: TypeError: not a function
11-
test262/test/built-ins/Array/prototype/toReversed/ignores-species.js:21: strict mode: TypeError: not a function
12-
test262/test/built-ins/Array/prototype/toReversed/immutable.js:13: TypeError: not a function
13-
test262/test/built-ins/Array/prototype/toReversed/immutable.js:13: strict mode: TypeError: not a function
14-
test262/test/built-ins/Array/prototype/toReversed/length-casted-to-zero.js:18: TypeError: cannot read property 'call' of undefined
15-
test262/test/built-ins/Array/prototype/toReversed/length-casted-to-zero.js:18: strict mode: TypeError: cannot read property 'call' of undefined
16-
test262/test/built-ins/Array/prototype/toReversed/length-decreased-while-iterating.js:32: TypeError: not a function
17-
test262/test/built-ins/Array/prototype/toReversed/length-decreased-while-iterating.js:32: strict mode: TypeError: not a function
18-
test262/test/built-ins/Array/prototype/toReversed/length-exceeding-array-length-limit.js:25: Test262Error: Expected a RangeError but got a TypeError
19-
test262/test/built-ins/Array/prototype/toReversed/length-exceeding-array-length-limit.js:25: strict mode: Test262Error: Expected a RangeError but got a TypeError
20-
test262/test/built-ins/Array/prototype/toReversed/length-increased-while-iterating.js:30: TypeError: not a function
21-
test262/test/built-ins/Array/prototype/toReversed/length-increased-while-iterating.js:30: strict mode: TypeError: not a function
22-
test262/test/built-ins/Array/prototype/toReversed/length-tolength.js:18: TypeError: cannot read property 'call' of undefined
23-
test262/test/built-ins/Array/prototype/toReversed/length-tolength.js:18: strict mode: TypeError: cannot read property 'call' of undefined
24-
test262/test/built-ins/Array/prototype/toReversed/metadata/length.js:30: TypeError: cannot convert to object
25-
test262/test/built-ins/Array/prototype/toReversed/metadata/length.js:30: strict mode: TypeError: cannot convert to object
26-
test262/test/built-ins/Array/prototype/toReversed/metadata/name.js:28: TypeError: cannot convert to object
27-
test262/test/built-ins/Array/prototype/toReversed/metadata/name.js:28: strict mode: TypeError: cannot convert to object
28-
test262/test/built-ins/Array/prototype/toReversed/metadata/property-descriptor.js:18: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
29-
test262/test/built-ins/Array/prototype/toReversed/metadata/property-descriptor.js:18: strict mode: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
30-
test262/test/built-ins/Array/prototype/toReversed/not-a-constructor.js:30: Test262Error: isConstructor invoked with a non-function value
31-
test262/test/built-ins/Array/prototype/toReversed/not-a-constructor.js:30: strict mode: Test262Error: isConstructor invoked with a non-function value
32-
test262/test/built-ins/Array/prototype/toReversed/this-value-boolean.js:18: TypeError: cannot read property 'call' of undefined
33-
test262/test/built-ins/Array/prototype/toReversed/this-value-boolean.js:18: strict mode: TypeError: cannot read property 'call' of undefined
34-
test262/test/built-ins/Array/prototype/toReversed/zero-or-one-element.js:13: TypeError: not a function
35-
test262/test/built-ins/Array/prototype/toReversed/zero-or-one-element.js:13: strict mode: TypeError: not a function
364
test262/test/built-ins/Array/prototype/toSorted/comparefn-called-after-get-elements.js:37: Test262Error: Expected a Test262Error but got a TypeError
375
test262/test/built-ins/Array/prototype/toSorted/comparefn-called-after-get-elements.js:37: strict mode: Test262Error: Expected a Test262Error but got a TypeError
386
test262/test/built-ins/Array/prototype/toSorted/comparefn-stop-after-error.js:22: Test262Error: Expected a Test262Error but got a TypeError

0 commit comments

Comments
 (0)