From 56333fadc1f65637117bf73f5bca0a18912ccdf3 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Mon, 10 Feb 2020 17:09:53 +0300 Subject: [PATCH] Improved Array object allocation after ccfa84cea2b3. 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. --- src/njs_array.c | 75 +++++++++++++++++++++++++++++++++++++--------- src/njs_array.h | 5 +++- src/njs_builtin.c | 2 +- src/njs_extern.c | 2 +- src/njs_function.c | 4 +-- src/njs_json.c | 20 +++++++++---- src/njs_object.c | 73 +++++++++++++++++++++++++------------------- src/njs_regexp.c | 2 +- src/njs_string.c | 4 +-- src/njs_value.c | 4 +-- src/njs_vm.c | 2 +- src/njs_vmcode.c | 2 +- 12 files changed, 133 insertions(+), 62 deletions(-) diff --git a/src/njs_array.c b/src/njs_array.c index d72b72fd..fb5da0f8 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -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; } diff --git a/src/njs_array.h b/src/njs_array.h index 56bb8113..663475d6 100644 --- a/src/njs_array.h +++ b/src/njs_array.h @@ -16,8 +16,11 @@ #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, diff --git a/src/njs_builtin.c b/src/njs_builtin.c index 35daa71e..69a39892 100644 --- a/src/njs_builtin.c +++ b/src/njs_builtin.c @@ -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; } diff --git a/src/njs_extern.c b/src/njs_extern.c index d8b79d2d..96e14fd4 100644 --- a/src/njs_extern.c +++ b/src/njs_extern.c @@ -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; } diff --git a/src/njs_function.c b/src/njs_function.c index 72c14297..beecd93c 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -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; } diff --git a/src/njs_json.c b/src/njs_json.c index 73d6c6df..46141b06 100644 --- a/src/njs_json.c +++ b/src/njs_json.c @@ -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)) { diff --git a/src/njs_object.c b/src/njs_object.c index 67d2ba65..365ce1b3 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -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; } diff --git a/src/njs_regexp.c b/src/njs_regexp.c index c16588a1..e22c3e83 100644 --- a/src/njs_regexp.c +++ b/src/njs_regexp.c @@ -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; } diff --git a/src/njs_string.c b/src/njs_string.c index d34700f2..a578dce1 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -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; } diff --git a/src/njs_value.c b/src/njs_value.c index ef069e45..d6037082 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -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; diff --git a/src/njs_vm.c b/src/njs_vm.c index 2d6fe22e..ffb933ff 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -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; diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 2a6f0105..a42cd758 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -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)) { -- 2.47.3