Skip to content

Implement Array.prototype.findLast{Index} #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 29 additions & 7 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -36440,13 +36440,21 @@ static JSValue js_array_lastIndexOf(JSContext *ctx, JSValueConst this_val,
return JS_EXCEPTION;
}

enum {
ArrayFind,
ArrayFindIndex,
ArrayFindLast,
ArrayFindLastIndex,
};

static JSValue js_array_find(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int findIndex)
int argc, JSValueConst *argv, int mode)
{
JSValueConst func, this_arg;
JSValueConst args[3];
JSValue obj, val, index_val, res;
int64_t len, k;
int64_t len, k, end;
int dir;

index_val = JS_UNDEFINED;
val = JS_UNDEFINED;
Expand All @@ -36462,7 +36470,17 @@ static JSValue js_array_find(JSContext *ctx, JSValueConst this_val,
if (argc > 1)
this_arg = argv[1];

for(k = 0; k < len; k++) {
k = 0;
dir = 1;
end = len;
if (mode == ArrayFindLast || mode == ArrayFindLastIndex) {
k = len - 1;
dir = -1;
end = -1;
}

// TODO(bnoordhuis) add fast path for fast arrays
for(; k != end; k += dir) {
index_val = JS_NewInt64(ctx, k);
if (JS_IsException(index_val))
goto exception;
Expand All @@ -36476,7 +36494,7 @@ static JSValue js_array_find(JSContext *ctx, JSValueConst this_val,
if (JS_IsException(res))
goto exception;
if (JS_ToBoolFree(ctx, res)) {
if (findIndex) {
if (mode == ArrayFindIndex || mode == ArrayFindLastIndex) {
JS_FreeValue(ctx, val);
JS_FreeValue(ctx, obj);
return index_val;
Expand All @@ -36490,7 +36508,7 @@ static JSValue js_array_find(JSContext *ctx, JSValueConst this_val,
JS_FreeValue(ctx, index_val);
}
JS_FreeValue(ctx, obj);
if (findIndex)
if (mode == ArrayFindIndex || mode == ArrayFindLastIndex)
return JS_NewInt32(ctx, -1);
else
return JS_UNDEFINED;
Expand Down Expand Up @@ -37542,8 +37560,10 @@ static const JSCFunctionListEntry js_array_proto_funcs[] = {
JS_CFUNC_MAGIC_DEF("reduce", 1, js_array_reduce, special_reduce ),
JS_CFUNC_MAGIC_DEF("reduceRight", 1, js_array_reduce, special_reduceRight ),
JS_CFUNC_DEF("fill", 1, js_array_fill ),
JS_CFUNC_MAGIC_DEF("find", 1, js_array_find, 0 ),
JS_CFUNC_MAGIC_DEF("findIndex", 1, js_array_find, 1 ),
JS_CFUNC_MAGIC_DEF("find", 1, js_array_find, ArrayFind ),
JS_CFUNC_MAGIC_DEF("findIndex", 1, js_array_find, ArrayFindIndex ),
JS_CFUNC_MAGIC_DEF("findLast", 1, js_array_find, ArrayFindLast ),
JS_CFUNC_MAGIC_DEF("findLastIndex", 1, js_array_find, ArrayFindLastIndex ),
JS_CFUNC_DEF("indexOf", 1, js_array_indexOf ),
JS_CFUNC_DEF("lastIndexOf", 1, js_array_lastIndexOf ),
JS_CFUNC_DEF("includes", 1, js_array_includes ),
Expand Down Expand Up @@ -47104,6 +47124,8 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
"fill" "\0"
"find" "\0"
"findIndex" "\0"
"findLast" "\0"
"findLastIndex" "\0"
"flat" "\0"
"flatMap" "\0"
"includes" "\0"
Expand Down
2 changes: 1 addition & 1 deletion test262.conf
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ __setter__
AggregateError
align-detached-buffer-semantics-with-web-reality
arbitrary-module-namespace-names=skip
array-find-from-last=skip
array-find-from-last
array-grouping=skip
Array.fromAsync=skip
Array.prototype.at
Expand Down
96 changes: 96 additions & 0 deletions test262_errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,102 @@ test262/test/built-ins/RegExp/prototype/Symbol.replace/get-unicode-error.js:26:
test262/test/built-ins/RegExp/prototype/Symbol.replace/get-unicode-error.js:26: strict mode: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all
test262/test/built-ins/String/prototype/localeCompare/15.5.4.9_CE.js:62: Test262Error: String.prototype.localeCompare considers ö (\u006f\u0308) ≠ ö (\u00f6).
test262/test/built-ins/String/prototype/localeCompare/15.5.4.9_CE.js:62: strict mode: Test262Error: String.prototype.localeCompare considers ö (\u006f\u0308) ≠ ö (\u00f6).
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/get-length-ignores-length-prop.js:40: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/get-length-ignores-length-prop.js:40: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-call-changes-value.js:30: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-call-changes-value.js:30: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-call-parameters.js:28: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-call-parameters.js:28: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-call-this-non-strict.js:27: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-call-this-strict.js:25: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-may-detach-buffer.js:36: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-may-detach-buffer.js:36: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-not-called-on-empty-array.js:25: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/predicate-not-called-on-empty-array.js:25: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/return-abrupt-from-predicate-call.js:22: Test262Error: Expected a Test262Error but got a TypeError (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/return-abrupt-from-predicate-call.js:22: strict mode: Test262Error: Expected a Test262Error but got a TypeError (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/return-found-value-predicate-result-is-true.js:27: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/return-found-value-predicate-result-is-true.js:27: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/return-undefined-if-predicate-returns-false-value.js:27: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/BigInt/return-undefined-if-predicate-returns-false-value.js:27: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/get-length-ignores-length-prop.js:39: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/get-length-ignores-length-prop.js:39: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/invoked-as-func.js:21: Test262Error: Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/findLast/invoked-as-func.js:21: strict mode: Test262Error: Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/findLast/invoked-as-method.js:21: Test262Error: Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/findLast/invoked-as-method.js:21: strict mode: Test262Error: Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/findLast/length.js:26: TypeError: cannot read property 'length' of undefined
test262/test/built-ins/TypedArray/prototype/findLast/length.js:26: strict mode: TypeError: cannot read property 'length' of undefined
test262/test/built-ins/TypedArray/prototype/findLast/name.js:23: TypeError: cannot read property 'name' of undefined
test262/test/built-ins/TypedArray/prototype/findLast/name.js:23: strict mode: TypeError: cannot read property 'name' of undefined
test262/test/built-ins/TypedArray/prototype/findLast/not-a-constructor.js:25: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArray/prototype/findLast/not-a-constructor.js:25: strict mode: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArray/prototype/findLast/predicate-call-changes-value.js:30: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/predicate-call-changes-value.js:30: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/predicate-call-parameters.js:28: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/predicate-call-parameters.js:28: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/predicate-call-this-non-strict.js:27: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/predicate-call-this-strict.js:25: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/predicate-may-detach-buffer.js:36: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/predicate-may-detach-buffer.js:36: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/predicate-not-called-on-empty-array.js:25: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/predicate-not-called-on-empty-array.js:25: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/prop-desc.js:15: Test262Error: obj should have an own property findLast
test262/test/built-ins/TypedArray/prototype/findLast/prop-desc.js:15: strict mode: Test262Error: obj should have an own property findLast
test262/test/built-ins/TypedArray/prototype/findLast/return-abrupt-from-predicate-call.js:22: Test262Error: Expected a Test262Error but got a TypeError (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/return-abrupt-from-predicate-call.js:22: strict mode: Test262Error: Expected a Test262Error but got a TypeError (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/return-found-value-predicate-result-is-true.js:27: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/return-found-value-predicate-result-is-true.js:27: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/return-undefined-if-predicate-returns-false-value.js:27: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLast/return-undefined-if-predicate-returns-false-value.js:27: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/get-length-ignores-length-prop.js:40: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/get-length-ignores-length-prop.js:40: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-call-changes-value.js:29: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-call-changes-value.js:29: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-call-parameters.js:29: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-call-parameters.js:29: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-call-this-non-strict.js:29: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-call-this-strict.js:27: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-may-detach-buffer.js:35: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-may-detach-buffer.js:35: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-not-called-on-empty-array.js:29: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/predicate-not-called-on-empty-array.js:29: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/return-abrupt-from-predicate-call.js:21: Test262Error: Expected a Test262Error but got a TypeError (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/return-abrupt-from-predicate-call.js:21: strict mode: Test262Error: Expected a Test262Error but got a TypeError (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/return-index-predicate-result-is-true.js:28: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/return-index-predicate-result-is-true.js:28: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/return-negative-one-if-predicate-returns-false-value.js:28: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/BigInt/return-negative-one-if-predicate-returns-false-value.js:28: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/get-length-ignores-length-prop.js:40: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/get-length-ignores-length-prop.js:40: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/invoked-as-func.js:23: Test262Error: Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/findLastIndex/invoked-as-func.js:23: strict mode: Test262Error: Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/findLastIndex/invoked-as-method.js:23: Test262Error: Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/findLastIndex/invoked-as-method.js:23: strict mode: Test262Error: Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/findLastIndex/length.js:26: TypeError: cannot read property 'length' of undefined
test262/test/built-ins/TypedArray/prototype/findLastIndex/length.js:26: strict mode: TypeError: cannot read property 'length' of undefined
test262/test/built-ins/TypedArray/prototype/findLastIndex/name.js:23: TypeError: cannot read property 'name' of undefined
test262/test/built-ins/TypedArray/prototype/findLastIndex/name.js:23: strict mode: TypeError: cannot read property 'name' of undefined
test262/test/built-ins/TypedArray/prototype/findLastIndex/not-a-constructor.js:25: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArray/prototype/findLastIndex/not-a-constructor.js:25: strict mode: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-call-changes-value.js:29: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-call-changes-value.js:29: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-call-parameters.js:29: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-call-parameters.js:29: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-call-this-non-strict.js:29: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-call-this-strict.js:27: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-may-detach-buffer.js:35: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-may-detach-buffer.js:35: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-not-called-on-empty-array.js:29: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/predicate-not-called-on-empty-array.js:29: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/prop-desc.js:15: Test262Error: obj should have an own property findLastIndex
test262/test/built-ins/TypedArray/prototype/findLastIndex/prop-desc.js:15: strict mode: Test262Error: obj should have an own property findLastIndex
test262/test/built-ins/TypedArray/prototype/findLastIndex/return-abrupt-from-predicate-call.js:21: Test262Error: Expected a Test262Error but got a TypeError (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/return-abrupt-from-predicate-call.js:21: strict mode: Test262Error: Expected a Test262Error but got a TypeError (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/return-index-predicate-result-is-true.js:28: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/return-index-predicate-result-is-true.js:28: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/return-negative-one-if-predicate-returns-false-value.js:28: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/findLastIndex/return-negative-one-if-predicate-returns-false-value.js:28: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-on-get-src-value-no-throw.js:30: TypeError: out-of-bound numeric index (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-on-get-src-value-no-throw.js:30: strict mode: TypeError: out-of-bound numeric index (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:30: TypeError: ArrayBuffer is detached (Testing with Float64Array.)
Expand Down