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;
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)) {
}
+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)
{
return ret;
}
+ keys = NULL;
+
if (length < prev_length) {
keys = njs_array_indices(vm, value);
if (njs_slow_path(keys == NULL)) {
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);
return ret;
}
- return NJS_OK;
+ ret = NJS_OK;
+
+done:
+
+ if (keys != NULL) {
+ njs_array_destroy(vm, keys);
+ }
+
+ return ret;
}
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)) {
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;
}
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;
}
} while (length != 0);
}
+ ret = NJS_OK;
goto done;
}
length--;
} while (length != 0);
+ ret = NJS_OK;
goto done;
}
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;
}
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;
}
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;
}
}
- deleted = njs_array_alloc(vm, delete, 0);
+ deleted = njs_array_alloc(vm, 0, delete, 0);
if (njs_slow_path(deleted == NULL)) {
return NJS_ERROR;
}
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;
}
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;
}
/* 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;
}
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;
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;
}
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;
}
#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,
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;
}
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;
}
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;
}
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;
}
uint32_t index;
uint32_t length;
njs_array_t *keys;
+ njs_value_t *key;
njs_object_prop_t *prop;
} njs_json_state_t;
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;
}
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;
{
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];
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;
}
}
- 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;
}
goto memory_error;
}
- key = NULL;
(void) njs_dump_visit(&visited, value);
for ( ;; ) {
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);
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)) {
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;
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)) {
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
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;
}
descriptors = njs_object_alloc(vm);
if (njs_slow_path(descriptors == NULL)) {
- return NJS_ERROR;
+ ret = NJS_ERROR;
+ goto done;
}
lhq.replace = 0;
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);
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;
}
return ret;
}
+ names = NULL;
+
for (i = 2; i < nargs; i++) {
source = &args[i];
ret = njs_property_query(vm, &pq, source, key);
if (njs_slow_path(ret != NJS_OK)) {
- return NJS_ERROR;
+ goto exception;
}
prop = pq.lhq.value;
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;
}
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;
}
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;
}
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;
}
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;
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;
{
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;
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)) {