Welcome! Log In Create A New Profile

Advanced

[njs] Array.reduce() function.

August 09, 2016 08:52AM
details: http://hg.nginx.org/njs/rev/5bd9c6bea8a6
branches:
changeset: 147:5bd9c6bea8a6
user: Igor Sysoev <igor@sysoev.ru>
date: Tue Aug 09 14:10:32 2016 +0300
description:
Array.reduce() function.

diffstat:

njs/njs_array.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++
njs/test/njs_unit_test.c | 36 +++++++++++++++++++
2 files changed, 126 insertions(+), 0 deletions(-)

diffs (160 lines):

diff -r 43b3a67ee1f1 -r 5bd9c6bea8a6 njs/njs_array.c
--- a/njs/njs_array.c Tue Aug 09 14:10:31 2016 +0300
+++ b/njs/njs_array.c Tue Aug 09 14:10:32 2016 +0300
@@ -68,6 +68,8 @@ static njs_ret_t njs_array_prototype_fil
njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
static njs_ret_t njs_array_prototype_map_cont(njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, njs_index_t unused);
+static njs_ret_t njs_array_prototype_reduce_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_iterator_args(njs_vm_t *vm,
njs_value_t *args, nxt_uint_t nargs);
static nxt_noinline uint32_t njs_array_iterator_next(njs_array_t *array,
@@ -1046,6 +1048,87 @@ njs_array_prototype_map_cont(njs_vm_t *v
}


+static njs_ret_t
+njs_array_prototype_reduce(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+ njs_index_t unused)
+{
+ uint32_t n;
+ nxt_int_t ret;
+ njs_array_t *array;
+ njs_array_iter_t *iter;
+
+ ret = njs_array_iterator_args(vm, args, nargs);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+
+ iter = njs_continuation(vm->frame);
+ iter->u.cont.function = njs_array_prototype_reduce_cont;
+
+ if (nargs > 2) {
+ iter->retval = args[2];
+
+ } else {
+ array = args[0].data.u.array;
+ n = iter->next_index;
+
+ if (n >= array->length) {
+ vm->exception = &njs_exception_type_error;
+ return NXT_ERROR;
+ }
+
+ iter->retval = array->start[n];
+
+ iter->next_index = njs_array_iterator_next(array, n + 1, array->length);
+ }
+
+ return njs_array_prototype_reduce_cont(vm, args, nargs, unused);
+}
+
+
+static njs_ret_t
+njs_array_prototype_reduce_cont(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ nxt_int_t n;
+ njs_array_t *array;
+ njs_value_t arguments[5];
+ njs_array_iter_t *iter;
+
+ iter = njs_continuation(vm->frame);
+
+ if (iter->next_index >= args[0].data.u.array->length) {
+ vm->retval = iter->retval;
+ return NXT_OK;
+ }
+
+ arguments[0] = njs_value_void;
+
+ /* GC: array elt, array */
+ arguments[1] = iter->retval;
+
+ /*
+ * All array iterators functions call njs_array_iterator_args()
+ * function which set a correct iter->next_index value. A large
+ * value of iter->next_index must be checked before calling
+ * njs_array_iterator_apply().
+ */
+ array = args[0].data.u.array;
+ n = iter->next_index;
+
+ arguments[2] = array->start[n];
+
+ njs_number_set(&arguments[3], n);
+
+ arguments[4] = args[0];
+
+ iter->next_index = njs_array_iterator_next(array, n + 1, iter->length);
+
+ return njs_function_apply(vm, args[1].data.u.function, arguments, 5,
+ (njs_index_t) &iter->retval);
+}
+
+
static nxt_noinline njs_ret_t
njs_array_iterator_args(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs)
{
@@ -1224,6 +1307,13 @@ static const njs_object_prop_t njs_arra
.value = njs_native_function(njs_array_prototype_map,
njs_continuation_size(njs_array_iter_t), 0),
},
+
+ {
+ .type = NJS_METHOD,
+ .name = njs_string("reduce"),
+ .value = njs_native_function(njs_array_prototype_reduce,
+ njs_continuation_size(njs_array_iter_t), 0),
+ },
};


diff -r 43b3a67ee1f1 -r 5bd9c6bea8a6 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Tue Aug 09 14:10:31 2016 +0300
+++ b/njs/test/njs_unit_test.c Tue Aug 09 14:10:32 2016 +0300
@@ -2385,6 +2385,42 @@ static njs_unit_test_t njs_test[] =
"a.map(function(v, i, a) { a.pop(); return v + 1 })"),
nxt_string("2,3,4,,,") },

+ { nxt_string("var a = [];"
+ "a.reduce(function(p, v, i, a) { return p + v })"),
+ nxt_string("TypeError") },
+
+ { nxt_string("var a = [];"
+ "a.reduce(function(p, v, i, a) { return p + v }, 10)"),
+ nxt_string("10") },
+
+ { nxt_string("var a = [,,];"
+ "a.reduce(function(p, v, i, a) { return p + v })"),
+ nxt_string("TypeError") },
+
+ { nxt_string("var a = [,,];"
+ "a.reduce(function(p, v, i, a) { return p + v }, 10)"),
+ nxt_string("10") },
+
+ { nxt_string("var a = [1];"
+ "a.reduce(function(p, v, i, a) { return p + v })"),
+ nxt_string("1") },
+
+ { nxt_string("var a = [1];"
+ "a.reduce(function(p, v, i, a) { return p + v }, 10)"),
+ nxt_string("11") },
+
+ { nxt_string("var a = [1,2,3];"
+ "a.reduce(function(p, v, i, a) { return p + v })"),
+ nxt_string("6") },
+
+ { nxt_string("var a = [1,2,3];"
+ "a.reduce(function(p, v, i, a) { return p + v }, 10)"),
+ nxt_string("16") },
+
+ { nxt_string("[[0, 1], [2, 3], [4, 5]].reduce(function(a, b)"
+ " { return a.concat(b) }, [])"),
+ nxt_string("0,1,2,3,4,5") },
+
/* Strings. */

{ nxt_string("var a = '0123456789' + '012345'"

_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Array.reduce() function.

Igor Sysoev 557 August 09, 2016 08:52AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 235
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready