]> git.kaiwu.me - njs.git/commitdiff
Improved Array object allocation after ccfa84cea2b3.
authorDmitry Volyntsev <xeioex@nginx.com>
Mon, 10 Feb 2020 14:09:53 +0000 (17:09 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Mon, 10 Feb 2020 14:09:53 +0000 (17:09 +0300)
Sometimes flat array alignment is desired, even if its "length" exceeds
32768. This patch introduces additional argument for njs_array_alloc()
which enforced flat allocation when it is set.

12 files changed:
src/njs_array.c
src/njs_array.h
src/njs_builtin.c
src/njs_extern.c
src/njs_function.c
src/njs_json.c
src/njs_object.c
src/njs_regexp.c
src/njs_string.c
src/njs_value.c
src/njs_vm.c
src/njs_vmcode.c

index d72b72fd9ce2a658d471ff78785d745c35a11c1e..fb5da0f80ba641553de4a58740e1bb4c73aaf2fc 100644 (file)
@@ -32,7 +32,7 @@ static njs_int_t njs_array_prototype_slice_copy(njs_vm_t *vm,
 
 
 njs_array_t *
-njs_array_alloc(njs_vm_t *vm, uint64_t length, uint32_t spare)
+njs_array_alloc(njs_vm_t *vm, njs_bool_t flat, uint64_t length, uint32_t spare)
 {
     uint64_t     size;
     njs_int_t    ret;
@@ -50,7 +50,7 @@ njs_array_alloc(njs_vm_t *vm, uint64_t length, uint32_t spare)
 
     size = length + spare;
 
-    if (size <= NJS_ARRAY_LARGE_OBJECT_LENGTH) {
+    if (flat || size <= NJS_ARRAY_LARGE_OBJECT_LENGTH) {
         array->data = njs_mp_align(vm->mem_pool, sizeof(njs_value_t),
                                    size * sizeof(njs_value_t));
         if (njs_slow_path(array->data == NULL)) {
@@ -102,6 +102,19 @@ overflow:
 }
 
 
+void
+njs_array_destroy(njs_vm_t *vm, njs_array_t *array)
+{
+    if (array->data != NULL) {
+        njs_mp_free(vm->mem_pool, array->data);
+    }
+
+    /* TODO: destroy keys. */
+
+    njs_mp_free(vm->mem_pool, array);
+}
+
+
 njs_int_t
 njs_array_convert_to_slow_array(njs_vm_t *vm, njs_array_t *array)
 {
@@ -195,6 +208,8 @@ njs_array_length_set(njs_vm_t *vm, njs_value_t *value,
         return ret;
     }
 
+    keys = NULL;
+
     if (length < prev_length) {
         keys = njs_array_indices(vm, value);
         if (njs_slow_path(keys == NULL)) {
@@ -210,7 +225,7 @@ njs_array_length_set(njs_vm_t *vm, njs_value_t *value,
                     ret = njs_value_property_delete(vm, value, &keys->start[i],
                                                     NULL);
                     if (njs_slow_path(ret == NJS_ERROR)) {
-                        return ret;
+                        goto done;
                     }
                 }
             } while (i-- != 0);
@@ -222,7 +237,15 @@ njs_array_length_set(njs_vm_t *vm, njs_value_t *value,
         return ret;
     }
 
-    return NJS_OK;
+    ret = NJS_OK;
+
+done:
+
+    if (keys != NULL) {
+        njs_array_destroy(vm, keys);
+    }
+
+    return ret;
 }
 
 
@@ -341,7 +364,8 @@ njs_array_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         args = NULL;
     }
 
-    array = njs_array_alloc(vm, size, NJS_ARRAY_SPARE);
+    array = njs_array_alloc(vm, size <= NJS_ARRAY_FLAT_MAX_LENGTH,
+                            size, NJS_ARRAY_SPARE);
 
     if (njs_fast_path(array != NULL)) {
 
@@ -401,7 +425,7 @@ njs_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     length = nargs > 1 ? nargs - 1 : 0;
 
-    array = njs_array_alloc(vm, length, NJS_ARRAY_SPARE);
+    array = njs_array_alloc(vm, 0, length, NJS_ARRAY_SPARE);
     if (njs_slow_path(array == NULL)) {
         return NJS_ERROR;
     }
@@ -639,12 +663,14 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
     njs_slice_prop_t   string_slice;
     njs_string_prop_t  string;
 
-    array = njs_array_alloc(vm, length, NJS_ARRAY_SPARE);
+    keys = NULL;
+    array = njs_array_alloc(vm, 0, length, NJS_ARRAY_SPARE);
     if (njs_slow_path(array == NULL)) {
         return NJS_ERROR;
     }
 
     if (njs_slow_path(length == 0)) {
+        ret = NJS_OK;
         goto done;
     }
 
@@ -744,6 +770,7 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
             } while (length != 0);
         }
 
+        ret = NJS_OK;
         goto done;
     }
 
@@ -768,6 +795,7 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
             length--;
         } while (length != 0);
 
+        ret = NJS_OK;
         goto done;
     }
 
@@ -779,21 +807,27 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
     for (n = 0; n < keys->length; n++) {
         ret = njs_value_property(vm, this, &keys->start[n], &retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
+            goto done;
         }
 
         ret = njs_value_property_set(vm, &array_value, &keys->start[n],
                                      &retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
+            goto done;
         }
     }
 
+    ret = NJS_OK;
+
 done:
 
+    if (keys != NULL) {
+        njs_array_destroy(vm, keys);
+    }
+
     njs_set_array(&vm->retval, array);
 
-    return NJS_OK;
+    return ret;
 }
 
 
