[njs] Refactored working with function calls.
Dmitry Volyntsev
xeioex at nginx.com
Fri Jul 19 20:28:16 UTC 2019
details: https://hg.nginx.org/njs/rev/540f03725df2
branches:
changeset: 1061:540f03725df2
user: hongzhidao <hongzhidao at gmail.com>
date: Tue Jul 16 22:44:16 2019 -0400
description:
Refactored working with function calls.
1) njs_continuation_t is removed (appropriate functions
are rewritten).
2) all function calls are made syncronous.
This closes #190 issue on Github.
diffstat:
njs/njs.c | 24 +-
njs/njs_array.c | 1303 +++++++++++++++-----------------------------
njs/njs_boolean.c | 4 +-
njs/njs_builtin.c | 2 +-
njs/njs_crypto.c | 16 +-
njs/njs_date.c | 158 ++--
njs/njs_error.c | 7 +-
njs/njs_fs.c | 66 +-
njs/njs_function.c | 232 ++-----
njs/njs_function.h | 75 +-
njs/njs_json.c | 173 +++--
njs/njs_math.c | 126 ++--
njs/njs_number.c | 20 +-
njs/njs_object.c | 42 +-
njs/njs_object.h | 4 +-
njs/njs_object_property.c | 18 +-
njs/njs_regexp.c | 10 +-
njs/njs_string.c | 133 +--
njs/njs_value.c | 7 +-
njs/njs_value.h | 3 +-
njs/njs_vm.c | 136 +---
njs/njs_vm.h | 11 +-
njs/test/njs_unit_test.c | 9 +-
23 files changed, 986 insertions(+), 1593 deletions(-)
diffs (truncated from 5002 to 1000 lines):
diff -r 201af81dfa9b -r 540f03725df2 njs/njs.c
--- a/njs/njs.c Fri Jul 05 21:45:28 2019 +0300
+++ b/njs/njs.c Tue Jul 16 22:44:16 2019 -0400
@@ -456,7 +456,7 @@ nxt_int_t
njs_vm_call(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args,
nxt_uint_t nargs)
{
- return njs_vm_invoke(vm, function, args, nargs, NJS_INDEX_GLOBAL_RETVAL);
+ return njs_vm_invoke(vm, function, args, nargs, (njs_index_t) &vm->retval);
}
@@ -464,30 +464,18 @@ nxt_int_t
njs_vm_invoke(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args,
nxt_uint_t nargs, njs_index_t retval)
{
- u_char *current;
njs_ret_t ret;
njs_value_t *this;
this = (njs_value_t *) &njs_value_undefined;
- current = vm->current;
-
- vm->current = (u_char *) njs_continuation_nexus;
-
- ret = njs_function_activate(vm, function, this, args, nargs, retval,
- sizeof(njs_vmcode_generic_t));
-
- if (nxt_fast_path(ret == NJS_APPLIED)) {
- ret = njs_vmcode_interpreter(vm);
-
- if (ret == NJS_STOP) {
- ret = NXT_OK;
- }
+ ret = njs_function_frame(vm, function, this, (njs_value_t *) args, nargs,
+ 0);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
}
- vm->current = current;
-
- return ret;
+ return njs_function_frame_invoke(vm, retval);
}
diff -r 201af81dfa9b -r 540f03725df2 njs/njs_array.c
--- a/njs/njs_array.c Fri Jul 05 21:45:28 2019 +0300
+++ b/njs/njs_array.c Tue Jul 16 22:44:16 2019 -0400
@@ -9,133 +9,9 @@
#include <stdint.h>
-typedef struct {
- union {
- njs_continuation_t cont;
- u_char padding[NJS_CONTINUATION_SIZE];
- } u;
- /*
- * This retval value must be aligned so the continuation is padded
- * to aligned size.
- */
- njs_value_t length;
-} njs_array_slice_t;
-
-
-typedef struct {
- union {
- njs_continuation_t cont;
- u_char padding[NJS_CONTINUATION_SIZE];
- } u;
-
- njs_value_t length;
- nxt_int_t start;
- nxt_int_t end;
-} njs_array_fill_t;
-
-
-typedef struct {
- njs_continuation_t cont;
- njs_value_t *values;
- uint32_t max;
-} njs_array_join_t;
-
-
-typedef struct {
- union {
- njs_continuation_t cont;
- u_char padding[NJS_CONTINUATION_SIZE];
- } u;
- /*
- * This retval value must be aligned so the continuation is padded
- * to aligned size.
- */
- njs_value_t retval;
-
- uint32_t index;
- uint32_t length;
-} njs_array_iter_t;
-
-
-typedef struct {
- njs_array_iter_t iter;
- njs_value_t value;
- njs_array_t *array;
-} njs_array_filter_t;
-
-
-typedef struct {
- njs_array_iter_t iter;
- njs_value_t value;
-} njs_array_find_t;
-
-
-typedef struct {
- njs_array_iter_t iter;
- njs_array_t *array;
-} njs_array_map_t;
-
-
-typedef struct {
- union {
- njs_continuation_t cont;
- u_char padding[NJS_CONTINUATION_SIZE];
- } u;
- /*
- * This retval value must be aligned so the continuation is padded
- * to aligned size.
- */
- njs_value_t retval;
-
- njs_function_t *function;
- uint32_t index;
- uint32_t current;
-} njs_array_sort_t;
-
-
-static njs_ret_t njs_array_prototype_slice_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
static njs_ret_t njs_array_prototype_slice_copy(njs_vm_t *vm,
njs_value_t *this, int64_t start, int64_t length);
-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_prototype_fill_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static njs_ret_t njs_array_prototype_fill_object_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-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,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static njs_ret_t njs_array_prototype_every_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static njs_ret_t njs_array_prototype_filter_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static njs_ret_t njs_array_prototype_find_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static njs_ret_t njs_array_prototype_find_index_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static njs_ret_t njs_array_prototype_map_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static uint32_t njs_array_prototype_map_index(njs_array_t *array,
- njs_array_map_t *map);
-static njs_ret_t njs_array_iterator_args(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs);
-static uint32_t njs_array_iterator_index(njs_array_t *array,
- njs_array_iter_t *iter);
-static njs_ret_t njs_array_iterator_apply(njs_vm_t *vm,
- njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs);
-static njs_ret_t njs_array_prototype_find_apply(njs_vm_t *vm,
- njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs);
-static njs_ret_t njs_array_prototype_reduce_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static njs_ret_t njs_array_prototype_reduce_right_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
-static uint32_t njs_array_reduce_right_index(njs_array_t *array,
- njs_array_iter_t *iter);
-static njs_ret_t njs_array_prototype_sort_continuation(njs_vm_t *vm,
- njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
njs_array_t *
@@ -407,7 +283,7 @@ static const njs_object_prop_t njs_arra
{
.type = NJS_METHOD,
.name = njs_string("isArray"),
- .value = njs_native_function(njs_array_is_array, 0, 0),
+ .value = njs_native_function(njs_array_is_array, 0),
.writable = 1,
.configurable = 1,
},
@@ -417,7 +293,7 @@ static const njs_object_prop_t njs_arra
{
.type = NJS_METHOD,
.name = njs_string("of"),
- .value = njs_native_function(njs_array_of, 0, 0),
+ .value = njs_native_function(njs_array_of, 0),
.writable = 1,
.configurable = 1,
},
@@ -517,44 +393,26 @@ static njs_ret_t
njs_array_prototype_slice(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
njs_index_t unused)
{
- njs_ret_t ret;
- njs_array_slice_t *slice;
-
- static const njs_value_t njs_string_length = njs_string("length");
-
- slice = njs_vm_continuation(vm);
- slice->u.cont.function = njs_array_prototype_slice_continuation;
-
- ret = njs_value_property(vm, &args[0], &njs_string_length, &slice->length,
- 0);
-
- if (nxt_slow_path(ret == NXT_ERROR || ret == NJS_APPLIED)) {
+ int64_t start, end, length;
+ njs_ret_t ret;
+ njs_value_t prop_length;
+
+ static const njs_value_t string_length = njs_string("length");
+
+ ret = njs_value_property(vm, &args[0], &string_length, &prop_length);
+ if (nxt_slow_path(ret == NXT_ERROR)) {
return ret;
}
- return njs_array_prototype_slice_continuation(vm, args, nargs, unused);
-}
-
-
-static njs_ret_t
-njs_array_prototype_slice_continuation(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused)
-{
- int64_t start, end, length;
- njs_ret_t ret;
- njs_array_slice_t *slice;
-
- slice = njs_vm_continuation(vm);
-
- if (nxt_slow_path(!njs_is_primitive(&slice->length))) {
- ret = njs_value_to_numeric(vm, &slice->length, &slice->length);
+ if (nxt_slow_path(!njs_is_primitive(&prop_length))) {
+ ret = njs_value_to_numeric(vm, &prop_length, &prop_length);
if (ret != NXT_OK) {
return ret;
}
}
start = njs_primitive_value_to_integer(njs_arg(args, nargs, 1));
- length = njs_primitive_value_to_length(&slice->length);
+ length = njs_primitive_value_to_length(&prop_length);
if (start < 0) {
start += length;
@@ -675,7 +533,7 @@ njs_array_prototype_slice_copy(njs_vm_t
njs_uint32_to_string(&name, start++);
value = &array->start[n++];
- ret = njs_value_property(vm, this, &name, value, 0);
+ ret = njs_value_property(vm, this, &name, value);
if (ret != NXT_OK) {
*value = njs_value_invalid;
@@ -970,8 +828,8 @@ njs_array_prototype_to_string(njs_vm_t *
prop = njs_object_property(vm, njs_object(&args[0]), &lhq);
if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) {
- return njs_function_call(vm, njs_function(&prop->value), args,
- nargs, (njs_index_t) &vm->retval);
+ return njs_function_apply(vm, njs_function(&prop->value), args,
+ nargs, &vm->retval);
}
}
@@ -983,26 +841,24 @@ static njs_ret_t
njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
njs_index_t unused)
{
- uint32_t max;
- nxt_uint_t i, n;
- njs_array_t *array;
- njs_value_t *value, *values;
- njs_array_join_t *join;
-
- if (!njs_is_array(&args[0])) {
- goto empty;
+ u_char *p;
+ uint32_t max;
+ size_t size, length, mask;
+ njs_ret_t ret;
+ nxt_uint_t i, n;
+ njs_array_t *array;
+ njs_value_t *value, *values;
+ njs_string_prop_t separator, string;
+
+ if (!njs_is_array(&args[0]) || njs_array_len(&args[0]) == 0) {
+ vm->retval = njs_string_empty;
+ return NXT_OK;
}
array = njs_array(&args[0]);
- if (array->length == 0) {
- goto empty;
- }
-
- join = njs_vm_continuation(vm);
- join->values = NULL;
- join->max = 0;
max = 0;
+ values = NULL;
for (i = 0; i < array->length; i++) {
value = &array->start[i];
@@ -1023,11 +879,6 @@ njs_array_prototype_join(njs_vm_t *vm, n
return NXT_ERROR;
}
- join = njs_vm_continuation(vm);
- join->cont.function = njs_array_prototype_join_continuation;
- join->values = values;
- join->max = max;
-
n = 0;
for (i = 0; i < array->length; i++) {
@@ -1046,34 +897,6 @@ njs_array_prototype_join(njs_vm_t *vm, n
}
}
- return njs_array_prototype_join_continuation(vm, args, nargs, unused);
-
-empty:
-
- vm->retval = njs_string_empty;
-
- return NXT_OK;
-}
-
-
-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)
-{
- u_char *p;
- size_t size, length, mask;
- uint32_t max;
- njs_ret_t ret;
- nxt_uint_t i, n;
- njs_array_t *array;
- njs_value_t *value, *values;
- njs_array_join_t *join;
- njs_string_prop_t separator, string;
-
- join = njs_vm_continuation(vm);
- values = join->values;
- max = join->max;
-
size = 0;
length = 0;
n = 0;
@@ -1422,11 +1245,14 @@ static njs_ret_t
njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
njs_index_t unused)
{
- njs_ret_t ret;
- njs_value_t *this;
- njs_array_fill_t *fill;
-
- static const njs_value_t njs_string_length = njs_string("length");
+ njs_ret_t ret;
+ nxt_int_t i, start, end, length;
+ njs_array_t *array;
+ njs_value_t name, prop_length;
+ njs_object_t *object;
+ const njs_value_t *this, *value;
+
+ static const njs_value_t string_length = njs_string("length");
this = (njs_value_t *) njs_arg(args, nargs, 0);
@@ -1437,38 +1263,6 @@ njs_array_prototype_fill(njs_vm_t *vm, n
return NJS_ERROR;
}
- } else if (!njs_is_array(this)) {
- fill = njs_vm_continuation(vm);
- fill->u.cont.function = njs_array_prototype_fill_continuation;
-
- ret = njs_value_property(vm, this, &njs_string_length, &fill->length,
- 0);
-
- if (nxt_slow_path(ret == NXT_ERROR || ret == NJS_APPLIED)) {
- return ret;
- }
- }
-
- return njs_array_prototype_fill_continuation(vm, args, nargs, unused);
-}
-
-
-static njs_ret_t
-njs_array_prototype_fill_continuation(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused)
-{
- nxt_int_t i, start, end, length;
- njs_ret_t ret;
- njs_array_t *array;
- njs_object_t *object;
- njs_array_fill_t *fill;
- const njs_value_t *this, *value;
-
- array = NULL;
-
- this = njs_arg(args, nargs, 0);
-
- if (njs_is_primitive(this)) {
object = njs_object_value_alloc(vm, this, this->type);
if (nxt_slow_path(object == NULL)) {
return NXT_ERROR;
@@ -1479,22 +1273,26 @@ njs_array_prototype_fill_continuation(nj
return NXT_OK;
}
- fill = njs_vm_continuation(vm);
+ array = NULL;
if (njs_is_array(this)) {
array = njs_array(this);
length = array->length;
} else {
-
- if (nxt_slow_path(!njs_is_primitive(&fill->length))) {
- ret = njs_value_to_numeric(vm, &fill->length, &fill->length);
+ ret = njs_value_property(vm, this, &string_length, &prop_length);
+ if (nxt_slow_path(ret == NXT_ERROR)) {
+ return ret;
+ }
+
+ if (nxt_slow_path(!njs_is_primitive(&prop_length))) {
+ ret = njs_value_to_numeric(vm, &prop_length, &prop_length);
if (ret != NXT_OK) {
return ret;
}
}
- length = njs_primitive_value_to_length(&fill->length);
+ length = njs_primitive_value_to_length(&prop_length);
}
start = njs_primitive_value_to_integer(njs_arg(args, nargs, 2));
@@ -1521,81 +1319,79 @@ njs_array_prototype_fill_continuation(nj
return NXT_OK;
}
- fill->u.cont.function = njs_array_prototype_fill_object_continuation;
- fill->start = start;
- fill->end = end;
-
- return njs_array_prototype_fill_object_continuation(vm, args, nargs,
- unused);
-}
-
-
-static njs_ret_t
-njs_array_prototype_fill_object_continuation(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused)
-{
- njs_ret_t ret;
- nxt_int_t end;
- njs_value_t name;
- njs_array_fill_t *fill;
- const njs_value_t *value;
-
- fill = njs_vm_continuation(vm);
- end = fill->end;
-
- vm->retval = *njs_arg(args, nargs, 0);
value = njs_arg(args, nargs, 1);
- while (fill->start < end) {
- njs_uint32_to_string(&name, fill->start++);
-
- ret = njs_value_property_set(vm, &vm->retval, &name,
- (njs_value_t *) value, 0);
- if (nxt_slow_path(ret == NXT_ERROR || ret == NJS_APPLIED)) {
+ while (start < end) {
+ njs_uint32_to_string(&name, start++);
+
+ ret = njs_value_property_set(vm, (njs_value_t *) this, &name,
+ (njs_value_t *) value);
+ if (nxt_slow_path(ret == NXT_ERROR)) {
return ret;
}
}
+ vm->retval = *this;
+
return NXT_OK;
}
+nxt_inline njs_ret_t
+njs_array_iterator_call(njs_vm_t *vm, njs_function_t *function,
+ const njs_value_t *this_arg, njs_value_t *value, uint32_t n,
+ njs_value_t *array)
+{
+ njs_value_t arguments[3];
+
+ /* GC: array elt, array */
+
+ arguments[0] = *value;
+ njs_set_number(&arguments[1], n);
+ arguments[2] = *array;
+
+ return njs_function_call(vm, function, (njs_value_t *) this_arg,
+ arguments, 3, &vm->retval);
+}
+
+
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)
{
- nxt_int_t ret;
- njs_array_iter_t *iter;
-
- ret = njs_array_iterator_args(vm, args, nargs);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
+ uint32_t i, length;
+ nxt_int_t ret;
+ njs_value_t *array, *value;
+ njs_function_t *function;
+ const njs_value_t *this_arg;
+
+ if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) {
+ njs_type_error(vm, "unexpected iterator arguments");
+ return NXT_ERROR;
}
- iter = njs_vm_continuation(vm);
- iter->u.cont.function = njs_array_prototype_for_each_continuation;
-
- return njs_array_prototype_for_each_continuation(vm, args, nargs, unused);
-}
-
-
-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)
-{
- uint32_t index;
- njs_array_iter_t *iter;
-
- iter = njs_vm_continuation(vm);
-
- index = njs_array_iterator_index(njs_array(&args[0]), iter);
-
- if (index == NJS_ARRAY_INVALID_INDEX) {
- vm->retval = njs_value_undefined;
- return NXT_OK;
+ array = &args[0];
+ length = njs_array_len(array);
+ function = njs_function(&args[1]);
+ this_arg = njs_arg(args, nargs, 2);
+
+ for (i = 0; i < length; i++) {
+ value = &njs_array_start(array)[i];
+
+ if (njs_is_valid(value)) {
+ ret = njs_array_iterator_call(vm, function, this_arg, value, i,
+ array);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+ }
+
+ length = nxt_min(length, njs_array_len(array));
}
- return njs_array_iterator_apply(vm, iter, args, nargs);
+ vm->retval = njs_value_undefined;
+
+ return NXT_OK;
}
@@ -1603,43 +1399,41 @@ static njs_ret_t
njs_array_prototype_some(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
njs_index_t unused)
{
- nxt_int_t ret;
- njs_array_iter_t *iter;
-
- ret = njs_array_iterator_args(vm, args, nargs);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
+ uint32_t i, length;
+ nxt_int_t ret;
+ njs_value_t *array, *value;
+ njs_function_t *function;
+ const njs_value_t *this_arg, *retval;
+
+ if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) {
+ njs_type_error(vm, "unexpected iterator arguments");
+ return NXT_ERROR;
}
- iter = njs_vm_continuation(vm);
- iter->u.cont.function = njs_array_prototype_some_continuation;
-
- return njs_array_prototype_some_continuation(vm, args, nargs, unused);
-}
-
-
-static njs_ret_t
-njs_array_prototype_some_continuation(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused)
-{
- uint32_t index;
- njs_array_iter_t *iter;
- const njs_value_t *retval;
-
- iter = njs_vm_continuation(vm);
-
- if (njs_is_true(&iter->retval)) {
- retval = &njs_value_true;
-
- } else {
- index = njs_array_iterator_index(njs_array(&args[0]), iter);
-
- if (index == NJS_ARRAY_INVALID_INDEX) {
- retval = &njs_value_false;
-
- } else {
- return njs_array_iterator_apply(vm, iter, args, nargs);
+ array = &args[0];
+ length = njs_array_len(array);
+ function = njs_function(&args[1]);
+ this_arg = njs_arg(args, nargs, 2);
+
+ retval = &njs_value_false;
+
+ for (i = 0; i < length; i++) {
+ value = &njs_array_start(array)[i];
+
+ if (njs_is_valid(value)) {
+ ret = njs_array_iterator_call(vm, function, this_arg, value, i,
+ array);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+
+ if (njs_is_true(&vm->retval)) {
+ retval = &njs_value_true;
+ break;
+ }
}
+
+ length = nxt_min(length, njs_array_len(array));
}
vm->retval = *retval;
@@ -1652,44 +1446,41 @@ static njs_ret_t
njs_array_prototype_every(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
njs_index_t unused)
{
- nxt_int_t ret;
- njs_array_iter_t *iter;
-
- ret = njs_array_iterator_args(vm, args, nargs);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
+ uint32_t i, length;
+ nxt_int_t ret;
+ njs_value_t *array, *value;
+ njs_function_t *function;
+ const njs_value_t *this_arg, *retval;
+
+ if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) {
+ njs_type_error(vm, "unexpected iterator arguments");
+ return NXT_ERROR;
}
- iter = njs_vm_continuation(vm);
- iter->u.cont.function = njs_array_prototype_every_continuation;
- iter->retval.data.truth = 1;
-
- return njs_array_prototype_every_continuation(vm, args, nargs, unused);
-}
-
-
-static njs_ret_t
-njs_array_prototype_every_continuation(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused)
-{
- uint32_t index;
- njs_array_iter_t *iter;
- const njs_value_t *retval;
-
- iter = njs_vm_continuation(vm);
-
- if (!njs_is_true(&iter->retval)) {
- retval = &njs_value_false;
-
- } else {
- index = njs_array_iterator_index(njs_array(&args[0]), iter);
-
- if (index == NJS_ARRAY_INVALID_INDEX) {
- retval = &njs_value_true;
-
- } else {
- return njs_array_iterator_apply(vm, iter, args, nargs);
+ array = &args[0];
+ length = njs_array_len(array);
+ function = njs_function(&args[1]);
+ this_arg = njs_arg(args, nargs, 2);
+
+ retval = &njs_value_true;
+
+ for (i = 0; i < length; i++) {
+ value = &njs_array_start(array)[i];
+
+ if (njs_is_valid(value)) {
+ ret = njs_array_iterator_call(vm, function, this_arg, value, i,
+ array);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+
+ if (!njs_is_true(&vm->retval)) {
+ retval = &njs_value_false;
+ break;
+ }
}
+
+ length = nxt_min(length, njs_array_len(array));
}
vm->retval = *retval;
@@ -1702,57 +1493,52 @@ static njs_ret_t
njs_array_prototype_filter(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
njs_index_t unused)
{
- nxt_int_t ret;
- njs_array_filter_t *filter;
-
- ret = njs_array_iterator_args(vm, args, nargs);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
+ uint32_t i, length;
+ nxt_int_t ret;
+ njs_array_t *retval;
+ njs_value_t *array, value;
+ njs_function_t *function;
+ const njs_value_t *this_arg;
+
+ if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) {
+ njs_type_error(vm, "unexpected iterator arguments");
+ return NXT_ERROR;
}
- filter = njs_vm_continuation(vm);
- filter->iter.u.cont.function = njs_array_prototype_filter_continuation;
-
- filter->array = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
- if (nxt_slow_path(filter->array == NULL)) {
+ array = &args[0];
+ length = njs_array_len(array);
+ function = njs_function(&args[1]);
+ this_arg = njs_arg(args, nargs, 2);
+
+ retval = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
+ if (nxt_slow_path(retval == NULL)) {
return NXT_ERROR;
}
- return njs_array_prototype_filter_continuation(vm, args, nargs, unused);
-}
-
-
-static njs_ret_t
-njs_array_prototype_filter_continuation(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused)
-{
- uint32_t index;
- nxt_int_t ret;
- njs_array_t *array;
- njs_array_filter_t *filter;
-
- filter = njs_vm_continuation(vm);
-
- if (njs_is_true(&filter->iter.retval)) {
- ret = njs_array_add(vm, filter->array, &filter->value);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
+ for (i = 0; i < length; i++) {
+ value = njs_array_start(array)[i];
+
+ if (njs_is_valid(&value)) {
+ ret = njs_array_iterator_call(vm, function, this_arg, &value, i,
+ array);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+
+ if (njs_is_true(&vm->retval)) {
+ ret = njs_array_add(vm, retval, &value);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+ }
}
+
+ length = nxt_min(length, njs_array_len(array));
}
- array = njs_array(&args[0]);
- index = njs_array_iterator_index(array, &filter->iter);
-
- if (index == NJS_ARRAY_INVALID_INDEX) {
- njs_set_array(&vm->retval, filter->array);
-
- return NXT_OK;
- }
-
- /* GC: filter->value */
- filter->value = array->start[index];
-
- return njs_array_iterator_apply(vm, &filter->iter, args, nargs);
+ njs_set_array(&vm->retval, retval);
+
+ return NXT_OK;
}
@@ -1760,50 +1546,42 @@ static njs_ret_t
njs_array_prototype_find(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
njs_index_t unused)
{
- nxt_int_t ret;
- njs_array_find_t *find;
-
- ret = njs_array_iterator_args(vm, args, nargs);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
+ uint32_t i, length;
+ nxt_int_t ret;
+ njs_value_t *array, value;
+ njs_function_t *function;
+ const njs_value_t *this_arg, *retval;
+
+ if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) {
+ njs_type_error(vm, "unexpected iterator arguments");
+ return NXT_ERROR;
}
- find = njs_vm_continuation(vm);
- find->iter.u.cont.function = njs_array_prototype_find_continuation;
-
- return njs_array_prototype_find_continuation(vm, args, nargs, unused);
-}
-
-
-static njs_ret_t
-njs_array_prototype_find_continuation(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused)
-{
- njs_array_t *array;
- njs_array_iter_t *iter;
- njs_array_find_t *find;
- const njs_value_t *retval;
+ array = &args[0];
+ length = njs_array_len(array);
+ function = njs_function(&args[1]);
+ this_arg = njs_arg(args, nargs, 2);
retval = &njs_value_undefined;
- find = njs_vm_continuation(vm);
- iter = &find->iter;
-
- if (!njs_is_true(&iter->retval)) {
- array = njs_array(&args[0]);
- iter->index++;
-
- if (iter->index < iter->length && iter->index < array->length) {
- /* GC: find->value */
- find->value = array->start[iter->index];
-
- return njs_array_prototype_find_apply(vm, iter, args, nargs);
+ for (i = 0; i < length; i++) {
+ value = njs_array_start(array)[i];
+
+ if (!njs_is_valid(&value)) {
+ value = njs_value_undefined;
}
- } else {
- if (njs_is_valid(&find->value)) {
- retval = &find->value;
+ ret = njs_array_iterator_call(vm, function, this_arg, &value, i, array);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
}
+
+ if (njs_is_true(&vm->retval)) {
+ retval = &value;
+ break;
+ }
+
+ length = nxt_min(length, njs_array_len(array));
}
vm->retval = *retval;
@@ -1816,41 +1594,43 @@ static njs_ret_t
njs_array_prototype_find_index(njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, njs_index_t unused)
{
- nxt_int_t ret;
- njs_array_iter_t *iter;
-
- ret = njs_array_iterator_args(vm, args, nargs);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
+ double index;
+ uint32_t i, length;
+ nxt_int_t ret;
+ njs_value_t *array, value;
+ njs_function_t *function;
+ const njs_value_t *this_arg;
+
+ if (nargs < 2 || !njs_is_array(&args[0]) || !njs_is_function(&args[1])) {
+ njs_type_error(vm, "unexpected iterator arguments");
+ return NXT_ERROR;
}
- iter = njs_vm_continuation(vm);
- iter->u.cont.function = njs_array_prototype_find_index_continuation;
-
- return njs_array_prototype_find_index_continuation(vm, args, nargs, unused);
-}
-
-
-static njs_ret_t
-njs_array_prototype_find_index_continuation(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused)
-{
- double index;
- njs_array_iter_t *iter;
-
- iter = njs_vm_continuation(vm);
- index = iter->index;
-
- if (!njs_is_true(&iter->retval)) {
- iter->index++;
-
- if (iter->index < iter->length
- && iter->index < njs_array_len(&args[0]))
- {
- return njs_array_prototype_find_apply(vm, iter, args, nargs);
+ array = &args[0];
+ length = njs_array_len(array);
+ function = njs_function(&args[1]);
+ this_arg = njs_arg(args, nargs, 2);
+
+ index = -1;
+
+ for (i = 0; i < length; i++) {
+ value = njs_array_start(array)[i];
+
+ if (!njs_is_valid(&value)) {
+ value = njs_value_undefined;
}
- index = -1;
+ ret = njs_array_iterator_call(vm, function, this_arg, &value, i, array);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+
+ if (njs_is_true(&vm->retval)) {
+ index = i;
+ break;
+ }
+
+ length = nxt_min(length, njs_array_len(array));
}
njs_set_number(&vm->retval, index);
@@ -1860,109 +1640,79 @@ njs_array_prototype_find_index_continuat
More information about the nginx-devel
mailing list