nxt_noinline njs_array_t * njs_array_alloc(njs_vm_t *vm, uint32_t length, uint32_t spare) { uint32_t size; njs_array_t *array; array = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), sizeof(njs_array_t)); if (nxt_slow_path(array == NULL)) { return NULL; } size = length + spare; array->data = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), size * sizeof(njs_value_t)); if (nxt_slow_path(array->data == NULL)) { return NULL; } array->start = array->data; nxt_lvlhsh_init(&array->object.hash); nxt_lvlhsh_init(&array->object.shared_hash); array->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_ARRAY]; array->size = size; array->length = length; return array; }
njs_ret_t njs_array_realloc(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, uint32_t size) { nxt_uint_t n; njs_value_t *value; if (size != array->size) { if (size < 16) { size *= 2; } else { size += size / 2; } } value = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), (prepend + size) * sizeof(njs_value_t)); if (nxt_slow_path(value == NULL)) { return NXT_ERROR; } /* GC: old = array->data */ array->data = value; while (prepend != 0) { njs_set_invalid(value); value++; prepend--; } memcpy(value, array->start, array->size * sizeof(njs_value_t)); array->start = value; n = array->size; array->size = size; value += n; size -= n; while (size != 0) { njs_set_invalid(value); value++; size--; } /* GC: free old pointer. */ return NXT_OK; }
njs_value_t * njs_array_add(njs_vm_t *vm, njs_value_t *value, u_char *start, size_t size) { njs_ret_t ret; njs_array_t *array; if (value != NULL) { array = value->data.u.array; if (array->size == array->length) { ret = njs_array_realloc(vm, array, 0, array->size + 1); if (nxt_slow_path(ret != NXT_OK)) { return NULL; } } } else { value = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), sizeof(njs_value_t)); if (nxt_slow_path(value == NULL)) { return NULL; } array = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE); if (nxt_slow_path(array == NULL)) { return NULL; } value->data.u.array = array; value->type = NJS_ARRAY; value->data.truth = 1; } ret = njs_string_create(vm, &array->start[array->length++], start, size, 0); if (nxt_fast_path(ret == NXT_OK)) { return value; } return NULL; }
njs_object_prop_t * njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name) { njs_object_prop_t *prop; prop = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), sizeof(njs_object_prop_t)); if (nxt_fast_path(prop != NULL)) { prop->value = njs_value_void; /* GC: retain. */ prop->name = *name; prop->type = NJS_PROPERTY; prop->enumerable = 1; prop->writable = 1; prop->configurable = 1; } return prop; }
static njs_ret_t njs_array_prototype_join(njs_vm_t *vm, njs_param_t *param) { u_char *p; size_t size, length; nxt_int_t ret; nxt_uint_t i, n, max; njs_array_t *array; njs_value_t *value, *values; njs_string_prop_t separator, string; if (!njs_is_array(param->object)) { goto empty; } array = param->object->data.u.array; if (array->length == 0) { goto empty; } if (param->nargs != 0) { value = ¶m->args[0]; } else { value = (njs_value_t *) &njs_string_comma; } (void) njs_string_prop(&separator, value); max = 0; for (i = 0; i < array->length; i++) { value = &array->start[i]; if (njs_is_valid(value) && !njs_is_string(value)) { max++; } } values = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), sizeof(njs_value_t) * max); if (nxt_slow_path(values == NULL)) { return NXT_ERROR; } size = separator.size * (array->length - 1); length = separator.length * (array->length - 1); n = 0; for (i = 0; i < array->length; i++) { value = &array->start[i]; if (njs_is_valid(value)) { if (!njs_is_string(value)) { ret = njs_value_to_string(vm, &values[n], value); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } value = &values[n++]; } (void) njs_string_prop(&string, value); size += string.size; length += string.length; } } p = njs_string_alloc(vm, &vm->retval, size, length); if (nxt_slow_path(p == NULL)) { return NXT_ERROR; } n = 0; for (i = 0; i < array->length; i++) { value = &array->start[i]; if (njs_is_valid(value)) { if (!njs_is_string(value)) { value = &values[n++]; } (void) njs_string_prop(&string, value); p = memcpy(p, string.start, string.size); p += string.size; } if (i < array->length - 1) { p = memcpy(p, separator.start, separator.size); p += separator.size; } } for (i = 0; i < max; i++) { njs_release(vm, &values[i]); } nxt_mem_cache_free(vm->mem_cache_pool, values); return NXT_OK; empty: vm->retval = njs_string_empty; return NXT_OK; }
static void * lvlhsh_unit_test_pool_alloc(void *pool, size_t size, nxt_uint_t nalloc) { return nxt_mem_cache_align(pool, size, size); }