Exemple #1
0
njs_ret_t
njs_array_function(njs_vm_t *vm, njs_param_t *param)
{
    double       num;
    uint32_t     size;
    njs_value_t  *value, *args;
    njs_array_t  *array;

    args = param->args;
    size = param->nargs;

    if (size == 1 && njs_is_number(&args[0])) {
        num = args[0].data.u.number;
        size = (uint32_t) num;

        if ((double) size != num) {
            vm->exception = &njs_exception_range_error;
            return NXT_ERROR;
        }

        args = NULL;
    }

    array = njs_array_alloc(vm, size, NJS_ARRAY_SPARE);

    if (nxt_fast_path(array != NULL)) {

        vm->retval.data.u.array = array;
        value = array->start;

        if (args == NULL) {
            while (size != 0) {
                njs_set_invalid(value);
                value++;
                size--;
            }

        } else {
            while (size != 0) {
                njs_retain(args);
                *value++ = *args++;
                size--;
            }
        }

        vm->retval.type = NJS_ARRAY;
        vm->retval.data.truth = 1;

        return NXT_OK;
    }

    return NXT_ERROR;
}
Exemple #2
0
static njs_ret_t
njs_array_prototype_concat(njs_vm_t *vm, njs_param_t *param)
{
    size_t       length;
    uintptr_t    nargs;
    nxt_uint_t    i;
    njs_value_t  *object, *args, *value;
    njs_array_t  *array;

    object = param->object;

    if (njs_is_array(object)) {
        length = object->data.u.array->length;

    } else {
        length = 1;
    }

    nargs = param->nargs;
    args = param->args;

    for (i = 0; i < nargs; i++) {
        if (njs_is_array(&args[i])) {
            length += args[i].data.u.array->length;

        } else {
            length++;
        }
    }

    array = njs_array_alloc(vm, length, NJS_ARRAY_SPARE);
    if (nxt_slow_path(array == NULL)) {
        return NXT_ERROR;
    }

    vm->retval.data.u.array = array;
    vm->retval.type = NJS_ARRAY;
    vm->retval.data.truth = 1;

    value = njs_array_copy(array->start, object);

    for (i = 0; i < nargs; i++) {
        value = njs_array_copy(value, &args[i]);
    }

    return NXT_OK;
}
Exemple #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;
}
Exemple #4
0
static njs_ret_t
njs_array_prototype_slice(njs_vm_t *vm, njs_param_t *param)
{
    int32_t      start, end, length;
    uint32_t     n;
    uintptr_t    nargs;
    njs_array_t  *array;
    njs_value_t  *object, *args, *value;

    start = 0;
    length = 0;
    object = param->object;

    if (njs_is_array(object)) {
        length = object->data.u.array->length;
        nargs = param->nargs;

        if (nargs != 0) {
            args = param->args;
            start = njs_value_to_number(&args[0]);

            if (start < 0) {
                start += length;

                if (start < 0) {
                    start = 0;
                }
            }

            end = length;

            if (nargs > 1) {
                end = njs_value_to_number(&args[1]);

                if (end < 0) {
                    end += length;
                }
            }

            length = end - start;

            if (length < 0) {
                start = 0;
                length = 0;
            }
        }
    }

    array = njs_array_alloc(vm, length, NJS_ARRAY_SPARE);
    if (nxt_slow_path(array == NULL)) {
        return NXT_ERROR;
    }

    vm->retval.data.u.array = array;
    vm->retval.type = NJS_ARRAY;
    vm->retval.data.truth = 1;

    if (length != 0) {
        value = object->data.u.array->start;
        n = 0;

        do {
            /* GC: retain long string and object in values[start]. */
            array->start[n++] = value[start++];
            length--;
        } while (length != 0);
    }

    return NXT_OK;
}
static njs_ret_t
njs_regexp_exec_result(njs_vm_t *vm, njs_regexp_t *regexp, u_char *string,
    nxt_regex_match_data_t *match_data, nxt_uint_t utf8)
{
    int                 *captures;
    u_char              *start;
    int32_t             size, length;
    njs_ret_t           ret;
    nxt_uint_t          i, n;
    njs_array_t         *array;
    njs_object_prop_t   *prop;
    nxt_lvlhsh_query_t  lhq;

    static const njs_value_t  njs_string_index = njs_string("index");
    static const njs_value_t  njs_string_input = njs_string("input");

    array = njs_array_alloc(vm, regexp->pattern->ncaptures, 0);
    if (nxt_slow_path(array == NULL)) {
        goto fail;
    }

    captures = nxt_regex_captures(match_data);

    for (i = 0; i < regexp->pattern->ncaptures; i++) {
        n = 2 * i;

        if (captures[n] != -1) {
            start = &string[captures[n]];
            size = captures[n + 1] - captures[n];

            switch (utf8) {
            case 0:
                length = 0;
                break;
            case 1:
                length = size;
                break;
            default:
                length = nxt_utf8_length(start, size);
                break;
            }

            ret = njs_regexp_string_create(vm, &array->start[i],
                                           start, size, length);
            if (nxt_slow_path(ret != NXT_OK)) {
                goto fail;
            }

        } else {
            array->start[i] = njs_value_void;
        }
    }

    prop = njs_object_prop_alloc(vm, &njs_string_index);
    if (nxt_slow_path(prop == NULL)) {
        goto fail;
    }

    /* TODO: Non UTF-8 position */

    njs_number_set(&prop->value, regexp->last_index + captures[0]);

    if (regexp->pattern->global) {
        regexp->last_index += captures[1];
    }

    lhq.key_hash = NJS_INDEX_HASH;
    lhq.key.len = sizeof("index") - 1;
    lhq.key.data = (u_char *) "index";
    lhq.replace = 0;
    lhq.value = prop;
    lhq.pool = vm->mem_cache_pool;
    lhq.proto = &njs_object_hash_proto;

    ret = nxt_lvlhsh_insert(&array->object.hash, &lhq);
    if (nxt_slow_path(ret != NXT_OK)) {
        goto fail;
    }

    prop = njs_object_prop_alloc(vm, &njs_string_input);
    if (nxt_slow_path(prop == NULL)) {
        goto fail;
    }

    njs_string_copy(&prop->value, &regexp->string);

    lhq.key_hash = NJS_INPUT_HASH;
    lhq.key.len = sizeof("input") - 1;
    lhq.key.data = (u_char *) "input";
    lhq.value = prop;

    ret = nxt_lvlhsh_insert(&array->object.hash, &lhq);

    if (nxt_fast_path(ret == NXT_OK)) {
        vm->retval.data.u.array = array;
        vm->retval.type = NJS_ARRAY;
        vm->retval.data.truth = 1;

        ret = NXT_OK;
        goto done;
    }

fail:

    ret = NXT_ERROR;

done:

    nxt_regex_match_data_free(match_data, vm->regex_context);

    return ret;
}