]> git.kaiwu.me - njs.git/commitdiff
Introduced Array.prototype.toSpliced().
authorDmitry Volyntsev <xeioex@nginx.com>
Sat, 27 May 2023 02:13:41 +0000 (19:13 -0700)
committerDmitry Volyntsev <xeioex@nginx.com>
Sat, 27 May 2023 02:13:41 +0000 (19:13 -0700)
src/njs_array.c
src/test/njs_unit_test.c

index 9fa2785efb063d8d6a0cd32f53bc97c4f07df9f4..f73e0d1bab2dc7c4621631c8b291a61efacbcc98 100644 (file)
@@ -1402,6 +1402,105 @@ njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
+static njs_int_t
+njs_array_prototype_to_spliced(njs_vm_t *vm, njs_value_t *args,
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
+{
+    int64_t      i, n, r, start, length, to_insert, to_skip, new_length;
+    njs_int_t    ret;
+    njs_value_t  *this, value;
+    njs_array_t  *array;
+
+    this = njs_argument(args, 0);
+
+    ret = njs_value_to_object(vm, this);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    ret = njs_object_length(vm, this, &length);
+    if (njs_slow_path(ret == NJS_ERROR)) {
+        return ret;
+    }
+
+    ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &start);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    start = (start < 0) ? njs_max(length + start, 0) : njs_min(start, length);
+
+    to_insert = 0;
+    to_skip = 0;
+
+    if (nargs == 2) {
+        to_skip = length - start;
+
+    } else if (nargs > 2) {
+        to_insert = nargs - 3;
+
+        ret = njs_value_to_integer(vm, njs_arg(args, nargs, 2), &to_skip);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+
+        to_skip = njs_min(njs_max(to_skip, 0), length - start);
+    }
+
+    new_length = length + to_insert - to_skip;
+
+    if (njs_slow_path(new_length > NJS_MAX_LENGTH)) {
+        njs_type_error(vm, "Invalid length");
+        return NJS_ERROR;
+    }
+
+    array = njs_array_alloc(vm, 0, new_length, 0);
+    if (njs_slow_path(array == NULL)) {
+        return NJS_ERROR;
+    }
+
+    njs_set_array(retval, array);
+
+    for (i = 0; i < start; i++) {
+        ret = njs_value_property_i64(vm, this, i, &value);
+        if (njs_slow_path(ret == NJS_ERROR)) {
+            return NJS_ERROR;
+        }
+
+        ret = njs_value_create_data_prop_i64(vm, retval, i, &value, 0);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    for (n = 3; to_insert-- > 0; i++, n++) {
+        ret = njs_value_create_data_prop_i64(vm, retval, i, &args[n], 0);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    r = start + to_skip;
+
+    while (i < new_length) {
+        ret = njs_value_property_i64(vm, this, r, &value);
+        if (njs_slow_path(ret == NJS_ERROR)) {
+            return NJS_ERROR;
+        }
+
+        ret = njs_value_create_data_prop_i64(vm, retval, i, &value, 0);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+
+        r++;
+        i++;
+    }
+
+    return NJS_OK;
+}
+
+
 static njs_int_t
 njs_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
@@ -3092,6 +3191,8 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
 
     NJS_DECLARE_PROP_NATIVE("toSorted", njs_array_prototype_to_sorted, 1, 0),
 
+    NJS_DECLARE_PROP_NATIVE("toSpliced", njs_array_prototype_to_spliced, 2, 0),
+
     NJS_DECLARE_PROP_NATIVE("toString", njs_array_prototype_to_string, 0, 0),
 
     NJS_DECLARE_PROP_NATIVE("unshift", njs_array_prototype_unshift, 1, 0),
index 2c8cfb11485437d256b141f6702934e3abcdb1ec..2b51cf85e72f7196ea8090f63f50f6479bce9812 100644 (file)
@@ -5159,6 +5159,9 @@ static njs_unit_test_t  njs_test[] =
               "a.splice(0)"),
       njs_str(",,") },
 
+    { njs_str("'/A/B/C/D/'.split('/').toSpliced(1,1).join('/')"),
+      njs_str("/B/C/D/") },
+
     { njs_str("var a = []; a.reverse()"),
       njs_str("") },