示例#1
0
文件: njs_array.c 项目: AsamQi/njs
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
nxt_noinline njs_object_t *
njs_object_alloc(njs_vm_t *vm)
{
    njs_object_t  *object;

    object = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_object_t));

    if (nxt_fast_path(object != NULL)) {
        nxt_lvlhsh_init(&object->hash);
        nxt_lvlhsh_init(&object->shared_hash);
        object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT];
    }

    return object;
}
njs_regexp_t *
njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern)
{
    njs_regexp_t  *regexp;

    regexp = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_regexp_t));

    if (nxt_fast_path(regexp != NULL)) {
        nxt_lvlhsh_init(&regexp->object.hash);
        nxt_lvlhsh_init(&regexp->object.shared_hash);
        regexp->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_REGEXP];
        regexp->object.shared = 0;
        regexp->last_index = 0;
        regexp->pattern = pattern;
    }

    return regexp;
}
示例#4
0
static njs_vm_t *
ngx_http_js_compile(ngx_conf_t *cf, ngx_str_t *script)
{
    u_char               *start, *end;
    nxt_int_t              rc;
    nxt_str_t              s;
    njs_vm_t             *vm;
    nxt_lvlhsh_t           externals;
    njs_vm_shared_t      *shared;
    nxt_mem_cache_pool_t  *mcp;

    mcp = ngx_http_js_create_mem_cache_pool();
    if (mcp == NULL) {
        return NULL;
    }

    shared = NULL;

    nxt_lvlhsh_init(&externals);

    if (njs_add_external(&externals, mcp, 0, ngx_http_js_externals,
                         nxt_nitems(ngx_http_js_externals))
        != NJS_OK)
    {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "could not add js externals");
        return NULL;
    }

    vm = njs_vm_create(mcp, &shared, &externals);
    if (vm == NULL) {
        return NULL;
    }

    start = script->data;
    end = start + script->len;

    rc = njs_vm_compile(vm, &start, end);

    if (rc != NJS_OK) {
        njs_vm_exception(vm, &s);

        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "js compilation error: \"%*s\"", s.len, s.data);
        return NULL;
    }

    if (start != end) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "extra characters in js script: \"%*s\"",
                           end - start, start);
        return NULL;
    }

    return vm;
}
示例#5
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;
}
示例#6
0
static char *
ngx_http_js_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_js_loc_conf_t *jlcf = conf;

    size_t                 size;
    u_char                *start, *end;
    ssize_t                n;
    ngx_fd_t               fd;
    ngx_str_t             *value, file;
    nxt_int_t              rc;
    nxt_str_t              text, ext, *export;
    nxt_lvlhsh_t           externals;
    ngx_file_info_t        fi;
    njs_vm_shared_t       *shared;
    ngx_pool_cleanup_t    *cln;
    nxt_mem_cache_pool_t  *mcp;

    if (jlcf->vm) {
        return "is duplicate";
    }

    value = cf->args->elts;
    file = value[1];

    if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    fd = ngx_open_file(file.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
    if (fd == NGX_INVALID_FILE) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
                           ngx_open_file_n " \"%s\" failed", file.data);
        return NGX_CONF_ERROR;
    }

    if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
        ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
                      ngx_fd_info_n " \"%s\" failed", file.data);
        (void) ngx_close_file(fd);
        return NGX_CONF_ERROR;
    }

    size = ngx_file_size(&fi);

    start = ngx_pnalloc(cf->pool, size);
    if (start == NULL) {
        (void) ngx_close_file(fd);
        return NGX_CONF_ERROR;
    }

    n = ngx_read_fd(fd, start,  size);

    if (n == -1) {
        ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
                      ngx_read_fd_n " \"%s\" failed", file.data);

        (void) ngx_close_file(fd);
        return NGX_CONF_ERROR;
    }

    if ((size_t) n != size) {
        ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
                      ngx_read_fd_n " has read only %z of %O from \"%s\"",
                      n, size, file.data);

        (void) ngx_close_file(fd);
        return NGX_CONF_ERROR;
    }

    if (ngx_close_file(fd) == NGX_FILE_ERROR) {
        ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
                      ngx_close_file_n " %s failed", file.data);
    }

    end = start + size;

    mcp = ngx_http_js_create_mem_cache_pool();
    if (mcp == NULL) {
        return NGX_CONF_ERROR;
    }

    cln = ngx_pool_cleanup_add(cf->pool, 0);
    if (cln == NULL) {
        return NULL;
    }

    cln->handler = ngx_http_js_cleanup_mem_cache_pool;
    cln->data = mcp;

    shared = NULL;

    nxt_lvlhsh_init(&externals);

    if (njs_vm_external_add(&externals, mcp, 0, ngx_http_js_externals,
                            nxt_nitems(ngx_http_js_externals))
        != NJS_OK)
    {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "could not add js externals");
        return NGX_CONF_ERROR;
    }

    jlcf->vm = njs_vm_create(mcp, &shared, &externals);
    if (jlcf->vm == NULL) {
        return NGX_CONF_ERROR;
    }

    rc = njs_vm_compile(jlcf->vm, &start, end, NULL, &export);

    if (rc != NJS_OK) {
        njs_vm_exception(jlcf->vm, &text);

        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "%*s, included",
                           text.length, text.start);
        return NGX_CONF_ERROR;
    }

    if (start != end) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "extra characters in js script: \"%*s\", included",
                           end - start, start);
        return NGX_CONF_ERROR;
    }

    ext = nxt_string_value("$r");

    if (njs_vm_external(jlcf->vm, NULL, &ext, &jlcf->args[0]) != NJS_OK) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "js external \"%*s\" not found",
                           ext.length, ext.start);
        return NGX_CONF_ERROR;
    }

    ext = nxt_string_value("response");

    rc = njs_vm_external(jlcf->vm, &jlcf->args[0], &ext, &jlcf->args[1]);
    if (rc != NXT_OK) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "js external \"$r.%*s\" not found",
                           ext.length, ext.start);
        return NGX_CONF_ERROR;
    }

    return NGX_CONF_OK;
}