Welcome! Log In Create A New Profile

Advanced

[njs] Introduced ToLength() according to ES6.

Dmitry Volyntsev
February 17, 2020 09:02AM
details: https://hg.nginx.org/njs/rev/13dbdff9b76f
branches:
changeset: 1326:13dbdff9b76f
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Mon Feb 17 16:13:43 2020 +0300
description:
Introduced ToLength() according to ES6.

Since ES6, according to the spec maximum length value is 2**53 - 1 not
2**32 - 1, so uint64_t data type is required.

diffstat:

src/njs_array.c | 418 +++++++++++++++++++++++---------------------
src/njs_array.h | 4 +-
src/njs_chb.h | 8 +-
src/njs_function.c | 8 +-
src/njs_json.c | 10 +-
src/njs_number.c | 24 ++
src/njs_number.h | 14 +-
src/njs_object.c | 2 +-
src/njs_object.h | 4 +-
src/njs_regexp.c | 4 +-
src/njs_string.c | 5 +-
src/njs_typed_array.c | 24 +-
src/njs_value.c | 18 +-
src/njs_value.h | 63 ++++++-
src/njs_value_conversion.h | 2 +-
src/test/njs_unit_test.c | 126 ++++++++++++-
16 files changed, 475 insertions(+), 259 deletions(-)

diffs (truncated from 1794 to 1000 lines):

diff -r 974e6c195410 -r 13dbdff9b76f src/njs_array.c
--- a/src/njs_array.c Thu Feb 13 16:25:37 2020 +0300
+++ b/src/njs_array.c Mon Feb 17 16:13:43 2020 +0300
@@ -18,13 +18,13 @@ typedef struct {

njs_array_t *array;

- uint32_t from;
- uint32_t to;
+ int64_t from;
+ int64_t to;
} njs_array_iterator_args_t;


typedef njs_int_t (*njs_array_iterator_handler_t)(njs_vm_t *vm,
- njs_array_iterator_args_t *args, njs_value_t *entry, uint32_t n);
+ njs_array_iterator_args_t *args, njs_value_t *entry, uint64_t n);


