*/
njs_value_t retval;
+ njs_value_t value;
+ njs_array_t *array;
uint32_t next_index;
uint32_t length;
} njs_array_iter_t;
njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
static nxt_noinline njs_ret_t njs_array_prototype_every_cont(njs_vm_t *vm,
njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
+static njs_ret_t njs_array_prototype_filter_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,
}
+static njs_ret_t
+njs_array_add(njs_vm_t *vm, njs_array_t *array, njs_value_t *value)
+{
+ njs_ret_t ret;
+
+ if (array->size == array->length) {
+ ret = njs_array_realloc(vm, array, 0, array->size + 1);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+ }
+
+ /* GC: retain value. */
+ array->start[array->length++] = *value;
+
+ return NXT_OK;
+}
+
+
njs_ret_t
njs_array_string_add(njs_vm_t *vm, njs_array_t *array, u_char *start,
size_t size, size_t length)
}
+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_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_filter_cont;
+ iter->retval.data.truth = 0;
+
+ iter->array = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
+ if (nxt_slow_path(iter->array == NULL)) {
+ return NXT_ERROR;
+ }
+
+ return njs_array_prototype_filter_cont(vm, args, nargs, unused);
+}
+
+
+static njs_ret_t
+njs_array_prototype_filter_cont(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;
+
+ iter = njs_continuation(vm->frame);
+
+ if (njs_is_true(&iter->retval)) {
+ ret = njs_array_add(vm, iter->array, &iter->value);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+ }
+
+ if (iter->next_index >= args[0].data.u.array->length) {
+ vm->retval.data.u.array = iter->array;
+ vm->retval.type = NJS_ARRAY;
+ vm->retval.data.truth = 1;
+
+ return NXT_OK;
+ }
+
+ return njs_array_iterator_apply(vm, iter, args, nargs);
+}
+
+
static nxt_noinline njs_ret_t
njs_array_iterator_args(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs)
{
*/
array = args[0].data.u.array;
n = iter->next_index;
+ iter->value = array->start[n];
arguments[1] = array->start[n];
njs_number_set(&arguments[2], n);
.value = njs_native_function(njs_array_prototype_every,
njs_continuation_size(njs_array_iter_t), 0),
},
+
+ {
+ .type = NJS_METHOD,
+ .name = njs_string("filter"),
+ .value = njs_native_function(njs_array_prototype_filter,
+ njs_continuation_size(njs_array_iter_t), 0),
+ },
};
"a.every(function(v, i, a) { return v > 0 })"),
nxt_string("true") },
+ { nxt_string("var a = [];"
+ "a.filter(function(v, i, a) { return v > 1 })"),
+ nxt_string("") },
+
+ { nxt_string("var a = [1,2,3,-1,5];"
+ "a.filter(function(v, i, a) { return v > 1 })"),
+ nxt_string("2,3,5") },
+
+ { nxt_string("var a = [1,2,3,4,5,6,7,8];"
+ "a.filter(function(v, i, a) { a.pop(); return v > 1 })"),
+ nxt_string("2,3,4") },
+
+ { nxt_string("var a = [1,2,3,4,5,6,7,8];"
+ "a.filter(function(v, i, a) { a.shift(); return v > 1 })"),
+ nxt_string("3,5,7") },
+
+ { nxt_string("var a = [1,2,3,4,5,6,7];"
+ "a.filter(function(v, i, a) { a.pop(); return v > 1 })"),
+ nxt_string("2,3,4") },
+
+ { nxt_string("var a = [1,2,3,4,5,6,7];"
+ "a.filter(function(v, i, a) { a.shift(); return v > 1 })"),
+ nxt_string("3,5,7") },
+
+ { nxt_string("var a = [1,2,3,4,5,6,7];"
+ "a.filter(function(v, i, a) { a[i] = v + 1; return true })"),
+ nxt_string("1,2,3,4,5,6,7") },
+
+ { nxt_string("var a = [1,2,3,4,5,6,7];"
+ "a.filter(function(v, i, a) { a[i+1] = v+10; return true })"),
+ nxt_string("1,11,21,31,41,51,61") },
+
/* Strings. */
{ nxt_string("var a = '0123456789' + '012345'"