summaryrefslogtreecommitdiff
path: root/quickjs.c
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2023-12-09 12:33:05 +0100
committerFabrice Bellard <fabrice@bellard.org>2023-12-09 12:33:05 +0100
commita0570086c698f78ec829cafd7d8d7ac3906abbc1 (patch)
tree968af2b652c4675970170e61d4aae40b0b435b42 /quickjs.c
parent177af416659188e114545d1194b23463baef2598 (diff)
downloadquickjs-a0570086c698f78ec829cafd7d8d7ac3906abbc1.tar.gz
quickjs-a0570086c698f78ec829cafd7d8d7ac3906abbc1.zip
added Array.prototype.findLast{Index} and TypeArray.prototype.findLast{index} (initial patch by bnoordhuis)
Diffstat (limited to 'quickjs.c')
-rw-r--r--quickjs.c77
1 files changed, 61 insertions, 16 deletions
diff --git a/quickjs.c b/quickjs.c
index d80d601..4c4d273 100644
--- a/quickjs.c
+++ b/quickjs.c
@@ -38496,13 +38496,21 @@ static JSValue js_array_lastIndexOf(JSContext *ctx, JSValueConst this_val,
return JS_EXCEPTION;
}
+enum {
+ special_find,
+ special_findIndex,
+ special_findLast,
+ special_findLastIndex,
+};
+
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;
@@ -38518,7 +38526,18 @@ static JSValue js_array_find(JSContext *ctx, JSValueConst this_val,
if (argc > 1)
this_arg = argv[1];
- for(k = 0; k < len; k++) {
+ if (mode == special_findLast || mode == special_findLastIndex) {
+ k = len - 1;
+ dir = -1;
+ end = -1;
+ } else {
+ k = 0;
+ dir = 1;
+ end = len;
+ }
+
+ // 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;
@@ -38532,7 +38551,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 == special_findIndex || mode == special_findLastIndex) {
JS_FreeValue(ctx, val);
JS_FreeValue(ctx, obj);
return index_val;
@@ -38546,7 +38565,7 @@ static JSValue js_array_find(JSContext *ctx, JSValueConst this_val,
JS_FreeValue(ctx, index_val);
}
JS_FreeValue(ctx, obj);
- if (findIndex)
+ if (mode == special_findIndex || mode == special_findLastIndex)
return JS_NewInt32(ctx, -1);
else
return JS_UNDEFINED;
@@ -39369,8 +39388,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, special_find ),
+ JS_CFUNC_MAGIC_DEF("findIndex", 1, js_array_find, special_findIndex ),
+ JS_CFUNC_MAGIC_DEF("findLast", 1, js_array_find, special_findLast ),
+ JS_CFUNC_MAGIC_DEF("findLastIndex", 1, js_array_find, special_findLastIndex ),
JS_CFUNC_DEF("indexOf", 1, js_array_indexOf ),
JS_CFUNC_DEF("lastIndexOf", 1, js_array_lastIndexOf ),
JS_CFUNC_DEF("includes", 1, js_array_includes ),
@@ -50725,8 +50746,19 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
/* XXX: create auto_initializer */
{
/* initialize Array.prototype[Symbol.unscopables] */
- char const unscopables[] = "copyWithin" "\0" "entries" "\0" "fill" "\0" "find" "\0"
- "findIndex" "\0" "flat" "\0" "flatMap" "\0" "includes" "\0" "keys" "\0" "values" "\0";
+ char const unscopables[] =
+ "copyWithin" "\0"
+ "entries" "\0"
+ "fill" "\0"
+ "find" "\0"
+ "findIndex" "\0"
+ "findLast" "\0"
+ "findLastIndex" "\0"
+ "flat" "\0"
+ "flatMap" "\0"
+ "includes" "\0"
+ "keys" "\0"
+ "values" "\0";
const char *p = unscopables;
obj1 = JS_NewObjectProto(ctx, JS_NULL);
for(p = unscopables; *p; p += strlen(p) + 1) {
@@ -51791,12 +51823,13 @@ static JSValue js_typed_array_fill(JSContext *ctx, JSValueConst this_val,
}
static JSValue js_typed_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 val, index_val, res;
- int len, k;
+ int len, k, end;
+ int dir;
val = JS_UNDEFINED;
len = js_typed_array_get_length_internal(ctx, this_val);
@@ -51811,7 +51844,17 @@ static JSValue js_typed_array_find(JSContext *ctx, JSValueConst this_val,
if (argc > 1)
this_arg = argv[1];
- for(k = 0; k < len; k++) {
+ if (mode == special_findLast || mode == special_findLastIndex) {
+ k = len - 1;
+ dir = -1;
+ end = -1;
+ } else {
+ k = 0;
+ dir = 1;
+ end = len;
+ }
+
+ for(; k != end; k += dir) {
index_val = JS_NewInt32(ctx, k);
val = JS_GetPropertyValue(ctx, this_val, index_val);
if (JS_IsException(val))
@@ -51823,7 +51866,7 @@ static JSValue js_typed_array_find(JSContext *ctx, JSValueConst this_val,
if (JS_IsException(res))
goto exception;
if (JS_ToBoolFree(ctx, res)) {
- if (findIndex) {
+ if (mode == special_findIndex || mode == special_findLastIndex) {
JS_FreeValue(ctx, val);
return index_val;
} else {
@@ -51832,7 +51875,7 @@ static JSValue js_typed_array_find(JSContext *ctx, JSValueConst this_val,
}
JS_FreeValue(ctx, val);
}
- if (findIndex)
+ if (mode == special_findIndex || mode == special_findLastIndex)
return JS_NewInt32(ctx, -1);
else
return JS_UNDEFINED;
@@ -52630,8 +52673,10 @@ static const JSCFunctionListEntry js_typed_array_base_proto_funcs[] = {
JS_CFUNC_MAGIC_DEF("reduce", 1, js_array_reduce, special_reduce | special_TA ),
JS_CFUNC_MAGIC_DEF("reduceRight", 1, js_array_reduce, special_reduceRight | special_TA ),
JS_CFUNC_DEF("fill", 1, js_typed_array_fill ),
- JS_CFUNC_MAGIC_DEF("find", 1, js_typed_array_find, 0 ),
- JS_CFUNC_MAGIC_DEF("findIndex", 1, js_typed_array_find, 1 ),
+ JS_CFUNC_MAGIC_DEF("find", 1, js_typed_array_find, special_find ),
+ JS_CFUNC_MAGIC_DEF("findIndex", 1, js_typed_array_find, special_findIndex ),
+ JS_CFUNC_MAGIC_DEF("findLast", 1, js_typed_array_find, special_findLast ),
+ JS_CFUNC_MAGIC_DEF("findLastIndex", 1, js_typed_array_find, special_findLastIndex ),
JS_CFUNC_DEF("reverse", 0, js_typed_array_reverse ),
JS_CFUNC_DEF("slice", 2, js_typed_array_slice ),
JS_CFUNC_DEF("subarray", 2, js_typed_array_subarray ),