Implement Array.prototype.toReversed (#19)
This commit is contained in:
parent
e2ae8746ca
commit
a3a57febed
2 changed files with 64 additions and 32 deletions
64
quickjs.c
64
quickjs.c
|
@ -38832,6 +38832,69 @@ static JSValue js_array_reverse(JSContext *ctx, JSValueConst this_val,
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: a.toReversed() is a.slice().reverse() with the twist that a.slice()
|
||||||
|
// leaves holes in sparse arrays intact whereas a.toReversed() replaces them
|
||||||
|
// with undefined, thus in effect creating a dense array.
|
||||||
|
// Does not use Array[@@species], always returns a base Array.
|
||||||
|
static JSValue js_array_toReversed(JSContext *ctx, JSValueConst this_val,
|
||||||
|
int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
JSValue arr, obj, ret, *arrp, *pval;
|
||||||
|
JSObject *p;
|
||||||
|
int64_t i, len;
|
||||||
|
uint32_t count32;
|
||||||
|
|
||||||
|
ret = JS_EXCEPTION;
|
||||||
|
arr = JS_UNDEFINED;
|
||||||
|
obj = JS_ToObject(ctx, this_val);
|
||||||
|
if (js_get_length64(ctx, &len, obj))
|
||||||
|
goto exception;
|
||||||
|
|
||||||
|
if (len > UINT32_MAX) {
|
||||||
|
JS_ThrowRangeError(ctx, "invalid array length");
|
||||||
|
goto exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
arr = JS_NewArray(ctx);
|
||||||
|
if (JS_IsException(arr))
|
||||||
|
goto exception;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
p = JS_VALUE_GET_OBJ(arr);
|
||||||
|
if (expand_fast_array(ctx, p, len) < 0)
|
||||||
|
goto exception;
|
||||||
|
p->u.array.count = len;
|
||||||
|
|
||||||
|
i = len - 1;
|
||||||
|
pval = p->u.array.u.values;
|
||||||
|
if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) {
|
||||||
|
for (; i >= 0; i--, pval++)
|
||||||
|
*pval = JS_DupValue(ctx, arrp[i]);
|
||||||
|
} else {
|
||||||
|
// Query order is observable; test262 expects descending order.
|
||||||
|
for (; i >= 0; i--, pval++) {
|
||||||
|
if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) {
|
||||||
|
// Exception; initialize remaining elements.
|
||||||
|
for (; i >= 0; i--, pval++)
|
||||||
|
*pval = JS_UNDEFINED;
|
||||||
|
goto exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, len)) < 0)
|
||||||
|
goto exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = arr;
|
||||||
|
arr = JS_UNDEFINED;
|
||||||
|
|
||||||
|
exception:
|
||||||
|
JS_FreeValue(ctx, arr);
|
||||||
|
JS_FreeValue(ctx, obj);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static JSValue js_array_slice(JSContext *ctx, JSValueConst this_val,
|
static JSValue js_array_slice(JSContext *ctx, JSValueConst this_val,
|
||||||
int argc, JSValueConst *argv, int splice)
|
int argc, JSValueConst *argv, int splice)
|
||||||
{
|
{
|
||||||
|
@ -39417,6 +39480,7 @@ static const JSCFunctionListEntry js_array_proto_funcs[] = {
|
||||||
JS_CFUNC_MAGIC_DEF("shift", 0, js_array_pop, 1 ),
|
JS_CFUNC_MAGIC_DEF("shift", 0, js_array_pop, 1 ),
|
||||||
JS_CFUNC_MAGIC_DEF("unshift", 1, js_array_push, 1 ),
|
JS_CFUNC_MAGIC_DEF("unshift", 1, js_array_push, 1 ),
|
||||||
JS_CFUNC_DEF("reverse", 0, js_array_reverse ),
|
JS_CFUNC_DEF("reverse", 0, js_array_reverse ),
|
||||||
|
JS_CFUNC_DEF("toReversed", 0, js_array_toReversed ),
|
||||||
JS_CFUNC_DEF("sort", 1, js_array_sort ),
|
JS_CFUNC_DEF("sort", 1, js_array_sort ),
|
||||||
JS_CFUNC_MAGIC_DEF("slice", 2, js_array_slice, 0 ),
|
JS_CFUNC_MAGIC_DEF("slice", 2, js_array_slice, 0 ),
|
||||||
JS_CFUNC_MAGIC_DEF("splice", 2, js_array_slice, 1 ),
|
JS_CFUNC_MAGIC_DEF("splice", 2, js_array_slice, 1 ),
|
||||||
|
|
|
@ -1,38 +1,6 @@
|
||||||
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
|
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
|
||||||
test262/test/built-ins/Array/prototype/Symbol.unscopables/change-array-by-copy.js:19: Test262Error: obj should have an own property toReversed
|
test262/test/built-ins/Array/prototype/Symbol.unscopables/change-array-by-copy.js:19: Test262Error: obj should have an own property toReversed
|
||||||
test262/test/built-ins/Array/prototype/Symbol.unscopables/change-array-by-copy.js:19: strict mode: Test262Error: obj should have an own property toReversed
|
test262/test/built-ins/Array/prototype/Symbol.unscopables/change-array-by-copy.js:19: strict mode: Test262Error: obj should have an own property toReversed
|
||||||
test262/test/built-ins/Array/prototype/toReversed/frozen-this-value.js:13: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/frozen-this-value.js:13: strict mode: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/get-descending-order.js:37: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/get-descending-order.js:37: strict mode: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/holes-not-preserved.js:27: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/holes-not-preserved.js:27: strict mode: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/ignores-species.js:21: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/ignores-species.js:21: strict mode: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/immutable.js:13: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/immutable.js:13: strict mode: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-casted-to-zero.js:18: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-casted-to-zero.js:18: strict mode: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-decreased-while-iterating.js:32: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-decreased-while-iterating.js:32: strict mode: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-exceeding-array-length-limit.js:25: Test262Error: Expected a RangeError but got a TypeError
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-exceeding-array-length-limit.js:25: strict mode: Test262Error: Expected a RangeError but got a TypeError
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-increased-while-iterating.js:30: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-increased-while-iterating.js:30: strict mode: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-tolength.js:18: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/length-tolength.js:18: strict mode: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/metadata/length.js:30: TypeError: cannot convert to object
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/metadata/length.js:30: strict mode: TypeError: cannot convert to object
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/metadata/name.js:28: TypeError: cannot convert to object
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/metadata/name.js:28: strict mode: TypeError: cannot convert to object
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/metadata/property-descriptor.js:18: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/metadata/property-descriptor.js:18: strict mode: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/not-a-constructor.js:30: Test262Error: isConstructor invoked with a non-function value
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/not-a-constructor.js:30: strict mode: Test262Error: isConstructor invoked with a non-function value
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/this-value-boolean.js:18: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/this-value-boolean.js:18: strict mode: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/zero-or-one-element.js:13: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toReversed/zero-or-one-element.js:13: strict mode: TypeError: not a function
|
|
||||||
test262/test/built-ins/Array/prototype/toSorted/comparefn-called-after-get-elements.js:37: Test262Error: Expected a Test262Error but got a TypeError
|
test262/test/built-ins/Array/prototype/toSorted/comparefn-called-after-get-elements.js:37: Test262Error: Expected a Test262Error but got a TypeError
|
||||||
test262/test/built-ins/Array/prototype/toSorted/comparefn-called-after-get-elements.js:37: strict mode: Test262Error: Expected a Test262Error but got a TypeError
|
test262/test/built-ins/Array/prototype/toSorted/comparefn-called-after-get-elements.js:37: strict mode: Test262Error: Expected a Test262Error but got a TypeError
|
||||||
test262/test/built-ins/Array/prototype/toSorted/comparefn-stop-after-error.js:22: Test262Error: Expected a Test262Error but got a TypeError
|
test262/test/built-ins/Array/prototype/toSorted/comparefn-stop-after-error.js:22: Test262Error: Expected a Test262Error but got a TypeError
|
||||||
|
|
Loading…
Reference in a new issue