Welcome! Log In Create A New Profile

Advanced

[njs] Introduced njs_array_copy_within().

Dmitry Volyntsev
June 03, 2020 02:42PM
details: https://hg.nginx.org/njs/rev/a23651137ccf
branches:
changeset: 1421:a23651137ccf
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Wed Jun 03 18:40:09 2020 +0000
description:
Introduced njs_array_copy_within().

diffstat:

src/njs_array.c | 105 +++++++++++++++++++++++++---------------------
src/test/njs_unit_test.c | 7 +++
2 files changed, 64 insertions(+), 48 deletions(-)

diffs (157 lines):

diff -r 61dce54ce3d5 -r a23651137ccf src/njs_array.c
--- a/src/njs_array.c Wed Jun 03 20:49:52 2020 +0300
+++ b/src/njs_array.c Wed Jun 03 18:40:09 2020 +0000
@@ -250,6 +250,60 @@ done:
}


+static njs_int_t
+njs_array_copy_within(njs_vm_t *vm, njs_value_t *array, int64_t to_pos,
+ int64_t from_pos, int64_t count, njs_bool_t forward)
+{
+ int64_t i, from, to;
+ njs_int_t ret;
+ njs_array_t *arr;
+ njs_value_t value;
+
+ if (njs_fast_path(njs_is_fast_array(array) && count > 0)) {
+ arr = njs_array(array);
+
+ memmove(&arr->start[to_pos], &arr->start[from_pos],
+ count * sizeof(njs_value_t));
+
+ return NJS_OK;
+ }
+
+ if (!forward) {
+ from_pos += count - 1;
+ to_pos += count - 1;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (forward) {
+ from = from_pos + i;
+ to = to_pos + i;
+
+ } else {
+ from = from_pos - i;
+ to = to_pos - i;
+ }
+
+ ret = njs_value_property_i64(vm, array, from, &value);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return NJS_ERROR;
+ }
+
+ if (ret == NJS_OK) {
+ ret = njs_value_property_i64_set(vm, array, to, &value);
+
+ } else {
+ ret = njs_value_property_i64_delete(vm, array, to, NULL);
+ }
+
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return NJS_ERROR;
+ }
+ }
+
+ return NJS_OK;
+}
+
+
njs_int_t
njs_array_add(njs_vm_t *vm, njs_array_t *array, njs_value_t *value)
{
@@ -3423,11 +3477,9 @@ static njs_int_t
njs_array_prototype_copy_within(njs_vm_t *vm, njs_value_t *args,
njs_uint_t nargs, njs_index_t unused)
{
- int8_t direction;
int64_t length, count, to, from, end;
njs_int_t ret;
- njs_array_t *array;
- njs_value_t *this, *value, prop;
+ njs_value_t *this, *value;

this = njs_argument(args, 0);

@@ -3471,53 +3523,10 @@ njs_array_prototype_copy_within(njs_vm_t

count = njs_min(end - from, length - to);

- if (from < to && from + count) {
- direction = -1;
- from = from + count - 1;
- to = to + count - 1;
-
- } else {
- direction = 1;
- }
-
njs_vm_retval_set(vm, this);

- if (njs_fast_path(njs_is_fast_array(this))) {
- array = njs_array(this);
-
- while (count-- > 0) {
- array->start[to] = array->start[from];
-
- from = from + direction;
- to = to + direction;
- }
-
- return NJS_OK;
- }
-
- while (count-- > 0) {
- ret = njs_value_property_i64(vm, this, from, &prop);
-
- if (ret == NJS_OK) {
- ret = njs_value_property_i64_set(vm, this, to, &prop);
-
- } else {
- if (njs_slow_path(ret == NJS_ERROR)) {
- return ret;
- }
-
- ret = njs_value_property_i64_delete(vm, this, to, NULL);
- }
-
- if (njs_slow_path(ret == NJS_ERROR)) {
- return ret;
- }
-
- from = from + direction;
- to = to + direction;
- }
-
- return NJS_OK;
+ return njs_array_copy_within(vm, this, to, from, count,
+ !(from < to && to < from + count));
}


diff -r 61dce54ce3d5 -r a23651137ccf src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Wed Jun 03 20:49:52 2020 +0300
+++ b/src/test/njs_unit_test.c Wed Jun 03 18:40:09 2020 +0000
@@ -4165,6 +4165,9 @@ static njs_unit_test_t njs_test[] =
{ njs_str("[0, 1, , , 1].copyWithin(0, 1, 4)"),
njs_str("1,,,,1") },

+ { njs_str("[0, 1, 2, 3].copyWithin(0, 1, -10)"),
+ njs_str("0,1,2,3") },
+
{ njs_str("var o = [0, 1, , , 1].copyWithin(0, 1, 4); typeof o"),
njs_str("object") },

@@ -4184,6 +4187,10 @@ static njs_unit_test_t njs_test[] =
"Object.keys(obj) + '|' + Object.values(obj)"),
njs_str("length,1,2,3,4,5,0|5,a,b,c,d,e,c") },

+ { njs_str("var o = {length:1}; Object.defineProperty(o, '0', {get:()=>{throw Error('Oops')}});"
+ "Array.prototype.copyWithin.call(o, 0, 0)"),
+ njs_str("Error: Oops") },
+
{ njs_str("Array.prototype.slice(1)"),
njs_str("") },

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

[njs] Introduced njs_array_copy_within().

Dmitry Volyntsev 256 June 03, 2020 02:42PM



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

Online Users

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