[njs] Array.indexOf() and Array.lastIndexOf() functions.

Igor Sysoev igor at sysoev.ru
Thu Aug 11 13:39:52 UTC 2016


details:   http://hg.nginx.org/njs/rev/050db82b0d46
branches:  
changeset: 150:050db82b0d46
user:      Igor Sysoev <igor at sysoev.ru>
date:      Wed Aug 10 15:52:25 2016 +0300
description:
Array.indexOf() and Array.lastIndexOf() functions.

diffstat:

 njs/njs_array.c          |  80 ++++++++++++++++++++++++++++++++++++++++++++++++
 njs/njs_vm.c             |   4 +-
 njs/njs_vm.h             |   2 +
 njs/test/njs_unit_test.c |  30 ++++++++++++++++++
 4 files changed, 113 insertions(+), 3 deletions(-)

diffs (177 lines):

diff -r bd3464a20ad2 -r 050db82b0d46 njs/njs_array.c
--- a/njs/njs_array.c	Wed Aug 10 11:57:56 2016 +0300
+++ b/njs/njs_array.c	Wed Aug 10 15:52:25 2016 +0300
@@ -58,6 +58,8 @@ static njs_ret_t njs_array_prototype_joi
     njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
 static nxt_noinline njs_value_t *njs_array_copy(njs_value_t *dst,
     njs_value_t *src);
+static njs_ret_t njs_array_index_of(njs_vm_t *vm, njs_value_t *args,
+    nxt_uint_t nargs, nxt_bool_t first);
 static nxt_noinline njs_ret_t njs_array_prototype_for_each_cont(njs_vm_t *vm,
     njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
 static nxt_noinline njs_ret_t njs_array_prototype_some_cont(njs_vm_t *vm,
@@ -836,6 +838,70 @@ njs_array_copy(njs_value_t *dst, njs_val
 
 
 static njs_ret_t
+njs_array_prototype_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    njs_index_t unused)
+{
+    return njs_array_index_of(vm, args, nargs, 1);
+}
+
+
+static njs_ret_t
+njs_array_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args,
+    nxt_uint_t nargs, njs_index_t unused)
+{
+    return njs_array_index_of(vm, args, nargs, 0);
+}
+
+
+static njs_ret_t
+njs_array_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    nxt_bool_t first)
+{
+    nxt_int_t    i, index, length;
+    njs_value_t  *value;
+    njs_array_t  *array;
+
+    index = -1;
+
+    if (nargs > 1) {
+        i = 0;
+        array = args[0].data.u.array;
+        length = array->length;
+
+        if (nargs > 2) {
+            i = args[2].data.u.number;
+
+            if (i < 0) {
+                i += length;
+
+                if (i < 0) {
+                    i = 0;
+                }
+            }
+        }
+
+        value = &args[1];
+
+        while (i < length) {
+            if (njs_values_strict_equal(value, &array->start[i])) {
+                index = i;
+
+                if (first) {
+                    break;
+                }
+            }
+
+            i++;
+        }
+    }
+
+    njs_number_set(&vm->retval, index);
+
+    return NXT_OK;
+}
+
+
+static njs_ret_t
 njs_array_prototype_for_each(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     njs_index_t unused)
 {
@@ -1399,6 +1465,20 @@ static const njs_object_prop_t  njs_arra
 
     {
         .type = NJS_METHOD,
+        .name = njs_string("indexOf"),
+        .value = njs_native_function(njs_array_prototype_index_of, 0,
+                     NJS_OBJECT_ARG, NJS_SKIP_ARG, NJS_INTEGER_ARG),
+    },
+
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("lastIndexOf"),
+        .value = njs_native_function(njs_array_prototype_last_index_of, 0,
+                     NJS_OBJECT_ARG, NJS_SKIP_ARG, NJS_INTEGER_ARG),
+    },
+
+    {
+        .type = NJS_METHOD,
         .name = njs_string("forEach"),
         .value = njs_native_function(njs_array_prototype_for_each,
                      njs_continuation_size(njs_array_iter_t), 0),
diff -r bd3464a20ad2 -r 050db82b0d46 njs/njs_vm.c
--- a/njs/njs_vm.c	Wed Aug 10 11:57:56 2016 +0300
+++ b/njs/njs_vm.c	Wed Aug 10 15:52:25 2016 +0300
@@ -82,8 +82,6 @@ static nxt_noinline njs_ret_t njs_values
     njs_value_t *val2);
 static nxt_noinline njs_ret_t njs_values_compare(njs_value_t *val1,
     njs_value_t *val2);
-static nxt_noinline nxt_bool_t njs_values_strict_equal(njs_value_t *val1,
-    njs_value_t *val2);
 static njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *value);
 static njs_ret_t njs_vmcode_continuation(njs_vm_t *vm, njs_value_t *invld1,
     njs_value_t *invld2);
@@ -2006,7 +2004,7 @@ njs_vmcode_strict_not_equal(njs_vm_t *vm
 }
 
 
-static nxt_noinline nxt_bool_t
+nxt_noinline nxt_bool_t
 njs_values_strict_equal(njs_value_t *val1, njs_value_t *val2)
 {
     size_t        size;
diff -r bd3464a20ad2 -r 050db82b0d46 njs/njs_vm.h
--- a/njs/njs_vm.h	Wed Aug 10 11:57:56 2016 +0300
+++ b/njs/njs_vm.h	Wed Aug 10 15:52:25 2016 +0300
@@ -958,6 +958,8 @@ njs_ret_t njs_vmcode_catch(njs_vm_t *vm,
 njs_ret_t njs_vmcode_finally(njs_vm_t *vm, njs_value_t *invld,
     njs_value_t *retval);
 
+nxt_bool_t njs_values_strict_equal(njs_value_t *val1, njs_value_t *val2);
+
 njs_ret_t njs_normalize_args(njs_vm_t *vm, njs_value_t *args,
     uint8_t *args_types, nxt_uint_t nargs);
 
diff -r bd3464a20ad2 -r 050db82b0d46 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Wed Aug 10 11:57:56 2016 +0300
+++ b/njs/test/njs_unit_test.c	Wed Aug 10 15:52:25 2016 +0300
@@ -2271,6 +2271,36 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var a = [1,2,3,4]; a.reverse()"),
       nxt_string("4,3,2,1") },
 
+    { nxt_string("var a = [1,2,3,4]; a.indexOf()"),
+      nxt_string("-1") },
+
+    { nxt_string("var a = [1,2,3,4]; a.indexOf(5)"),
+      nxt_string("-1") },
+
+    { nxt_string("var a = [1,2,3,4,3,4]; a.indexOf(3, '2')"),
+      nxt_string("2") },
+
+    { nxt_string("var a = [1,2,3,4,3,4]; a.indexOf(4, -1)"),
+      nxt_string("5") },
+
+    { nxt_string("var a = [1,2,3,4,3,4]; a.indexOf(3, -10)"),
+      nxt_string("2") },
+
+    { nxt_string("var a = [1,2,3,4]; a.lastIndexOf()"),
+      nxt_string("-1") },
+
+    { nxt_string("var a = [1,2,3,4]; a.lastIndexOf(5)"),
+      nxt_string("-1") },
+
+    { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(3, '2')"),
+      nxt_string("4") },
+
+    { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(4, -1)"),
+      nxt_string("5") },
+
+    { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(3, -10)"),
+      nxt_string("4") },
+
     { nxt_string("var a = []; var s = { sum: 0 };"
                  "a.forEach(function(v, i, a) { this.sum += v }, s); s.sum"),
       nxt_string("0") },



More information about the nginx-devel mailing list