Пример #1
0
static nxt_int_t
njs_parser_boolean_expression(njs_vm_t *vm, njs_parser_t *parser,
    njs_token_t token, const void *data)
{
    njs_parser_node_t  *node;

    node = njs_parser_node_alloc(vm);

    if (nxt_fast_path(node != NULL)) {
        node->token = token;
        node->u.value = (parser->lexer->number == 0.0) ? njs_value_false:
                                                         njs_value_true;
        parser->node = node;

        return NXT_OK;
    }

    return NXT_ERROR;
}
Пример #2
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;
}
Пример #3
0
static nxt_int_t
njs_parser_node(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token,
    const void *data)
{
    njs_parser_node_t  *node;

    token = (njs_token_t) data;

    node = njs_parser_node_alloc(vm);

    if (nxt_fast_path(node != NULL)) {
        node->token = token;
        node->left = parser->node;
        parser->node = node;

        return NXT_OK;
    }

    return NXT_ERROR;
}
Пример #4
0
nxt_noinline njs_object_t *
njs_object_value_alloc(njs_vm_t *vm, const njs_value_t *value, nxt_uint_t type)
{
    nxt_uint_t          index;
    njs_object_value_t  *ov;

    ov = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_object_value_t));

    if (nxt_fast_path(ov != NULL)) {
        nxt_lvlhsh_init(&ov->object.hash);
        nxt_lvlhsh_init(&ov->object.shared_hash);

        index = njs_primitive_prototype_index(type);
        ov->object.__proto__ = &vm->prototypes[index];

        ov->value = *value;
    }

    return &ov->object;
}
Пример #5
0
static int
njs_regexp_pattern_compile(njs_vm_t *vm, nxt_regex_t *regex, u_char *source,
                           int options)
{
    nxt_int_t            ret;
    nxt_trace_handler_t  handler;

    handler = vm->trace.handler;
    vm->trace.handler = njs_regexp_compile_trace_handler;

    /* Zero length means a zero-terminated string. */
    ret = nxt_regex_compile(regex, source, 0, options, vm->regex_context);

    vm->trace.handler = handler;

    if (nxt_fast_path(ret == NXT_OK)) {
        return regex->ncaptures;
    }

    return ret;
}
Пример #6
0
static nxt_int_t
njs_parser_number_expression(njs_vm_t *vm, njs_parser_t *parser,
    njs_token_t token, const void *data)
{
    double             num;
    njs_parser_node_t  *node;

    node = njs_parser_node_alloc(vm);

    if (nxt_fast_path(node != NULL)) {
        node->token = token;
        num = parser->lexer->number;
        node->u.value.data.u.number = num;
        node->u.value.type = NJS_NUMBER;
        node->u.value.data.truth = njs_is_number_true(num);
        parser->node = node;

        return NXT_OK;
    }

    return NXT_ERROR;
}
Пример #7
0
static nxt_int_t
njs_parser_unary_expression(njs_vm_t *vm, njs_parser_t *parser,
    njs_token_t token, const void *data)
{
    njs_parser_node_t       *node;
    njs_vmcode_operation_t  operation;

    operation = (njs_vmcode_operation_t) data;

    node = njs_parser_node_alloc(vm);

    if (nxt_fast_path(node != NULL)) {
        node->token = token;
        node->u.operation = operation;
        parser->node = node;
        parser->code_size += sizeof(njs_vmcode_2addr_t);

        return NXT_OK;
    }

    return NXT_ERROR;
}
Пример #8
0
static nxt_int_t
nxt_lvlhsh_new_bucket(nxt_lvlhsh_query_t *lhq, void **slot)
{
    uint32_t  *bucket;

    bucket = lhq->proto->alloc(lhq->pool, nxt_lvlhsh_bucket_size(lhq->proto),
                               lhq->proto->nalloc);

    if (nxt_fast_path(bucket != NULL)) {

        nxt_lvlhsh_set_entry_value(bucket, lhq->value);
        nxt_lvlhsh_set_entry_key(bucket, lhq->key_hash);

        *nxt_lvlhsh_next_bucket(lhq->proto, bucket) = NULL;

        nxt_lvlhsh_store_bucket(*slot, bucket);

        return NXT_OK;
    }

    return NXT_ERROR;
}
Пример #9
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;
}
Пример #10
0
static nxt_int_t
njs_parser_condition_expression(njs_vm_t *vm, njs_parser_t *parser,
    njs_token_t token, const void *data)
{
    njs_parser_node_t  *node;

    node = njs_parser_node_alloc(vm);

    if (nxt_fast_path(node != NULL)) {
        node->token = token;
        node->left = parser->node;
        parser->node = node;
        parser->code_size += sizeof(njs_vmcode_cond_jump_t)
                             + sizeof(njs_vmcode_move_t)
                             + sizeof(njs_vmcode_jump_t)
                             + sizeof(njs_vmcode_move_t);
        parser->branch = 1;

        return NXT_OK;
    }

    return NXT_ERROR;
}
Пример #11
0
static nxt_int_t
njs_parser_string_expression(njs_vm_t *vm, njs_parser_t *parser,
    njs_token_t token, const void *data)
{
    nxt_int_t          ret;
    njs_parser_node_t  *node;

    node = njs_parser_node_alloc(vm);

    if (nxt_fast_path(node != NULL)) {
        node->token = token;

        ret = njs_parser_string_create(vm, &node->u.value);
        if (nxt_slow_path(ret != NXT_OK)) {
            return NJS_TOKEN_ERROR;
        }

        parser->node = node;

        return NXT_OK;
    }

    return NXT_ERROR;
}
Пример #12
0
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;
}
Пример #13
0
njs_regexp_pattern_t *
njs_regexp_pattern_create(njs_vm_t *vm, u_char *start, size_t length,
    njs_regexp_flags_t flags)
{
    int                   options, ret;
    u_char                *p, *end;
    size_t                size;
    njs_regexp_pattern_t  *pattern;

    size = 1;  /* A trailing "/". */
    size += ((flags & NJS_REGEXP_GLOBAL) != 0);
    size += ((flags & NJS_REGEXP_IGNORE_CASE) != 0);
    size += ((flags & NJS_REGEXP_MULTILINE) != 0);

    pattern = nxt_mem_cache_zalloc(vm->mem_cache_pool,
                                   sizeof(njs_regexp_pattern_t)
                                   + 1 + length + size + 1);
    if (nxt_slow_path(pattern == NULL)) {
        return NULL;
    }

    pattern->flags = size;
    pattern->next = NULL;

    p = (u_char *) pattern + sizeof(njs_regexp_pattern_t);
    pattern->source = p;

    *p++ = '/';
    p = memcpy(p, start, length);
    p += length;
    end = p;
    *p++ = '\0';

    pattern->global = ((flags & NJS_REGEXP_GLOBAL) != 0);
    if (pattern->global) {
        *p++ = 'g';
    }

#ifdef PCRE_JAVASCRIPT_COMPAT
    /* JavaScript compatibility has been introduced in PCRE-7.7. */
    options = PCRE_JAVASCRIPT_COMPAT;
#else
    options = 0;
#endif

    pattern->ignore_case = ((flags & NJS_REGEXP_IGNORE_CASE) != 0);
    if (pattern->ignore_case) {
        *p++ = 'i';
         options |= PCRE_CASELESS;
    }

    pattern->multiline = ((flags & NJS_REGEXP_MULTILINE) != 0);
    if (pattern->multiline) {
        *p++ = 'm';
         options |= PCRE_MULTILINE;
    }

    *p++ = '\0';

    ret = njs_regexp_pattern_compile(vm, &pattern->regex[0],
                                     &pattern->source[1], options);
    if (nxt_slow_path(ret < 0)) {
        return NULL;
    }

    pattern->ncaptures = ret;

    ret = njs_regexp_pattern_compile(vm, &pattern->regex[1],
                                     &pattern->source[1], options | PCRE_UTF8);
    if (nxt_fast_path(ret >= 0)) {

        if (nxt_slow_path((u_int) ret != pattern->ncaptures)) {
            vm->exception = &njs_exception_internal_error;
            nxt_mem_cache_free(vm->mem_cache_pool, pattern);
            return NULL;
        }

    } else if (ret != NXT_DECLINED) {
        nxt_mem_cache_free(vm->mem_cache_pool, pattern);
        return NULL;
    }

    *end = '/';

    return pattern;
}
Пример #14
0
static njs_ret_t
njs_object_prototype_create_constructor(njs_vm_t *vm, njs_value_t *value)
{
    int32_t                   index;
    nxt_int_t                 ret;
    njs_value_t               *constructor;
    njs_object_t              *prototype;
    njs_object_prop_t         *prop;
    nxt_lvlhsh_query_t        lhq;

    static const njs_value_t  constructor_string = njs_string("constructor");

    if (njs_is_object(value)) {
        prototype = value->data.u.object;

        do {
            index = prototype - vm->prototypes;

            if (index >= 0 && index < NJS_PROTOTYPE_MAX) {
                goto found;
            }

            prototype = prototype->__proto__;

        } while (prototype != NULL);

        nxt_thread_log_alert("prototype not found");

        return NXT_ERROR;

    } else {
        index = njs_primitive_prototype_index(value->type);
        prototype = &vm->prototypes[index];
    }

found:

    prop = njs_object_prop_alloc(vm, &constructor_string);
    if (nxt_slow_path(prop == NULL)) {
        return NXT_ERROR;
    }

    /* GC */

    constructor = &vm->scopes[NJS_SCOPE_GLOBAL][index];
    prop->value = *constructor;

    prop->enumerable = 0;

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

    ret = nxt_lvlhsh_insert(&prototype->hash, &lhq);

    if (nxt_fast_path(ret == NXT_OK)) {
        vm->retval = *constructor;
    }

    return ret;
}