[njs] Externals refactored.
Dmitry Volyntsev
xeioex at nginx.com
Tue Feb 20 16:19:28 UTC 2018
details: http://hg.nginx.org/njs/rev/e7bc9d328a20
branches:
changeset: 448:e7bc9d328a20
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Feb 20 19:12:53 2018 +0300
description:
Externals refactored.
Public API is rectified to allow the creation of external objects in
runtime.
1) njs_vm_external_add() is replaced with njs_vm_external_prototype().
The later functions returns a pointer to a prototype object which can
be used to create a value with such a prototype in runtime.
2) njs_vm_external() is split into njs_vm_external_create() and
njs_vm_external_bind(). The former creates a variable with a specified
prototype and associates it with an external pointer. The latter binds
a variable to a name in the global namespace.
diffstat:
nginx/ngx_http_js_module.c | 212 ++++++---------------
nginx/ngx_stream_js_module.c | 176 ++++-------------
njs/njs.c | 75 +++----
njs/njs_builtin.c | 26 +-
njs/njs_extern.c | 209 +++++++++++++-------
njs/njs_extern.h | 14 +-
njs/njs_parser.c | 6 +-
njs/njs_parser.h | 3 +-
njs/njs_vm.c | 168 ++++++++++-------
njs/njs_vm.h | 19 +-
njs/njscript.c | 71 ++++--
njs/njscript.h | 22 +-
njs/test/njs_benchmark.c | 114 ++++-------
njs/test/njs_interactive_test.c | 27 +-
njs/test/njs_unit_test.c | 381 +++++++++++++++++++++++++++------------
nxt/nxt_array.h | 4 +
nxt/nxt_lvlhsh.c | 4 +-
nxt/nxt_lvlhsh.h | 6 +-
18 files changed, 800 insertions(+), 737 deletions(-)
diffs (truncated from 2773 to 1000 lines):
diff -r 0a3645d22d22 -r e7bc9d328a20 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c Tue Feb 20 19:12:52 2018 +0300
+++ b/nginx/ngx_http_js_module.c Tue Feb 20 19:12:53 2018 +0300
@@ -15,37 +15,21 @@
#include <nxt_string.h>
#include <nxt_stub.h>
#include <nxt_array.h>
-#include <nxt_random.h>
-#include <nxt_lvlhsh.h>
-#include <nxt_mem_cache_pool.h>
#include <njscript.h>
-#define NGX_HTTP_JS_MCP_CLUSTER_SIZE (2 * ngx_pagesize)
-#define NGX_HTTP_JS_MCP_PAGE_ALIGNMENT 128
-#define NGX_HTTP_JS_MCP_PAGE_SIZE 512
-#define NGX_HTTP_JS_MCP_MIN_CHUNK_SIZE 16
-
-
-#define ngx_http_js_create_mem_cache_pool() \
- nxt_mem_cache_pool_create(&ngx_http_js_mem_cache_pool_proto, NULL, NULL, \
- NGX_HTTP_JS_MCP_CLUSTER_SIZE, \
- NGX_HTTP_JS_MCP_PAGE_ALIGNMENT, \
- NGX_HTTP_JS_MCP_PAGE_SIZE, \
- NGX_HTTP_JS_MCP_MIN_CHUNK_SIZE)
+typedef struct {
+ njs_vm_t *vm;
+ ngx_str_t content;
+ const njs_extern_t *req_proto;
+ const njs_extern_t *res_proto;
+} ngx_http_js_loc_conf_t;
typedef struct {
njs_vm_t *vm;
njs_opaque_value_t args[2];
- ngx_str_t content;
-} ngx_http_js_loc_conf_t;
-
-
-typedef struct {
- njs_vm_t *vm;
- njs_opaque_value_t *args;
} ngx_http_js_ctx_t;
@@ -59,12 +43,7 @@ static ngx_int_t ngx_http_js_handler(ngx
static ngx_int_t ngx_http_js_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_js_init_vm(ngx_http_request_t *r);
-static void ngx_http_js_cleanup_mem_cache_pool(void *data);
-
-static void *ngx_http_js_alloc(void *mem, size_t size);
-static void *ngx_http_js_calloc(void *mem, size_t size);
-static void *ngx_http_js_memalign(void *mem, size_t alignment, size_t size);
-static void ngx_http_js_free(void *mem, void *p);
+static void ngx_http_js_cleanup_vm(void *data);
static njs_ret_t ngx_http_js_ext_get_string(njs_vm_t *vm, njs_value_t *value,
void *obj, uintptr_t data);
@@ -183,17 +162,6 @@ ngx_module_t ngx_http_js_module = {
};
-static const nxt_mem_proto_t ngx_http_js_mem_cache_pool_proto = {
- ngx_http_js_alloc,
- ngx_http_js_calloc,
- ngx_http_js_memalign,
- NULL,
- ngx_http_js_free,
- NULL,
- NULL,
-};
-
-
static njs_external_t ngx_http_js_ext_response[] = {
{ nxt_string("headers"),
@@ -284,18 +252,6 @@ static njs_external_t ngx_http_js_ext_r
static njs_external_t ngx_http_js_ext_request[] = {
- { nxt_string("response"),
- NJS_EXTERN_OBJECT,
- ngx_http_js_ext_response,
- nxt_nitems(ngx_http_js_ext_response),
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- 0 },
-
{ nxt_string("log"),
NJS_EXTERN_METHOD,
NULL,
@@ -396,7 +352,7 @@ static njs_external_t ngx_http_js_ext_r
static njs_external_t ngx_http_js_externals[] = {
- { nxt_string("$r"),
+ { nxt_string("request"),
NJS_EXTERN_OBJECT,
ngx_http_js_ext_request,
nxt_nitems(ngx_http_js_ext_request),
@@ -407,6 +363,18 @@ static njs_external_t ngx_http_js_exter
NULL,
NULL,
0 },
+
+ { nxt_string("response"),
+ NJS_EXTERN_OBJECT,
+ ngx_http_js_ext_response,
+ nxt_nitems(ngx_http_js_ext_response),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0 },
};
@@ -520,11 +488,10 @@ ngx_http_js_variable(ngx_http_request_t
static ngx_int_t
ngx_http_js_init_vm(ngx_http_request_t *r)
{
- void **ext;
- ngx_http_js_ctx_t *ctx;
- ngx_pool_cleanup_t *cln;
- nxt_mem_cache_pool_t *mcp;
- ngx_http_js_loc_conf_t *jlcf;
+ nxt_int_t rc;
+ ngx_http_js_ctx_t *ctx;
+ ngx_pool_cleanup_t *cln;
+ ngx_http_js_loc_conf_t *jlcf;
jlcf = ngx_http_get_module_loc_conf(r, ngx_http_js_module);
if (jlcf->vm == NULL) {
@@ -546,8 +513,8 @@ ngx_http_js_init_vm(ngx_http_request_t *
return NGX_OK;
}
- mcp = ngx_http_js_create_mem_cache_pool();
- if (mcp == NULL) {
+ ctx->vm = njs_vm_clone(jlcf->vm, r);
+ if (ctx->vm == NULL) {
return NGX_ERROR;
}
@@ -556,65 +523,33 @@ ngx_http_js_init_vm(ngx_http_request_t *
return NGX_ERROR;
}
- cln->handler = ngx_http_js_cleanup_mem_cache_pool;
- cln->data = mcp;
-
- ext = ngx_palloc(r->pool, sizeof(void *));
- if (ext == NULL) {
- return NGX_ERROR;
- }
-
- *ext = r;
-
- ctx->vm = njs_vm_clone(jlcf->vm, mcp, ext);
- if (ctx->vm == NULL) {
- return NGX_ERROR;
- }
+ cln->handler = ngx_http_js_cleanup_vm;
+ cln->data = ctx->vm;
if (njs_vm_run(ctx->vm) != NJS_OK) {
return NGX_ERROR;
}
- ctx->args = &jlcf->args[0];
+ rc = njs_vm_external_create(ctx->vm, &ctx->args[0], jlcf->req_proto, r);
+ if (rc != NXT_OK) {
+ return NGX_ERROR;
+ }
+
+ rc = njs_vm_external_create(ctx->vm, &ctx->args[1], jlcf->res_proto, r);
+ if (rc != NXT_OK) {
+ return NGX_ERROR;
+ }
return NGX_OK;
}
static void
-ngx_http_js_cleanup_mem_cache_pool(void *data)
+ngx_http_js_cleanup_vm(void *data)
{
- nxt_mem_cache_pool_t *mcp = data;
-
- nxt_mem_cache_pool_destroy(mcp);
-}
-
-
-static void *
-ngx_http_js_alloc(void *mem, size_t size)
-{
- return ngx_alloc(size, ngx_cycle->log);
-}
-
+ njs_vm_t *vm = data;
-static void *
-ngx_http_js_calloc(void *mem, size_t size)
-{
- return ngx_calloc(size, ngx_cycle->log);
-}
-
-
-static void *
-ngx_http_js_memalign(void *mem, size_t alignment, size_t size)
-{
- return ngx_memalign(alignment, size, ngx_cycle->log);
-}
-
-
-static void
-ngx_http_js_free(void *mem, void *p)
-{
- ngx_free(p);
+ njs_vm_destroy(vm);
}
@@ -1229,12 +1164,10 @@ ngx_http_js_include(ngx_conf_t *cf, ngx_
ngx_fd_t fd;
ngx_str_t *value, file;
nxt_int_t rc;
- nxt_str_t text, ext;
+ nxt_str_t text;
njs_vm_opt_t options;
- nxt_lvlhsh_t externals;
ngx_file_info_t fi;
ngx_pool_cleanup_t *cln;
- nxt_mem_cache_pool_t *mcp;
if (jlcf->vm) {
return "is duplicate";
@@ -1295,8 +1228,13 @@ ngx_http_js_include(ngx_conf_t *cf, ngx_
end = start + size;
- mcp = ngx_http_js_create_mem_cache_pool();
- if (mcp == NULL) {
+ ngx_memzero(&options, sizeof(njs_vm_opt_t));
+
+ options.backtrace = 1;
+
+ jlcf->vm = njs_vm_create(&options);
+ if (jlcf->vm == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "failed to create JS VM");
return NGX_CONF_ERROR;
}
@@ -1305,28 +1243,21 @@ ngx_http_js_include(ngx_conf_t *cf, ngx_
return NGX_CONF_ERROR;
}
- cln->handler = ngx_http_js_cleanup_mem_cache_pool;
- cln->data = mcp;
-
- nxt_lvlhsh_init(&externals);
+ cln->handler = ngx_http_js_cleanup_vm;
+ cln->data = jlcf->vm;
- 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");
+ jlcf->req_proto = njs_vm_external_prototype(jlcf->vm,
+ &ngx_http_js_externals[0]);
+ if (jlcf->req_proto == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "failed to add request proto");
return NGX_CONF_ERROR;
}
- ngx_memzero(&options, sizeof(njs_vm_opt_t));
-
- options.mcp = mcp;
- options.backtrace = 1;
- options.externals_hash = &externals;
-
- jlcf->vm = njs_vm_create(&options);
- if (jlcf->vm == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "failed to create JS VM");
+ jlcf->res_proto = njs_vm_external_prototype(jlcf->vm,
+ &ngx_http_js_externals[1]);
+ if (jlcf->res_proto == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "failed to add response proto");
return NGX_CONF_ERROR;
}
@@ -1348,25 +1279,6 @@ ngx_http_js_include(ngx_conf_t *cf, ngx_
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;
}
@@ -1443,6 +1355,8 @@ ngx_http_js_create_loc_conf(ngx_conf_t *
* set by ngx_pcalloc():
*
* conf->vm = NULL;
+ * conf->req_proto = NULL;
+ * conf->res_proto = NULL;
*/
return conf;
@@ -1457,8 +1371,8 @@ ngx_http_js_merge_loc_conf(ngx_conf_t *c
if (conf->vm == NULL) {
conf->vm = prev->vm;
- conf->args[0] = prev->args[0];
- conf->args[1] = prev->args[1];
+ conf->req_proto = prev->req_proto;
+ conf->res_proto = prev->res_proto;
}
return NGX_CONF_OK;
diff -r 0a3645d22d22 -r e7bc9d328a20 nginx/ngx_stream_js_module.c
--- a/nginx/ngx_stream_js_module.c Tue Feb 20 19:12:52 2018 +0300
+++ b/nginx/ngx_stream_js_module.c Tue Feb 20 19:12:53 2018 +0300
@@ -15,39 +15,22 @@
#include <nxt_string.h>
#include <nxt_stub.h>
#include <nxt_array.h>
-#include <nxt_random.h>
-#include <nxt_lvlhsh.h>
-#include <nxt_mem_cache_pool.h>
#include <njscript.h>
-#define NGX_STREAM_JS_MCP_CLUSTER_SIZE (2 * ngx_pagesize)
-#define NGX_STREAM_JS_MCP_PAGE_ALIGNMENT 128
-#define NGX_STREAM_JS_MCP_PAGE_SIZE 512
-#define NGX_STREAM_JS_MCP_MIN_CHUNK_SIZE 16
-
-
-#define ngx_stream_js_create_mem_cache_pool() \
- nxt_mem_cache_pool_create(&ngx_stream_js_mem_cache_pool_proto, NULL, NULL,\
- NGX_STREAM_JS_MCP_CLUSTER_SIZE, \
- NGX_STREAM_JS_MCP_PAGE_ALIGNMENT, \
- NGX_STREAM_JS_MCP_PAGE_SIZE, \
- NGX_STREAM_JS_MCP_MIN_CHUNK_SIZE)
+typedef struct {
+ njs_vm_t *vm;
+ ngx_str_t access;
+ ngx_str_t preread;
+ ngx_str_t filter;
+ const njs_extern_t *proto;
+} ngx_stream_js_srv_conf_t;
typedef struct {
njs_vm_t *vm;
njs_opaque_value_t arg;
- ngx_str_t access;
- ngx_str_t preread;
- ngx_str_t filter;
-} ngx_stream_js_srv_conf_t;
-
-
-typedef struct {
- njs_vm_t *vm;
- njs_opaque_value_t *arg;
ngx_buf_t *buf;
ngx_chain_t *free;
ngx_chain_t *busy;
@@ -65,13 +48,8 @@ static ngx_int_t ngx_stream_js_body_filt
ngx_chain_t *in, ngx_uint_t from_upstream);
static ngx_int_t ngx_stream_js_variable(ngx_stream_session_t *s,
ngx_stream_variable_value_t *v, uintptr_t data);
-static void ngx_stream_js_cleanup_mem_cache_pool(void *data);
static ngx_int_t ngx_stream_js_init_vm(ngx_stream_session_t *s);
-
-static void *ngx_stream_js_alloc(void *mem, size_t size);
-static void *ngx_stream_js_calloc(void *mem, size_t size);
-static void *ngx_stream_js_memalign(void *mem, size_t alignment, size_t size);
-static void ngx_stream_js_free(void *mem, void *p);
+static void ngx_stream_js_cleanup_vm(void *data);
static njs_ret_t ngx_stream_js_ext_get_remote_address(njs_vm_t *vm,
njs_value_t *value, void *obj, uintptr_t data);
@@ -169,17 +147,6 @@ ngx_module_t ngx_stream_js_module = {
};
-static const nxt_mem_proto_t ngx_stream_js_mem_cache_pool_proto = {
- ngx_stream_js_alloc,
- ngx_stream_js_calloc,
- ngx_stream_js_memalign,
- NULL,
- ngx_stream_js_free,
- NULL,
- NULL,
-};
-
-
static njs_external_t ngx_stream_js_ext_session[] = {
{ nxt_string("remoteAddress"),
@@ -318,7 +285,7 @@ static njs_external_t ngx_stream_js_ext
static njs_external_t ngx_stream_js_externals[] = {
- { nxt_string("$s"),
+ { nxt_string("stream"),
NJS_EXTERN_OBJECT,
ngx_stream_js_ext_session,
nxt_nitems(ngx_stream_js_ext_session),
@@ -405,7 +372,7 @@ ngx_stream_js_phase_handler(ngx_stream_s
return NGX_ERROR;
}
- if (njs_vm_call(ctx->vm, func, ctx->arg, 1) != NJS_OK) {
+ if (njs_vm_call(ctx->vm, func, &ctx->arg, 1) != NJS_OK) {
njs_vm_retval_to_ext_string(ctx->vm, &exception);
ngx_log_error(NGX_LOG_ERR, c->log, 0, "js exception: %*s",
@@ -492,7 +459,7 @@ ngx_stream_js_body_filter(ngx_stream_ses
while (in) {
ctx->buf = in->buf;
- if (njs_vm_call(ctx->vm, func, ctx->arg, 1) != NJS_OK) {
+ if (njs_vm_call(ctx->vm, func, &ctx->arg, 1) != NJS_OK) {
njs_vm_retval_to_ext_string(ctx->vm, &exception);
ngx_log_error(NGX_LOG_ERR, c->log, 0, "js exception: %*s",
@@ -590,7 +557,7 @@ ngx_stream_js_variable(ngx_stream_sessio
return NGX_OK;
}
- if (njs_vm_call(ctx->vm, func, ctx->arg, 1) != NJS_OK) {
+ if (njs_vm_call(ctx->vm, func, &ctx->arg, 1) != NJS_OK) {
njs_vm_retval_to_ext_string(ctx->vm, &exception);
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
@@ -617,11 +584,10 @@ ngx_stream_js_variable(ngx_stream_sessio
static ngx_int_t
ngx_stream_js_init_vm(ngx_stream_session_t *s)
{
- void **ext;
- ngx_pool_cleanup_t *cln;
- nxt_mem_cache_pool_t *mcp;
- ngx_stream_js_ctx_t *ctx;
- ngx_stream_js_srv_conf_t *jscf;
+ nxt_int_t rc;
+ ngx_pool_cleanup_t *cln;
+ ngx_stream_js_ctx_t *ctx;
+ ngx_stream_js_srv_conf_t *jscf;
jscf = ngx_stream_get_module_srv_conf(s, ngx_stream_js_module);
if (jscf->vm == NULL) {
@@ -643,8 +609,8 @@ ngx_stream_js_init_vm(ngx_stream_session
return NGX_OK;
}
- mcp = ngx_stream_js_create_mem_cache_pool();
- if (mcp == NULL) {
+ ctx->vm = njs_vm_clone(jscf->vm, s);
+ if (ctx->vm == NULL) {
return NGX_ERROR;
}
@@ -653,65 +619,28 @@ ngx_stream_js_init_vm(ngx_stream_session
return NGX_ERROR;
}
- cln->handler = ngx_stream_js_cleanup_mem_cache_pool;
- cln->data = mcp;
-
- ext = ngx_palloc(s->connection->pool, sizeof(void *));
- if (ext == NULL) {
- return NGX_ERROR;
- }
-
- *ext = s;
-
- ctx->vm = njs_vm_clone(jscf->vm, mcp, ext);
- if (ctx->vm == NULL) {
- return NGX_ERROR;
- }
+ cln->handler = ngx_stream_js_cleanup_vm;
+ cln->data = ctx->vm;
if (njs_vm_run(ctx->vm) != NJS_OK) {
return NGX_ERROR;
}
- ctx->arg = &jscf->arg;
+ rc = njs_vm_external_create(ctx->vm, &ctx->arg, jscf->proto, s);
+ if (rc != NXT_OK) {
+ return NGX_ERROR;
+ }
return NGX_OK;
}
static void
-ngx_stream_js_cleanup_mem_cache_pool(void *data)
+ngx_stream_js_cleanup_vm(void *data)
{
- nxt_mem_cache_pool_t *mcp = data;
-
- nxt_mem_cache_pool_destroy(mcp);
-}
-
-
-static void *
-ngx_stream_js_alloc(void *mem, size_t size)
-{
- return ngx_alloc(size, ngx_cycle->log);
-}
-
+ njs_vm_t *vm = data;
-static void *
-ngx_stream_js_calloc(void *mem, size_t size)
-{
- return ngx_calloc(size, ngx_cycle->log);
-}
-
-
-static void *
-ngx_stream_js_memalign(void *mem, size_t alignment, size_t size)
-{
- return ngx_memalign(alignment, size, ngx_cycle->log);
-}
-
-
-static void
-ngx_stream_js_free(void *mem, void *p)
-{
- ngx_free(p);
+ njs_vm_destroy(vm);
}
@@ -937,12 +866,10 @@ ngx_stream_js_include(ngx_conf_t *cf, ng
ngx_fd_t fd;
ngx_str_t *value, file;
nxt_int_t rc;
- nxt_str_t text, ext;
+ nxt_str_t text;
njs_vm_opt_t options;
- nxt_lvlhsh_t externals;
ngx_file_info_t fi;
ngx_pool_cleanup_t *cln;
- nxt_mem_cache_pool_t *mcp;
if (jscf->vm) {
return "is duplicate";
@@ -1003,8 +930,13 @@ ngx_stream_js_include(ngx_conf_t *cf, ng
end = start + size;
- mcp = ngx_stream_js_create_mem_cache_pool();
- if (mcp == NULL) {
+ ngx_memzero(&options, sizeof(njs_vm_opt_t));
+
+ options.backtrace = 1;
+
+ jscf->vm = njs_vm_create(&options);
+ if (jscf->vm == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "failed to create JS VM");
return NGX_CONF_ERROR;
}
@@ -1013,28 +945,14 @@ ngx_stream_js_include(ngx_conf_t *cf, ng
return NGX_CONF_ERROR;
}
- cln->handler = ngx_stream_js_cleanup_mem_cache_pool;
- cln->data = mcp;
-
- nxt_lvlhsh_init(&externals);
+ cln->handler = ngx_stream_js_cleanup_vm;
+ cln->data = jscf->vm;
- if (njs_vm_external_add(&externals, mcp, 0, ngx_stream_js_externals,
- nxt_nitems(ngx_stream_js_externals))
- != NJS_OK)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "could not add js externals");
- return NGX_CONF_ERROR;
- }
+ jscf->proto = njs_vm_external_prototype(jscf->vm,
+ &ngx_stream_js_externals[0]);
- ngx_memzero(&options, sizeof(njs_vm_opt_t));
-
- options.mcp = mcp;
- options.backtrace = 1;
- options.externals_hash = &externals;
-
- jscf->vm = njs_vm_create(&options);
- if (jscf->vm == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "failed to create JS VM");
+ if (jscf->proto == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "failed to add stream proto");
return NGX_CONF_ERROR;
}
@@ -1056,14 +974,6 @@ ngx_stream_js_include(ngx_conf_t *cf, ng
return NGX_CONF_ERROR;
}
- ext = nxt_string_value("$s");
-
- if (njs_vm_external(jscf->vm, NULL, &ext, &jscf->arg) != NJS_OK) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "js external \"%*s\" not found", ext.length, ext.start);
- return NGX_CONF_ERROR;
- }
-
return NGX_CONF_OK;
}
@@ -1118,7 +1028,7 @@ ngx_stream_js_create_srv_conf(ngx_conf_t
* set by ngx_pcalloc():
*
* conf->vm = NULL;
- * conf->arg = NULL;
+ * conf->proto = NULL;
* conf->access = { 0, NULL };
* conf->preread = { 0, NULL };
* conf->filter = { 0, NULL };
@@ -1136,7 +1046,7 @@ ngx_stream_js_merge_srv_conf(ngx_conf_t
if (conf->vm == NULL) {
conf->vm = prev->vm;
- conf->arg = prev->arg;
+ conf->proto = prev->proto;
}
ngx_conf_merge_str_value(conf->access, prev->access, "");
diff -r 0a3645d22d22 -r e7bc9d328a20 njs/njs.c
--- a/njs/njs.c Tue Feb 20 19:12:52 2018 +0300
+++ b/njs/njs.c Tue Feb 20 19:12:53 2018 +0300
@@ -60,7 +60,7 @@ typedef struct {
static nxt_int_t njs_get_options(njs_opts_t *opts, int argc, char **argv);
-static nxt_int_t njs_externals_init(njs_opts_t *opts, njs_vm_opt_t *vm_options);
+static nxt_int_t njs_externals_init(njs_vm_t *vm);
static nxt_int_t njs_interactive_shell(njs_opts_t *opts,
njs_vm_opt_t *vm_options);
static nxt_int_t njs_process_file(njs_opts_t *opts, njs_vm_opt_t *vm_options);
@@ -119,17 +119,15 @@ static njs_external_t njs_externals[] =
};
-static nxt_lvlhsh_t njs_externals_hash;
static njs_completion_t njs_completion;
int
main(int argc, char **argv)
{
- nxt_int_t ret;
- njs_opts_t opts;
- njs_vm_opt_t vm_options;
- nxt_mem_cache_pool_t *mcp;
+ nxt_int_t ret;
+ njs_opts_t opts;
+ njs_vm_opt_t vm_options;
memset(&opts, 0, sizeof(njs_opts_t));
opts.interactive = 1;
@@ -144,22 +142,11 @@ main(int argc, char **argv)
return EXIT_SUCCESS;
}
- mcp = nxt_mem_cache_pool_create(&njs_vm_mem_cache_pool_proto, NULL,
- NULL, 2 * nxt_pagesize(), 128, 512, 16);
- if (nxt_slow_path(mcp == NULL)) {
- return EXIT_FAILURE;
- }
-
memset(&vm_options, 0, sizeof(njs_vm_opt_t));
- vm_options.mcp = mcp;
vm_options.accumulative = 1;
vm_options.backtrace = 1;
- if (njs_externals_init(&opts, &vm_options) != NXT_OK) {
- return EXIT_FAILURE;
- }
-
if (opts.interactive) {
ret = njs_interactive_shell(&opts, &vm_options);
@@ -218,30 +205,35 @@ njs_get_options(njs_opts_t *opts, int ar
static nxt_int_t
-njs_externals_init(njs_opts_t *opts, njs_vm_opt_t *vm_options)
+njs_externals_init(njs_vm_t *vm)
{
- void **ext;
- nxt_uint_t i;
-
- nxt_lvlhsh_init(&njs_externals_hash);
+ nxt_uint_t ret;
+ const njs_extern_t *proto;
+ njs_opaque_value_t *value;
- for (i = 0; i < nxt_nitems(njs_externals); i++) {
- if (njs_vm_external_add(&njs_externals_hash, vm_options->mcp,
- (uintptr_t) i, &njs_externals[i], 1)
- != NXT_OK)
- {
- fprintf(stderr, "could not add external objects\n");
- return NXT_ERROR;
- }
- }
+ static const nxt_str_t name = nxt_string_value("console");
- ext = nxt_mem_cache_zalloc(vm_options->mcp, sizeof(void *) * i);
- if (ext == NULL) {
+ proto = njs_vm_external_prototype(vm, &njs_externals[0]);
+ if (proto == NULL) {
+ fprintf(stderr, "failed to add console proto\n");
return NXT_ERROR;
}
- vm_options->external = ext;
- vm_options->externals_hash = &njs_externals_hash;
+ value = nxt_mem_cache_zalloc(vm->mem_cache_pool,
+ sizeof(njs_opaque_value_t));
+ if (value == NULL) {
+ return NXT_ERROR;
+ }
+
+ ret = njs_vm_external_create(vm, value, proto, NULL);
+ if (ret != NXT_OK) {
+ return NXT_ERROR;
+ }
+
+ ret = njs_vm_external_bind(vm, &name, value);
+ if (ret != NXT_OK) {
+ return NXT_ERROR;
+ }
return NXT_OK;
}
@@ -260,6 +252,10 @@ njs_interactive_shell(njs_opts_t *opts,
return NXT_ERROR;
}
+ if (njs_externals_init(vm) != NXT_OK) {
+ return NXT_ERROR;
+ }
+
if (njs_editline_init(vm) != NXT_OK) {
fprintf(stderr, "failed to init completions\n");
return NXT_ERROR;
@@ -393,6 +389,10 @@ njs_process_file(njs_opts_t *opts, njs_v
goto done;
}
+ if (njs_externals_init(vm) != NXT_OK) {
+ return NXT_ERROR;
+ }
+
ret = njs_process_script(vm, opts, &script, &out);
if (ret != NXT_OK) {
fprintf(stderr, "failed to get retval from VM\n");
@@ -652,10 +652,7 @@ njs_ext_console_help(njs_vm_t *vm, njs_v
}
printf("\nEmbedded objects:\n");
- for (i = 0; i < nxt_nitems(njs_externals); i++) {
- printf(" %.*s\n", (int) njs_externals[i].name.length,
- njs_externals[i].name.start);
- }
+ printf(" console\n");
printf("\n");
diff -r 0a3645d22d22 -r e7bc9d328a20 njs/njs_builtin.c
--- a/njs/njs_builtin.c Tue Feb 20 19:12:52 2018 +0300
+++ b/njs/njs_builtin.c Tue Feb 20 19:12:53 2018 +0300
@@ -513,12 +513,13 @@ njs_builtin_completions(njs_vm_t *vm, si
size_t n, len;
nxt_str_t string;
nxt_uint_t i, k;
- njs_extern_t *ext_object, *ext_prop;
njs_object_t *objects;
njs_keyword_t *keyword;
njs_function_t *constructors;
njs_object_prop_t *prop;
nxt_lvlhsh_each_t lhe, lhe_prop;
+ njs_extern_value_t *ev;
+ const njs_extern_t *ext_proto, *ext_prop;
njs_object_prototype_t *prototypes;
n = 0;
@@ -652,26 +653,27 @@ njs_builtin_completions(njs_vm_t *vm, si
}
}
- nxt_lvlhsh_each_init(&lhe, &njs_extern_hash_proto);
+ nxt_lvlhsh_each_init(&lhe, &njs_extern_value_hash_proto);
for ( ;; ) {
- ext_object = nxt_lvlhsh_each(&vm->externals_hash, &lhe);
+ ev = nxt_lvlhsh_each(&vm->externals_hash, &lhe);
- if (ext_object == NULL) {
+ if (ev == NULL) {
break;
}
+ ext_proto = ev->value->external.proto;
+
nxt_lvlhsh_each_init(&lhe_prop, &njs_extern_hash_proto);
if (completions != NULL) {
- len = ext_object->name.length + 1;
+ len = ev->name.length + 1;
compl = nxt_mem_cache_zalloc(vm->mem_cache_pool, len);
if (compl == NULL) {
return NXT_ERROR;
}
- snprintf(compl, len, "%.*s",
- (int) ext_object->name.length, ext_object->name.start);
+ snprintf(compl, len, "%.*s", (int) ev->name.length, ev->name.start);
completions[n].length = len;
completions[n++].start = (u_char *) compl;
@@ -681,22 +683,22 @@ njs_builtin_completions(njs_vm_t *vm, si
}
for ( ;; ) {
- ext_prop = nxt_lvlhsh_each(&ext_object->hash, &lhe_prop);
+ ext_prop = nxt_lvlhsh_each(&ext_proto->hash, &lhe_prop);
if (ext_prop == NULL) {
break;
}
if (completions != NULL) {
- len = ext_object->name.length + ext_prop->name.length + 2;
+ len = ev->name.length + ev->name.length + 2;
compl = nxt_mem_cache_zalloc(vm->mem_cache_pool, len);
if (compl == NULL) {
return NXT_ERROR;
}
- snprintf(compl, len, "%.*s.%.*s",
- (int) ext_object->name.length, ext_object->name.start,
- (int) ext_prop->name.length, ext_prop->name.start);
+ snprintf(compl, len, "%.*s.%.*s", (int) ev->name.length,
+ ev->name.start, (int) ext_prop->name.length,
+ ext_prop->name.start);
completions[n].length = len;
completions[n++].start = (u_char *) compl;
diff -r 0a3645d22d22 -r e7bc9d328a20 njs/njs_extern.c
--- a/njs/njs_extern.c Tue Feb 20 19:12:52 2018 +0300
+++ b/njs/njs_extern.c Tue Feb 20 19:12:53 2018 +0300
@@ -29,11 +29,24 @@ njs_extern_hash_test(nxt_lvlhsh_query_t
{
njs_extern_t *ext;
- ext = data;
+ ext = (njs_extern_t *) data;
+
+ if (nxt_strstr_eq(&lhq->key, &ext->name)) {
+ return NXT_OK;
+ }
+
+ return NXT_DECLINED;
+}
-// STUB
-// if (nxt_strcasestr_eq(&lhq->key, &ext->name)) {
- if (nxt_strstr_eq(&lhq->key, &ext->name)) {
+
+static nxt_int_t
+njs_extern_value_hash_test(nxt_lvlhsh_query_t *lhq, void *data)
+{
+ njs_extern_value_t *ev;
+
+ ev = (njs_extern_value_t *) data;
+
+ if (nxt_strstr_eq(&lhq->key, &ev->name)) {
return NXT_OK;
}
@@ -52,71 +65,78 @@ const nxt_lvlhsh_proto_t njs_extern_has
};
-nxt_int_t
-njs_vm_external_add(nxt_lvlhsh_t *hash, nxt_mem_cache_pool_t *mcp,
- uintptr_t object, njs_external_t *external, nxt_uint_t n)
+const nxt_lvlhsh_proto_t njs_extern_value_hash_proto
+ nxt_aligned(64) =
+{
+ NXT_LVLHSH_DEFAULT,
+ NXT_LVLHSH_BATCH_ALLOC,
+ njs_extern_value_hash_test,
+ njs_lvlhsh_alloc,
+ njs_lvlhsh_free,
+};
+
+
+static njs_extern_t *
+njs_vm_external_add(njs_vm_t *vm, nxt_lvlhsh_t *hash, njs_external_t *external,
+ nxt_uint_t n)
{
nxt_int_t ret;
- njs_extern_t *ext;
+ njs_extern_t *ext, *child;
nxt_lvlhsh_query_t lhq;
do {
- ext = nxt_mem_cache_align(mcp, sizeof(njs_value_t),
- sizeof(njs_extern_t));
+ ext = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_extern_t));
if (nxt_slow_path(ext == NULL)) {
- return NXT_ERROR;
- }
-
- ext->name.length = external->name.length;
- ext->name.start = nxt_mem_cache_alloc(mcp, external->name.length);
- if (nxt_slow_path(ext->name.start == NULL)) {
- return NXT_ERROR;
+ return NULL;
}
- memcpy(ext->name.start, external->name.start, external->name.length);
-
- ext->value.type = NJS_EXTERNAL;
- ext->value.data.truth = 1;
- ext->value.data.u.external = ext;
-
- if (external->method != NULL) {
- ext->function = nxt_mem_cache_zalloc(mcp, sizeof(njs_function_t));
- if (nxt_slow_path(ext->function == NULL)) {
- return NXT_ERROR;
- }
-
- ext->function->native = 1;
- ext->function->args_offset = 1;
- ext->function->u.native = external->method;
- }
+ ext->name = external->name;
nxt_lvlhsh_init(&ext->hash);
+
ext->type = external->type;
ext->get = external->get;
ext->set = external->set;
ext->find = external->find;
ext->foreach = external->foreach;
ext->next = external->next;
- ext->object = object;
ext->data = external->data;
- lhq.key_hash = nxt_djb_hash(external->name.start, external->name.length);
- lhq.key = ext->name;
- lhq.replace = 0;
- lhq.value = ext;
- lhq.pool = mcp;
More information about the nginx-devel
mailing list