Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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 = &param->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;
}
Пример #6
0
static void *
lvlhsh_unit_test_pool_alloc(void *pool, size_t size, nxt_uint_t nalloc)
{
    return nxt_mem_cache_align(pool, size, size);
}