@@ -992,6 +1026,7 @@ njs_array_prototype_unshift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             ret = njs_value_property_delete(vm, this, &keys->start[--from],
                                             &entry);
             if (njs_slow_path(ret == NJS_ERROR)) {
+                njs_array_destroy(vm, keys);
                 return ret;
             }
 
@@ -1002,11 +1037,14 @@ njs_array_prototype_unshift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
                 ret = njs_value_property_set(vm, this, &index, &entry);
                 if (njs_slow_path(ret == NJS_ERROR)) {
+                    njs_array_destroy(vm, keys);
                     return ret;
                 }
             }
         }
 
+        njs_array_destroy(vm, keys);
+
         length += nargs - 1;
 
         goto copy;
@@ -1208,7 +1246,7 @@ njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    deleted = njs_array_alloc(vm, delete, 0);
+    deleted = njs_array_alloc(vm, 0, delete, 0);
     if (njs_slow_path(deleted == NULL)) {
         return NJS_ERROR;
     }
@@ -1711,10 +1749,13 @@ process_object:
             ret = njs_array_object_handler(vm, handler, args, &keys->start[i],
                                            idx);
             if (njs_slow_path(ret != NJS_OK)) {
+                njs_array_destroy(vm, keys);
                 return ret;
             }
         }
 
+        njs_array_destroy(vm, keys);
+
         return NJS_OK;
     }
 
@@ -1867,10 +1908,13 @@ process_object:
             ret = njs_array_object_handler(vm, handler, args, &keys->start[i],
                                            idx);
             if (njs_slow_path(ret != NJS_OK)) {
+                njs_array_destroy(vm, keys);
                 return ret;
             }
         }
 
+        njs_array_destroy(vm, keys);
+
         return NJS_OK;
     }
 
@@ -1934,7 +1978,7 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     /* TODO: ArraySpeciesCreate(). */
 
-    array = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
+    array = njs_array_alloc(vm, 0, 0, NJS_ARRAY_SPARE);
     if (njs_slow_path(array == NULL)) {
         return NJS_ERROR;
     }
@@ -2035,11 +2079,14 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
                     ret = njs_value_property_set(vm, &this, &index, &retval);
                     if (njs_slow_path(ret == NJS_ERROR)) {
+                        njs_array_destroy(vm, keys);
                         return ret;
                     }
                 }
             }
 
+            njs_array_destroy(vm, keys);
+
             length += len;
 
             continue;