static njs_int_t njs_array_prototype_slice_copy(njs_vm_t *vm,
@@ -128,9 +128,8 @@ njs_array_convert_to_slow_array(njs_vm_t
length = array->length;

for (i = 0; i < length; i++) {
- njs_uint32_to_string(&index, i);
-
if (njs_is_valid(&array->start[i])) {
+ njs_uint32_to_string(&index, i);
prop = njs_object_property_add(vm, &value, &index, 0);
if (njs_slow_path(prop == NULL)) {
return NJS_ERROR;
@@ -183,7 +182,8 @@ njs_array_length_set(njs_vm_t *vm, njs_v
njs_object_prop_t *prev, njs_value_t *setval)
{
double num, idx;
- uint32_t i, length, prev_length;
+ uint32_t i, length;
+ uint64_t prev_length;
njs_int_t ret;
njs_array_t *array, *keys;

@@ -197,7 +197,7 @@ njs_array_length_set(njs_vm_t *vm, njs_v
return ret;
}

- length = njs_number_to_length(num);
+ length = (uint32_t) njs_number_to_length(num);
if ((double) length != num) {
njs_range_error(vm, "Invalid array length");
return NJS_ERROR;
@@ -306,7 +306,7 @@ njs_array_expand(njs_vm_t *vm, njs_array
size += size / 2;
}

- if (njs_slow_path(size > NJS_ARRAY_MAX_LENGTH)) {
+ if (njs_slow_path(size > (UINT32_MAX / sizeof(njs_value_t)))) {
goto memory_error;
}

@@ -354,7 +354,7 @@ njs_array_constructor(njs_vm_t *vm, njs_

if (size == 1 && njs_is_number(&args[0])) {
num = njs_number(&args[0]);
- size = (uint32_t) num;
+ size = (uint32_t) njs_number_to_length(num);

if ((double) size != num) {
njs_range_error(vm, "Invalid array length");
@@ -529,7 +529,7 @@ njs_array_length(njs_vm_t *vm,njs_object
return ret;
}

- length = njs_number_to_length(num);
+ length = (uint32_t) njs_number_to_length(num);
if ((double) length != num) {
njs_range_error(vm, "Invalid array length");
return NJS_ERROR;
@@ -582,7 +582,7 @@ njs_array_prototype_slice(njs_vm_t *vm,
njs_index_t unused)
{
int64_t start, end, length;
- uint32_t object_length;
+ uint64_t object_length;
njs_int_t ret;
njs_value_t *this;

@@ -658,7 +658,7 @@ njs_array_prototype_slice_copy(njs_vm_t
uint32_t n;
njs_int_t ret;
njs_array_t *array, *keys;
- njs_value_t *value, index, retval, array_value;
+ njs_value_t *value, retval, self;
const u_char *src, *end;
njs_slice_prop_t string_slice;
njs_string_prop_t string;
@@ -688,10 +688,8 @@ njs_array_prototype_slice_copy(njs_vm_t

/* src value may be in Array.prototype object. */

- njs_uint32_to_string(&index, start++);
-
value = &array->start[n++];
- ret = njs_value_property(vm, this, &index, value);
+ ret = njs_value_property_i64(vm, this, start++, value);
if (njs_slow_path(ret == NJS_ERROR)) {
return NJS_ERROR;
}
@@ -746,10 +744,8 @@ njs_array_prototype_slice_copy(njs_vm_t
} else if (njs_is_object(this)) {

do {
- njs_uint32_to_string(&index, start++);
-
value = &array->start[n++];
- ret = njs_value_property(vm, this, &index, value);
+ ret = njs_value_property_i64(vm, this, start++, value);

if (ret != NJS_OK) {
njs_set_invalid(value);
@@ -774,19 +770,17 @@ njs_array_prototype_slice_copy(njs_vm_t
goto done;
}

- njs_set_array(&array_value, array);
+ njs_set_array(&self, array);

if (njs_fast_object(length)) {
do {
- njs_uint32_to_string(&index, start++);
-
- ret = njs_value_property(vm, this, &index, &retval);
+ ret = njs_value_property_i64(vm, this, start++, &retval);
if (njs_slow_path(ret == NJS_ERROR)) {
return NJS_ERROR;
}

if (ret == NJS_OK) {
- ret = njs_value_property_set(vm, &array_value, &index, &retval);
+ ret = njs_value_property_i64_set(vm, &self, start, &retval);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -810,8 +804,7 @@ njs_array_prototype_slice_copy(njs_vm_t
goto done;
}

- ret = njs_value_property_set(vm, &array_value, &keys->start[n],
- &retval);
+ ret = njs_value_property_set(vm, &self, &keys->start[n], &retval);
if (njs_slow_path(ret == NJS_ERROR)) {
goto done;
}
@@ -835,11 +828,11 @@ static njs_int_t
njs_array_prototype_push(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- uint32_t length;
+ uint64_t length;
njs_int_t ret;
njs_uint_t i;
njs_array_t *array;
- njs_value_t *this, index;
+ njs_value_t *this;

length = 0;
this = njs_argument(args, 0);
@@ -874,10 +867,13 @@ njs_array_prototype_push(njs_vm_t *vm, n
return ret;
}

+ if (njs_slow_path((length + nargs - 1) > NJS_MAX_LENGTH)) {
+ njs_type_error(vm, "Invalid length");
+ return NJS_ERROR;
+ }
+
for (i = 1; i < nargs; i++) {
- njs_uint32_to_string(&index, length++);
-
- ret = njs_value_property_set(vm, this, &index, &args[i]);
+ ret = njs_value_property_i64_set(vm, this, length++, &args[i]);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -898,10 +894,10 @@ static njs_int_t
njs_array_prototype_pop(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- uint32_t length;
+ uint64_t length;
njs_int_t ret;
njs_array_t *array;
- njs_value_t *this, *entry, index;
+ njs_value_t *this, *entry;

this = njs_argument(args, 0);

@@ -921,6 +917,15 @@ njs_array_prototype_pop(njs_vm_t *vm, nj

if (njs_is_valid(entry)) {
vm->retval = *entry;
+
+ } else {
+ /* src value may be in Array.prototype object. */
+
+ ret = njs_value_property_i64(vm, this, array->length,
+ &vm->retval);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return NJS_ERROR;
+ }
}
}

@@ -932,15 +937,23 @@ njs_array_prototype_pop(njs_vm_t *vm, nj
return ret;
}

- if (length != 0) {
- njs_uint32_to_string(&index, --length);
-
- ret = njs_value_property_delete(vm, this, &index, &vm->retval);
- if (njs_slow_path(ret == NJS_ERROR)) {
- return ret;
- }
+ if (length == 0) {
+ njs_set_undefined(&vm->retval);
+ goto done;
}

+ ret = njs_value_property_i64(vm, this, --length, &vm->retval);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+
+ ret = njs_value_property_i64_delete(vm, this, length, NULL);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+
+done:
+
ret = njs_object_length_set(vm, this, length);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
@@ -955,11 +968,11 @@ njs_array_prototype_unshift(njs_vm_t *vm
njs_index_t unused)
{
double idx;
- uint32_t from, to, length;
+ uint64_t from, to, length;
njs_int_t ret;
njs_uint_t n;
njs_array_t *array, *keys;
- njs_value_t *this, entry, index;
+ njs_value_t *this, entry;

this = njs_argument(args, 0);
length = 0;
@@ -970,14 +983,9 @@ njs_array_prototype_unshift(njs_vm_t *vm
return ret;
}

- if (njs_is_fast_array(this)) {
+ if (njs_fast_path(njs_is_fast_array(this))) {
array = njs_array(this);

- if (array->length > (UINT32_MAX - n)) {
- njs_type_error(vm, "Invalid length");
- return NJS_ERROR;
- }
-
if (n != 0) {
ret = njs_array_expand(vm, array, n, 0);
if (njs_slow_path(ret != NJS_OK)) {
@@ -1009,7 +1017,7 @@ njs_array_prototype_unshift(njs_vm_t *vm
goto done;
}

- if (length > (UINT32_MAX - n)) {
+ if (njs_slow_path((length + n) > NJS_MAX_LENGTH)) {
njs_type_error(vm, "Invalid length");
return NJS_ERROR;
}
@@ -1031,11 +1039,9 @@ njs_array_prototype_unshift(njs_vm_t *vm
}

if (ret == NJS_OK) {
- idx = njs_string_to_index(&keys->start[from]);
-
- njs_uint32_to_string(&index, (uint32_t) idx + nargs - 1);
-
- ret = njs_value_property_set(vm, this, &index, &entry);
+ idx = njs_string_to_index(&keys->start[from]) + n;
+
+ ret = njs_value_property_i64_set(vm, this, idx, &entry);
if (njs_slow_path(ret == NJS_ERROR)) {
njs_array_destroy(vm, keys);
return ret;
@@ -1045,7 +1051,7 @@ njs_array_prototype_unshift(njs_vm_t *vm

njs_array_destroy(vm, keys);

- length += nargs - 1;
+ length += n;

goto copy;
}
@@ -1055,9 +1061,7 @@ njs_array_prototype_unshift(njs_vm_t *vm
to = length;

while (from > 0) {
- njs_uint32_to_string(&index, --from);
-
- ret = njs_value_property_delete(vm, this, &index, &entry);
+ ret = njs_value_property_i64_delete(vm, this, --from, &entry);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -1065,9 +1069,7 @@ njs_array_prototype_unshift(njs_vm_t *vm
to--;

if (ret == NJS_OK) {
- njs_uint32_to_string(&index, to);
-
- ret = njs_value_property_set(vm, this, &index, &entry);
+ ret = njs_value_property_i64_set(vm, this, to, &entry);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -1077,9 +1079,7 @@ njs_array_prototype_unshift(njs_vm_t *vm
copy:

for (n = 1; n < nargs; n++) {
- njs_uint32_to_string(&index, n - 1);
-
- ret = njs_value_property_set(vm, this, &index, &args[n]);
+ ret = njs_value_property_i64_set(vm, this, n - 1, &args[n]);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -1102,10 +1102,10 @@ static njs_int_t
njs_array_prototype_shift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- uint32_t i, length;
+ uint64_t i, length;
njs_int_t ret;
njs_array_t *array;
- njs_value_t *this, *item, entry, index;
+ njs_value_t *this, *item, entry;

this = njs_argument(args, 0);
length = 0;
@@ -1122,13 +1122,21 @@ njs_array_prototype_shift(njs_vm_t *vm,

if (array->length != 0) {
array->length--;
-
item = &array->start[0];
- array->start++;

if (njs_is_valid(item)) {
vm->retval = *item;
+
+ } else {
+ /* src value may be in Array.prototype object. */
+
+ ret = njs_value_property_i64(vm, this, 0, &vm->retval);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return NJS_ERROR;
+ }
}
+
+ array->start++;
}

return NJS_OK;
@@ -1143,25 +1151,19 @@ njs_array_prototype_shift(njs_vm_t *vm,
goto done;
}

- njs_uint32_to_string(&index, 0);
-
- ret = njs_value_property_delete(vm, this, &index, &vm->retval);
+ ret = njs_value_property_i64_delete(vm, this, 0, &vm->retval);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}

for (i = 1; i < length; i++) {
- njs_uint32_to_string(&index, i);
-
- ret = njs_value_property_delete(vm, this, &index, &entry);
+ ret = njs_value_property_i64_delete(vm, this, i, &entry);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}

if (ret == NJS_OK) {
- njs_uint32_to_string(&index, i - 1);
-
- ret = njs_value_property_set(vm, this, &index, &entry);
+ ret = njs_value_property_i64_set(vm, this, i - 1, &entry);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -1304,7 +1306,7 @@ static njs_int_t
njs_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- uint32_t length;
+ uint64_t length;
njs_int_t ret;
njs_uint_t i, n;
njs_value_t value, *this;
@@ -1385,15 +1387,13 @@ njs_array_prototype_join(njs_vm_t *vm, n
njs_index_t unused)
{
u_char *p, *last;
- size_t size;
- ssize_t length;
- uint32_t len;
+ int64_t length;
+ uint64_t i, len, size;
njs_int_t ret;
njs_chb_t chain;
njs_utf8_t utf8;
- njs_uint_t i;
njs_array_t *array;
- njs_value_t *value, *this, index, entry;
+ njs_value_t *value, *this, entry;
njs_string_prop_t separator, string;

this = njs_argument(args, 0);
@@ -1447,13 +1447,13 @@ njs_array_prototype_join(njs_vm_t *vm, n
njs_chb_init(&chain, vm->mem_pool);

for (i = 0; i < len; i++) {
- if (njs_fast_path(array != NULL)) {
+ if (njs_fast_path(njs_object(this)->fast_array
+ && njs_is_valid(&array->start[i])))
+ {
value = &array->start[i];

} else {
- njs_uint32_to_string(&index, i);
-
- ret = njs_value_property(vm, this, &index, &entry);
+ ret = njs_value_property_i64(vm, this, i, &entry);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -1493,6 +1493,11 @@ njs_array_prototype_join(njs_vm_t *vm, n

length += separator.length;
njs_chb_append(&chain, separator.start, separator.size);
+
+ if (njs_slow_path(length > NJS_STRING_MAX_LENGTH)) {
+ njs_range_error(vm, "invalid string length");
+ return NJS_ERROR;
+ }
}

njs_chb_drop(&chain, separator.size);
@@ -1597,14 +1602,22 @@ njs_array_indices(njs_vm_t *vm, const nj

njs_inline njs_int_t
njs_array_object_handler(njs_vm_t *vm, njs_array_iterator_handler_t handler,
- njs_array_iterator_args_t *args, njs_value_t *key, uint32_t i)
+ njs_array_iterator_args_t *args, njs_value_t *key, uint64_t i)
{
njs_int_t ret;
njs_value_t prop, *entry;

- ret = njs_value_property(vm, args->value, key, &prop);
- if (njs_slow_path(ret == NJS_ERROR)) {
- return ret;
+ if (key != NULL) {
+ ret = njs_value_property(vm, args->value, key, &prop);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+
+ } else {
+ ret = njs_value_property_i64(vm, args->value, i, &prop);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
}

entry = (ret == NJS_OK) ? &prop : njs_value_arg(&njs_value_invalid);
@@ -1627,10 +1640,10 @@ njs_array_iterator(njs_vm_t *vm, njs_arr
njs_array_iterator_handler_t handler)
{
double idx;
- uint32_t length, i, from, to;
+ uint64_t length, i, from, to;
njs_int_t ret;
- njs_array_t *keys;
- njs_value_t *value, character, index, string_obj;
+ njs_array_t *array, *keys;
+ njs_value_t *value, *entry, prop, character, string_obj;
njs_object_t *object;
const u_char *p, *end, *pos;
njs_string_prop_t string_prop;
@@ -1640,16 +1653,30 @@ njs_array_iterator(njs_vm_t *vm, njs_arr
to = args->to;

if (njs_is_array(value)) {
- if (njs_slow_path(!njs_is_fast_array(value))) {
- goto process_object;
- }
-
- for (i = from; i < to; i++) {
- if (i < njs_array_len(value)) {
- ret = handler(vm, args, &njs_array_start(value)[i], i);
+ array = njs_array(value);
+
+ for (; from < to; from++) {
+ if (njs_slow_path(!array->object.fast_array)) {
+ goto process_object;
+ }
+
+ if (njs_fast_path(from < array->length
+ && njs_is_valid(&array->start[from])))
+ {
+ ret = handler(vm, args, &array->start[from], from);

} else {
- ret = handler(vm, args, njs_value_arg(&njs_value_invalid), i);
+ entry = njs_value_arg(&njs_value_invalid);
+ ret = njs_value_property_i64(vm, value, from, &prop);
+ if (njs_slow_path(ret != NJS_DECLINED)) {
+ if (ret == NJS_ERROR) {
+ return NJS_ERROR;
+ }
+
+ entry = &prop;
+ }
+
+ ret = handler(vm, args, entry, from);
}

if (njs_slow_path(ret != NJS_OK)) {
@@ -1680,7 +1707,7 @@ njs_array_iterator(njs_vm_t *vm, njs_arr
value = njs_object_value(value);
}

- length = (uint32_t) njs_string_prop(&string_prop, value);
+ length = njs_string_prop(&string_prop, value);

p = string_prop.start;
end = p + string_prop.size;
@@ -1760,9 +1787,7 @@ process_object:
}

for (i = from; i < to; i++) {
- njs_uint32_to_string(&index, i);
-
- ret = njs_array_object_handler(vm, handler, args, &index, i);
+ ret = njs_array_object_handler(vm, handler, args, NULL, i);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
@@ -1777,10 +1802,10 @@ njs_array_reverse_iterator(njs_vm_t *vm,
njs_array_iterator_handler_t handler)
{
double idx;
- uint32_t i, from, to, length;
+ uint64_t i, from, to, length;
njs_int_t ret;
- njs_array_t *keys;
- njs_value_t *entry, *value, character, index, string_obj;
+ njs_array_t *array, *keys;
+ njs_value_t *entry, *value, prop, character, string_obj;
njs_object_t *object;
const u_char *p, *end, *pos;
njs_string_prop_t string_prop;
@@ -1790,16 +1815,34 @@ njs_array_reverse_iterator(njs_vm_t *vm,
to = args->to;

if (njs_is_array(value)) {
- if (njs_slow_path(!njs_is_fast_array(value))) {
- goto process_object;
- }
-
- i = from + 1;
-
- while (i-- > to) {
- entry = &njs_array_start(value)[i];
-
- ret = handler(vm, args, entry, i);
+ array = njs_array(value);
+
+ from += 1;
+
+ while (from-- > to) {
+ if (njs_slow_path(!array->object.fast_array)) {
+ goto process_object;
+ }
+
+ if (njs_fast_path(from < array->length
+ && njs_is_valid(&array->start[from])))
+ {
+ ret = handler(vm, args, &array->start[from], from);
+
+ } else {
+ entry = njs_value_arg(&njs_value_invalid);
+ ret = njs_value_property_i64(vm, value, from, &prop);
+ if (njs_slow_path(ret != NJS_DECLINED)) {
+ if (ret == NJS_ERROR) {
+ return NJS_ERROR;
+ }
+
+ entry = &prop;
+ }
+
+ ret = handler(vm, args, entry, from);
+ }
+
if (njs_slow_path(ret != NJS_OK)) {
if (ret > 0) {
return NJS_DECLINED;
@@ -1828,7 +1871,7 @@ njs_array_reverse_iterator(njs_vm_t *vm,
value = njs_object_value(value);
}

- length = (uint32_t) njs_string_prop(&string_prop, value);
+ length = njs_string_prop(&string_prop, value);
end = string_prop.start + string_prop.size;

if (length == string_prop.size) {
@@ -1921,9 +1964,7 @@ process_object:
i = from + 1;

while (i-- > to) {
- njs_uint32_to_string(&index, i);
-
- ret = njs_array_object_handler(vm, handler, args, &index, i);
+ ret = njs_array_object_handler(vm, handler, args, NULL, i);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
@@ -1964,11 +2005,9 @@ njs_array_prototype_concat(njs_vm_t *vm,
njs_index_t unused)
{
double idx;
- uint32_t len;
- uint64_t length;
+ uint64_t i, k, len, length;
njs_int_t ret;
- njs_uint_t i, k;
- njs_value_t this, index, retval, *value, *e;
+ njs_value_t this, retval, *value, *e;
njs_array_t *array, *keys;

ret = njs_value_to_object(vm, &args[0]);
@@ -2002,7 +2041,7 @@ njs_array_prototype_concat(njs_vm_t *vm,
return ret;
}

- if (njs_slow_path((length + len) >= NJS_ARRAY_MAX_LENGTH53)) {
+ if (njs_slow_path((length + len) > NJS_MAX_LENGTH)) {
njs_type_error(vm, "Invalid length");
return NJS_ERROR;
}
@@ -2014,9 +2053,7 @@ njs_array_prototype_concat(njs_vm_t *vm,
value = &njs_array_start(e)[k];

if (njs_slow_path(!njs_is_valid(value))) {
- njs_uint32_to_string(&index, k);
- ret = njs_value_property(vm, e, &index,
- &retval);
+ ret = njs_value_property_i64(vm, e, k, &retval);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -2039,9 +2076,7 @@ njs_array_prototype_concat(njs_vm_t *vm,

if (njs_fast_object(len)) {
for (k = 0; k < len; k++, length++) {
- njs_uint32_to_string(&index, k);
-
- ret = njs_value_property(vm, e, &index, &retval);
+ ret = njs_value_property_i64(vm, e, k, &retval);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -2050,9 +2085,8 @@ njs_array_prototype_concat(njs_vm_t *vm,
continue;
}

- njs_uint32_to_string(&index, length);
-
- ret = njs_value_property_set(vm, &this, &index, &retval);
+ ret = njs_value_property_i64_set(vm, &this, length,
+ &retval);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -2072,12 +2106,10 @@ njs_array_prototype_concat(njs_vm_t *vm,
return ret;
}

- idx = njs_string_to_index(&keys->start[k]);
+ idx = njs_string_to_index(&keys->start[k]) + length;

if (ret == NJS_OK) {
- njs_uint32_to_string(&index, length + idx);
-
- ret = njs_value_property_set(vm, &this, &index, &retval);
+ ret = njs_value_property_i64_set(vm, &this, idx, &retval);
if (njs_slow_path(ret == NJS_ERROR)) {
njs_array_destroy(vm, keys);
return ret;
@@ -2092,7 +2124,7 @@ njs_array_prototype_concat(njs_vm_t *vm,
continue;
}

- if (njs_slow_path((length + len) >= NJS_ARRAY_MAX_LENGTH53)) {
+ if (njs_slow_path((length + len) >= NJS_MAX_LENGTH)) {
njs_type_error(vm, "Invalid length");
return NJS_ERROR;
}
@@ -2104,9 +2136,7 @@ njs_array_prototype_concat(njs_vm_t *vm,
}

} else {
- njs_uint32_to_string(&index, length);
-
- ret = njs_value_property_set(vm, &this, &index, e);
+ ret = njs_value_property_i64_set(vm, &this, length, e);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -2128,7 +2158,7 @@ njs_array_prototype_concat(njs_vm_t *vm,

static njs_int_t
njs_array_handler_index_of(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
if (njs_values_strict_equal(args->argument, entry)) {
njs_set_number(&vm->retval, n);
@@ -2145,7 +2175,7 @@ njs_array_prototype_index_of(njs_vm_t *v
njs_index_t unused)
{
int64_t from;
- uint32_t length;
+ uint64_t length;
njs_int_t ret;
njs_array_iterator_args_t iargs;

@@ -2180,12 +2210,12 @@ njs_array_prototype_index_of(njs_vm_t *v
}
}

- iargs.from = (uint32_t) from;
+ iargs.from = from;
iargs.to = length;

ret = njs_array_iterator(vm, &iargs, njs_array_handler_index_of);
- if (njs_fast_path(ret == NJS_DECLINED)) {
- return NJS_OK;
+ if (njs_fast_path(ret != NJS_OK)) {
+ return (ret == NJS_DECLINED) ? NJS_OK : NJS_ERROR;
}

not_found:
@@ -2201,7 +2231,7 @@ njs_array_prototype_last_index_of(njs_vm
njs_uint_t nargs, njs_index_t unused)
{
int64_t from;
- uint32_t length;
+ uint64_t length;
njs_int_t ret;
njs_array_iterator_args_t iargs;

@@ -2234,7 +2264,7 @@ njs_array_prototype_last_index_of(njs_vm
}

if (from >= 0) {
- from = njs_min(from, length - 1);
+ from = njs_min((uint64_t) from, length - 1);

} else if (from < 0) {
from += length;
@@ -2248,8 +2278,8 @@ njs_array_prototype_last_index_of(njs_vm
iargs.to = 0;

ret = njs_array_reverse_iterator(vm, &iargs, njs_array_handler_index_of);
- if (njs_fast_path(ret == NJS_DECLINED)) {
- return NJS_OK;
+ if (njs_fast_path(ret != NJS_OK)) {
+ return (ret == NJS_DECLINED) ? NJS_OK : NJS_ERROR;
}

not_found:
@@ -2262,7 +2292,7 @@ not_found:

static njs_int_t
njs_array_handler_includes(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
if (!njs_is_valid(entry)) {
entry = njs_value_arg(&njs_value_undefined);
@@ -2283,7 +2313,7 @@ njs_array_prototype_includes(njs_vm_t *v
njs_index_t unused)
{
int64_t from;
- uint32_t length;
+ uint64_t length;
njs_int_t ret;
njs_array_iterator_args_t iargs;

@@ -2318,12 +2348,12 @@ njs_array_prototype_includes(njs_vm_t *v
}
}

- iargs.from = (uint32_t) from;
+ iargs.from = from;
iargs.to = length;

ret = njs_array_iterator(vm, &iargs, njs_array_handler_includes);
- if (njs_fast_path(ret == NJS_DECLINED)) {
- return NJS_OK;
+ if (njs_fast_path(ret != NJS_OK)) {
+ return (ret == NJS_DECLINED) ? NJS_OK : NJS_ERROR;
}

not_found:
@@ -2338,11 +2368,10 @@ static njs_int_t
njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- int64_t start, end;
- uint32_t length;
- njs_int_t i, ret;
+ int64_t i, length, start, end;
+ njs_int_t ret;
njs_array_t *array;
- njs_value_t name, *this, *value;
+ njs_value_t *this, *value;

this = njs_argument(args, 0);

@@ -2358,7 +2387,7 @@ njs_array_prototype_fill(njs_vm_t *vm, n
length = array->length;

} else {
- ret = njs_object_length(vm, this, &length);
+ ret = njs_object_length(vm, this, (uint64_t *) &length);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -2398,9 +2427,7 @@ njs_array_prototype_fill(njs_vm_t *vm, n
value = njs_arg(args, nargs, 1);

while (start < end) {
- njs_uint32_to_string(&name, start++);
-
- ret = njs_value_property_set(vm, this, &name, value);
+ ret = njs_value_property_i64_set(vm, this, start++, value);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -2442,7 +2469,7 @@ njs_array_validate_args(njs_vm_t *vm, nj
return ret;
}

- ret = njs_value_length(vm, iargs->value, &iargs->to);
+ ret = njs_value_length(vm, iargs->value, (uint64_t *) &iargs->to);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
@@ -2467,7 +2494,7 @@ failed:

static njs_int_t
njs_array_handler_for_each(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
if (njs_is_valid(entry)) {
return njs_array_iterator_call(vm, args, entry, n);
@@ -2502,7 +2529,7 @@ njs_array_prototype_for_each(njs_vm_t *v

static njs_int_t
njs_array_handler_some(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
njs_int_t ret;

@@ -2550,7 +2577,7 @@ njs_array_prototype_some(njs_vm_t *vm, n

static njs_int_t
njs_array_handler_every(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
njs_int_t ret;

@@ -2598,7 +2625,7 @@ njs_array_prototype_every(njs_vm_t *vm,

static njs_int_t
njs_array_handler_filter(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
njs_int_t ret;
njs_value_t copy;
@@ -2654,7 +2681,7 @@ njs_array_prototype_filter(njs_vm_t *vm,

static njs_int_t
njs_array_handler_find(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
njs_int_t ret;
njs_value_t copy;
@@ -2708,7 +2735,7 @@ njs_array_prototype_find(njs_vm_t *vm, n

static njs_int_t
njs_array_handler_find_index(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
njs_int_t ret;
njs_value_t copy;
@@ -2762,11 +2789,11 @@ njs_array_prototype_find_index(njs_vm_t

static njs_int_t
njs_array_handler_map(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
njs_int_t ret;
njs_array_t *retval;
- njs_value_t this, key;
+ njs_value_t this;

retval = args->array;

@@ -2786,9 +2813,8 @@ njs_array_handler_map(njs_vm_t *vm, njs_

} else {
njs_set_array(&this, retval);
- njs_uint32_to_string(&key, n);
-
- ret = njs_value_property_set(vm, &this, &key, &vm->retval);
+
+ ret = njs_value_property_i64_set(vm, &this, n, &vm->retval);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
@@ -2804,7 +2830,7 @@ static njs_int_t
njs_array_prototype_map(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- uint32_t length, i;
+ uint64_t length, i;
njs_int_t ret;
njs_array_t *array;
njs_value_t *this;
@@ -2870,7 +2896,7 @@ unexpected_args:

njs_inline njs_int_t
njs_array_iterator_reduce(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
njs_value_t arguments[5];

@@ -2888,7 +2914,7 @@ njs_array_iterator_reduce(njs_vm_t *vm,

static njs_int_t
njs_array_handler_reduce(njs_vm_t *vm, njs_array_iterator_args_t *args,
- njs_value_t *entry, uint32_t n)
+ njs_value_t *entry, uint64_t n)
{
njs_int_t ret;

@@ -2960,7 +2986,7 @@ njs_array_prototype_reduce_right(njs_vm_
return ret;
}

- ret = njs_value_length(vm, iargs.value, &iargs.from);
+ ret = njs_value_length(vm, iargs.value, (uint64_t *) &iargs.from);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
@@ -3019,8 +3045,8 @@ unexpected_args:


static njs_int_t
-njs_array_string_sort(njs_vm_t *vm, njs_value_t *args,
- njs_uint_t nargs, njs_index_t unused)
+njs_array_string_sort(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+ njs_index_t unused)
{
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Introduced ToLength() according to ES6.

Dmitry Volyntsev 252 February 17, 2020 09:02AM



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

Online Users

Guests: 316
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