[njs] Array.prototype.lastIndexOf() and Array.prototype.indexOf(...
Andrey Zelenkov
zelenkov at nginx.com
Tue Oct 25 14:33:39 UTC 2016
details: http://hg.nginx.org/njs/rev/76e57071e411
branches:
changeset: 220:76e57071e411
user: Andrey Zelenkov <zelenkov at nginx.com>
date: Mon Oct 24 19:02:31 2016 +0300
description:
Array.prototype.lastIndexOf() and Array.prototype.indexOf() fixes.
The fromIndex parameter processing in lastIndexOf() has been fixed.
The lastIndexOf() search algorithm has been optimized.
The njs_array_index_of() function has been removed.
In collaboration with Valentin Bartenev.
diffstat:
njs/njs_array.c | 125 +++++++++++++++++++++++++++++++++-------------
njs/test/njs_unit_test.c | 25 ++++++++-
2 files changed, 112 insertions(+), 38 deletions(-)
diffs (215 lines):
diff -r 12a38e4e030b -r 76e57071e411 njs/njs_array.c
--- a/njs/njs_array.c Mon Oct 24 18:27:31 2016 +0300
+++ b/njs/njs_array.c Mon Oct 24 19:02:31 2016 +0300
@@ -84,8 +84,6 @@ static njs_ret_t njs_array_prototype_to_
static njs_ret_t njs_array_prototype_join_continuation(njs_vm_t *vm,
njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
static 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 njs_ret_t njs_array_prototype_for_each_continuation(njs_vm_t *vm,
njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
static njs_ret_t njs_array_prototype_some_continuation(njs_vm_t *vm,
@@ -974,7 +972,59 @@ 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);
+ nxt_int_t i, index, length;
+ njs_value_t *value, *start;
+ njs_array_t *array;
+
+ index = -1;
+
+ if (nargs < 2 || !njs_is_array(&args[0])) {
+ goto done;
+ }
+
+ array = args[0].data.u.array;
+ length = array->length;
+
+ if (length == 0) {
+ goto done;
+ }
+
+ i = 0;
+
+ if (nargs > 2) {
+ i = args[2].data.u.number;
+
+ if (i >= length) {
+ goto done;
+ }
+
+ if (i < 0) {
+ i += length;
+
+ if (i < 0) {
+ i = 0;
+ }
+ }
+ }
+
+ value = &args[1];
+ start = array->start;
+
+ do {
+ if (njs_values_strict_equal(value, &start[i])) {
+ index = i;
+ break;
+ }
+
+ i++;
+
+ } while (i < length);
+
+done:
+
+ njs_number_set(&vm->retval, index);
+
+ return NXT_OK;
}
@@ -982,51 +1032,54 @@ 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;
+ nxt_int_t i, n, index, length;
+ njs_value_t *value, *start;
njs_array_t *array;
index = -1;
- if (nargs > 1 && njs_is_array(&args[0])) {
- i = 0;
- array = args[0].data.u.array;
- length = array->length;
+ if (nargs < 2 || !njs_is_array(&args[0])) {
+ goto done;
+ }
- if (nargs > 2) {
- i = args[2].data.u.number;
+ array = args[0].data.u.array;
+ length = array->length;
+
+ if (length == 0) {
+ goto done;
+ }
+
+ i = length - 1;
+
+ if (nargs > 2) {
+ n = args[2].data.u.number;
+
+ if (n < 0) {
+ i = n + length;
if (i < 0) {
- i += length;
+ goto done;
+ }
- if (i < 0) {
- i = 0;
- }
- }
+ } else if (n < length) {
+ i = n;
+ }
+ }
+
+ value = &args[1];
+ start = array->start;
+
+ do {
+ if (njs_values_strict_equal(value, &start[i])) {
+ index = i;
+ break;
}
- value = &args[1];
-
- while (i < length) {
- if (njs_values_strict_equal(value, &array->start[i])) {
- index = i;
+ i--;
- if (first) {
- break;
- }
- }
+ } while (i >= 0);
- i++;
- }
- }
+done:
njs_number_set(&vm->retval, index);
diff -r 12a38e4e030b -r 76e57071e411 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Mon Oct 24 18:27:31 2016 +0300
+++ b/njs/test/njs_unit_test.c Mon Oct 24 19:02:31 2016 +0300
@@ -2362,6 +2362,12 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("var a = [1,2,3,4]; a.indexOf(5)"),
nxt_string("-1") },
+ { nxt_string("var a = [1,2,3,4]; a.indexOf(4, 3)"),
+ nxt_string("3") },
+
+ { nxt_string("var a = [1,2,3,4]; a.indexOf(4, 4)"),
+ nxt_string("-1") },
+
{ nxt_string("var a = [1,2,3,4,3,4]; a.indexOf(3, '2')"),
nxt_string("2") },
@@ -2374,20 +2380,35 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("[].indexOf.bind(0)(0, 0)"),
nxt_string("-1") },
+ { nxt_string("[].lastIndexOf(1, -1)"),
+ nxt_string("-1") },
+
{ 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(1, 0)"),
+ nxt_string("0") },
+
{ nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(3, '2')"),
- nxt_string("4") },
+ nxt_string("2") },
+
+ { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(1, 6)"),
+ nxt_string("0") },
+
+ { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(2, 6)"),
+ nxt_string("1") },
{ 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(4, -6)"),
+ nxt_string("-1") },
+
{ nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(3, -10)"),
- nxt_string("4") },
+ nxt_string("-1") },
{ nxt_string("var a = []; var s = { sum: 0 };"
"a.forEach(function(v, i, a) { this.sum += v }, s); s.sum"),
More information about the nginx-devel
mailing list