@@ -2589,7 +2636,7 @@ njs_array_prototype_filter(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    iargs.array = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
+    iargs.array = njs_array_alloc(vm, 0, 0, NJS_ARRAY_SPARE);
     if (njs_slow_path(iargs.array == NULL)) {
         return NJS_ERROR;
     }
@@ -2779,7 +2826,7 @@ njs_array_prototype_map(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         goto unexpected_args;
     }
 
-    iargs.array = njs_array_alloc(vm, length, 0);
+    iargs.array = njs_array_alloc(vm, 0, length, 0);
     if (njs_slow_path(iargs.array == NULL)) {
         return NJS_ERROR;
     }
index 56bb8113b6245843a1375c36faf7372ab71d121c..663475d6d2b16a9c403a84e0f8bd92cc2aa7503e 100644 (file)
 #define NJS_ARRAY_MAX_LENGTH53         (0x1fffffffffffff)
 #define NJS_ARRAY_FAST_OBJECT_LENGTH   (128)
 #define NJS_ARRAY_LARGE_OBJECT_LENGTH  (32768)
+#define NJS_ARRAY_FLAT_MAX_LENGTH      (1048576)
 
-njs_array_t *njs_array_alloc(njs_vm_t *vm, uint64_t length, uint32_t spare);
+njs_array_t *njs_array_alloc(njs_vm_t *vm, njs_bool_t flat, uint64_t length,
+    uint32_t spare);
+void njs_array_destroy(njs_vm_t *vm, njs_array_t *array);
 njs_int_t njs_array_add(njs_vm_t *vm, njs_array_t *array, njs_value_t *value);
 njs_int_t njs_array_convert_to_slow_array(njs_vm_t *vm, njs_array_t *array);
 njs_int_t njs_array_length_redefine(njs_vm_t *vm, njs_value_t *value,
index 35daa71e8ff1346aaa7ff9fb256d0a3ae807ba8e..69a3989271fd5b092fd7c3b5f3de6c3a6adf0566 100644 (file)
@@ -1511,7 +1511,7 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr,
 
     static const njs_value_t  argv_string = njs_string("argv");
 
-    argv = njs_array_alloc(vm, vm->options.argc, 0);
+    argv = njs_array_alloc(vm, 1, vm->options.argc, 0);
     if (njs_slow_path(argv == NULL)) {
         return NJS_ERROR;
     }
index d8b79d2da9f15f0e417b8410626ef771e714e3c6..96e14fd4ab8d313f7d6adf66668489a1f7359c32 100644 (file)
@@ -234,7 +234,7 @@ njs_extern_keys_array(njs_vm_t *vm, const njs_extern_t *external)
         keys_length++;
     }
 
-    keys = njs_array_alloc(vm, keys_length, NJS_ARRAY_SPARE);
+    keys = njs_array_alloc(vm, 1, keys_length, NJS_ARRAY_SPARE);
     if (njs_slow_path(keys == NULL)) {
         return NULL;
     }
index 72c142977e31b1ea1c60a7e6664d4643ebd46347..beecd93ceae4fa7beee930cf4f5f8d98483ecc28 100644 (file)
@@ -301,7 +301,7 @@ njs_function_rest_parameters_init(njs_vm_t *vm, njs_native_frame_t *frame)
     n = frame->function->u.lambda->nargs;
     length = (nargs >= n) ? (nargs - n + 1) : 0;
 
-    array = njs_array_alloc(vm, length, 0);
+    array = njs_array_alloc(vm, 1, length, 0);
     if (njs_slow_path(array == NULL)) {
         return NJS_ERROR;
     }
@@ -1125,7 +1125,7 @@ njs_function_prototype_apply(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    arr = njs_array_alloc(vm, length, NJS_ARRAY_SPARE);
+    arr = njs_array_alloc(vm, 1, length, NJS_ARRAY_SPARE);
     if (njs_slow_path(arr == NULL)) {
         return NJS_ERROR;
     }
index 73d6c6dfac7745a516fe9e459a3d89739ae4463a..46141b061c3beda35171a0ab06c80e4bf57fe2af 100644 (file)
@@ -31,6 +31,7 @@ typedef struct {
     uint32_t                   index;
     uint32_t                   length;
     njs_array_t                *keys;
+    njs_value_t                *key;
     njs_object_prop_t          *prop;
 } njs_json_state_t;
 
@@ -448,7 +449,7 @@ njs_json_parse_array(njs_json_parse_ctx_t *ctx, njs_value_t *value,
         return NULL;
     }
 
-    array = njs_array_alloc(ctx->vm, 0, 0);
+    array = njs_array_alloc(ctx->vm, 0, 0, NJS_ARRAY_SPARE);
     if (njs_slow_path(array == NULL)) {
         return NULL;
     }
@@ -1027,6 +1028,8 @@ njs_json_push_stringify_state(njs_vm_t *vm, njs_json_stringify_t *stringify,
     state->value = *value;
     state->index = 0;
     state->written = 0;
+    state->keys = NULL;
+    state->key = NULL;
 
     if (njs_is_fast_array(value)) {
         state->type = NJS_JSON_ARRAY;
@@ -1069,6 +1072,12 @@ njs_json_pop_stringify_state(njs_json_stringify_t *stringify)
 {
     njs_json_state_t  *state;
 
+    state = &stringify->states[stringify->depth - 1];
+    if (!njs_is_array(&stringify->replacer) && state->keys != NULL) {
+        njs_array_destroy(stringify->vm, state->keys);
+        state->keys = NULL;
+    }
+
     if (stringify->depth > 1) {
         stringify->depth--;
         state = &stringify->states[stringify->depth - 1];
@@ -1411,7 +1420,7 @@ njs_json_stringify_replacer(njs_json_stringify_t* stringify,
 
 
 static njs_int_t
-njs_json_stringify_array(njs_vm_t *vm, njs_json_stringify_t  *stringify)
+njs_json_stringify_array(njs_vm_t *vm, njs_json_stringify_t *stringify)
 {
     njs_int_t    ret;
     uint32_t     i, n, k, properties_length, array_length;
@@ -1428,7 +1437,7 @@ njs_json_stringify_array(njs_vm_t *vm, njs_json_stringify_t  *stringify)
         }
     }
 
-    properties = njs_array_alloc(vm, properties_length, NJS_ARRAY_SPARE);
+    properties = njs_array_alloc(vm, 1, properties_length, NJS_ARRAY_SPARE);
     if (njs_slow_path(properties == NULL)) {
         return NJS_ERROR;
     }
@@ -2086,7 +2095,6 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
         goto memory_error;
     }
 
-    key = NULL;
     (void) njs_dump_visit(&visited, value);
 
     for ( ;; ) {
@@ -2106,12 +2114,11 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
 
                 njs_chb_append(&chain, state->array ? "[" : "{", 1);
                 njs_json_stringify_indent(stringify, &chain, 1);
-
             }
 
             if (state->index >= state->keys->length) {
                 njs_dump_empty(stringify, state, &chain, state->length,
-                     (state->index > 0) ? njs_key_to_index(key) : -1, 0);
+                     (state->index > 0) ? njs_key_to_index(state->key) : -1, 0);
 
                 njs_json_stringify_indent(stringify, &chain, 0);
                 njs_chb_append(&chain, state->array ? "]" : "}", 1);
@@ -2127,6 +2134,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
             njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
 
             key = &state->keys->start[state->index++];
+            state->key = key;
 
             ret = njs_property_query(vm, &pq, &state->value, key);
             if (njs_slow_path(ret != NJS_OK)) {
index 67d2ba657ed03b18b6a7171def7790bd5ba619cb..365ce1b323eeb432742570d205d9c742619952d9 100644 (file)
@@ -584,16 +584,11 @@ njs_object_enumerate(njs_vm_t *vm, const njs_object_t *object,
 
     length = njs_object_enumerate_length(object, type, all);
 
-    items = njs_array_alloc(vm, length, NJS_ARRAY_SPARE);
+    items = njs_array_alloc(vm, 1, length, NJS_ARRAY_SPARE);
     if (njs_slow_path(items == NULL)) {
         return NULL;
     }
 
-    if (njs_slow_path(!items->object.fast_array)) {
-        njs_internal_error(vm, "njs_object_enumerate() too many keys");
-        return NULL;
-    }
-
     ret = njs_object_enumerate_value(vm, object, items, kind, type, all);
     if (njs_slow_path(ret != NJS_OK)) {
         return NULL;
@@ -615,16 +610,11 @@ njs_object_own_enumerate(njs_vm_t *vm, const njs_object_t *object,
 
     length = njs_object_own_enumerate_length(object, object, type, all);
 
-    items = njs_array_alloc(vm, length, NJS_ARRAY_SPARE);
+    items = njs_array_alloc(vm, 1, length, NJS_ARRAY_SPARE);
     if (njs_slow_path(items == NULL)) {
         return NULL;
     }
 
-    if (njs_slow_path(!items->object.fast_array)) {
-        njs_internal_error(vm, "njs_object_own_enumerate() too many keys");
-        return NULL;
-    }
-
     ret = njs_object_own_enumerate_value(vm, object, object, items, kind, type,
                                          all);
     if (njs_slow_path(ret != NJS_OK)) {
@@ -804,7 +794,7 @@ njs_object_enumerate_array(njs_vm_t *vm, const njs_array_t *array,
         for (i = 0; i < array->length; i++) {
             if (njs_is_valid(&array->start[i])) {
 
-                entry = njs_array_alloc(vm, 2, 0);
+                entry = njs_array_alloc(vm, 0, 2, 0);
                 if (njs_slow_path(entry == NULL)) {
                     return NJS_ERROR;
                 }
@@ -857,7 +847,7 @@ njs_object_enumerate_typed_array(njs_vm_t *vm, const njs_typed_array_t *array,
 
     case NJS_ENUM_BOTH:
         for (i = 0; i < length; i++) {
-            entry = njs_array_alloc(vm, 2, 0);
+            entry = njs_array_alloc(vm, 0, 2, 0);
             if (njs_slow_path(entry == NULL)) {
                 return NJS_ERROR;
             }
@@ -938,7 +928,7 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value,
 
             for (i = 0; i < len; i++) {
 
-                entry = njs_array_alloc(vm, 2, 0);
+                entry = njs_array_alloc(vm, 0, 2, 0);
                 if (njs_slow_path(entry == NULL)) {
                     return NJS_ERROR;
                 }
@@ -965,7 +955,7 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value,
             i = 0;
 
             do {
-                entry = njs_array_alloc(vm, 2, 0);
+                entry = njs_array_alloc(vm, 0, 2, 0);
                 if (njs_slow_path(entry == NULL)) {
                     return NJS_ERROR;
                 }
@@ -1171,7 +1161,7 @@ njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
             if (ext_prop == NULL && prop->type != NJS_WHITEOUT
                 && (prop->enumerable || all))
             {
-                entry = njs_array_alloc(vm, 2, 0);
+                entry = njs_array_alloc(vm, 0, 2, 0);
                 if (njs_slow_path(entry == NULL)) {
                     return NJS_ERROR;
                 }
@@ -1209,7 +1199,7 @@ njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
                 ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
 
                 if (ext_prop == NULL) {
-                    entry = njs_array_alloc(vm, 2, 0);
+                    entry = njs_array_alloc(vm, 0, 2, 0);
                     if (njs_slow_path(entry == NULL)) {
                         return NJS_ERROR;
                     }
@@ -1442,7 +1432,7 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     for (i = 0; i < length; i++) {
         ret = njs_property_query(vm, &pq, descs, &keys->start[i]);
         if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
+            goto done;
         }
 
         prop = pq.lhq.value;
@@ -1453,19 +1443,24 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         ret = njs_value_property(vm, descs, &keys->start[i], &desc);
         if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
+            goto done;
         }
 
         ret = njs_object_prop_define(vm, value, &keys->start[i], &desc,
                                      NJS_OBJECT_PROP_DESCRIPTOR);
         if (njs_slow_path(ret != NJS_OK)) {
-            return NJS_ERROR;
+            goto done;
         }
     }
 
+    ret = NJS_OK;
     vm->retval = *value;
 
-    return NJS_OK;
+done:
+
+    njs_array_destroy(vm, keys);
+
+    return ret;
 }
 
 
@@ -1520,7 +1515,8 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
 
     descriptors = njs_object_alloc(vm);
     if (njs_slow_path(descriptors == NULL)) {
-        return NJS_ERROR;
+        ret = NJS_ERROR;
+        goto done;
     }
 
     lhq.replace = 0;
@@ -1531,12 +1527,14 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
         key = &names->start[i];
         ret = njs_object_prop_descriptor(vm, &descriptor, value, key);
         if (njs_slow_path(ret != NJS_OK)) {
-            return ret;
+            ret = NJS_ERROR;
+            goto done;
         }
 
         pr = njs_object_prop_alloc(vm, key, &descriptor, 1);
         if (njs_slow_path(pr == NULL)) {
-            return NJS_ERROR;
+            ret = NJS_ERROR;
+            goto done;
         }
 
         njs_object_property_key_set(&lhq, key, 0);
@@ -1545,13 +1543,18 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
         ret = njs_lvlhsh_insert(&descriptors->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
-            return NJS_ERROR;
+            goto done;
         }
     }
 
+    ret = NJS_OK;
     njs_set_object(&vm->retval, descriptors);
 
-    return NJS_OK;
+done:
+
+    njs_array_destroy(vm, names);
+
+    return ret;
 }
 
 
@@ -1912,6 +1915,8 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
+    names = NULL;
+
     for (i = 2; i < nargs; i++) {
         source = &args[i];
 
@@ -1930,7 +1935,7 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
             ret = njs_property_query(vm, &pq, source, key);
             if (njs_slow_path(ret != NJS_OK)) {
-                return NJS_ERROR;
+                goto exception;
             }
 
             prop = pq.lhq.value;
@@ -1940,19 +1945,27 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
             ret = njs_value_property(vm, source, key, &setval);
             if (njs_slow_path(ret != NJS_OK)) {
-                return NJS_ERROR;
+                goto exception;
             }
 
             ret = njs_value_property_set(vm, value, key, &setval);
             if (njs_slow_path(ret != NJS_OK)) {
-                return NJS_ERROR;
+                goto exception;
             }
         }
+
+        njs_array_destroy(vm, names);
     }
 
     vm->retval = *value;
 
     return NJS_OK;
+
+exception:
+
+    njs_array_destroy(vm, names);
+
+    return NJS_ERROR;
 }
 
 
index c16588a1d197b8cc91b6efc75a206cd0df91a68c..e22c3e832f87da5d97dc64a5882240ece6f03c27 100644 (file)
@@ -1072,7 +1072,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_regexp_t *regexp, njs_utf8_t utf8,
     static const njs_value_t  string_input = njs_string("input");
     static const njs_value_t  string_groups = njs_string("groups");
 
-    array = njs_array_alloc(vm, regexp->pattern->ncaptures, 0);
+    array = njs_array_alloc(vm, 0, regexp->pattern->ncaptures, 0);
     if (njs_slow_path(array == NULL)) {
         goto fail;
     }
index d34700f290dd8bd295489e97dce80d71c6a4906c..a578dce10eb58f223cedddfe1d3f69842ef94d19 100644 (file)
@@ -3237,7 +3237,7 @@ njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args,
 
     if (njs_regex_is_valid(&pattern->regex[type])) {
 
-        array = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
+        array = njs_array_alloc(vm, 0, 0, NJS_ARRAY_SPARE);
         if (njs_slow_path(array == NULL)) {
             return NJS_ERROR;
         }
@@ -3330,7 +3330,7 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    array = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
+    array = njs_array_alloc(vm, 0, 0, NJS_ARRAY_SPARE);
     if (njs_slow_path(array == NULL)) {
         return NJS_ERROR;
     }
index ef069e45e3adba60a1e288b7f0c834801e59405b..d6037082ccc86c0cdbaedc32ddc3df0df8f65e30 100644 (file)
@@ -228,7 +228,7 @@ njs_value_enumerate(njs_vm_t *vm, const njs_value_t *value,
             return njs_extern_keys_array(vm, ext_proto);
         }
 
-        return njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
+        return njs_array_alloc(vm, 1, 0, NJS_ARRAY_SPARE);
     }
 
     obj_val.object = vm->string_object;
@@ -273,7 +273,7 @@ njs_value_own_enumerate(njs_vm_t *vm, const njs_value_t *value,
             return njs_extern_keys_array(vm, ext_proto);
         }
 
-        return njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
+        return njs_array_alloc(vm, 1, 0, NJS_ARRAY_SPARE);
     }
 
     obj_val.object = vm->string_object;
index 2d6fe22e807819f11a5caacdd4c8154fdff84712..ffb933ff83c568ed9d867d1883408c80d847bbf6 100644 (file)
@@ -805,7 +805,7 @@ njs_vm_array_alloc(njs_vm_t *vm, njs_value_t *retval, uint32_t spare)
 {
     njs_array_t  *array;
 
-    array = njs_array_alloc(vm, 0, spare);
+    array = njs_array_alloc(vm, 0, 0, spare);
 
     if (njs_slow_path(array == NULL)) {
         return NJS_ERROR;
index 2a6f010574e51e0b82076367cee9a94cfc47f91e..a42cd7582f84960369d46e765a85c9a6152a73d0 100644 (file)
@@ -966,7 +966,7 @@ njs_vmcode_array(njs_vm_t *vm, u_char *pc)
 
     code = (njs_vmcode_array_t *) pc;
 
-    array = njs_array_alloc(vm, code->length, NJS_ARRAY_SPARE);
+    array = njs_array_alloc(vm, 0, code->length, NJS_ARRAY_SPARE);
 
     if (njs_fast_path(array != NULL)) {