Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # HG changeset patch
- # User hongzhidao <hongzhidao@gmail.com>
- # Date 1550382736 -28800
- # Node ID 304c90cab85af07248cb80fb1fe6df40101e0011
- # Parent 8c422e42448e23eeacf85cad5f559941fd64a0ca
- Fixed nxt_file_name().
- diff -r 8c422e42448e -r 304c90cab85a nxt/nxt_file.c
- --- a/nxt/nxt_file.c Thu Feb 14 21:19:51 2019 +0300
- +++ b/nxt/nxt_file.c Sun Feb 17 13:52:16 2019 +0800
- @@ -16,18 +16,19 @@
- void
- nxt_file_name(nxt_str_t *name, char *path)
- {
- - char *p;
- + char *p, *last;
- size_t length;
- length = strlen(path);
- + last = path;
- for (p = path + length; p >= path; p--) {
- if (*p == '/') {
- - p++;
- + last = p + 1;
- break;
- }
- }
- - name->start = (u_char *) p;
- - name->length = length - (p - path);
- + name->start = (u_char *) last;
- + name->length = length - (last - path);
- }
- # HG changeset patch
- # User hongzhidao <hongzhidao@gmail.com>
- # Date 1550382773 -28800
- # Node ID 9c17b088408cc2c8f32d706972ef09d10d713d1e
- # Parent 304c90cab85af07248cb80fb1fe6df40101e0011
- Style.
- diff -r 304c90cab85a -r 9c17b088408c njs/njs.c
- --- a/njs/njs.c Sun Feb 17 13:52:16 2019 +0800
- +++ b/njs/njs.c Sun Feb 17 13:52:53 2019 +0800
- @@ -10,8 +10,6 @@
- static nxt_int_t njs_vm_init(njs_vm_t *vm);
- -static nxt_int_t njs_vm_invoke(njs_vm_t *vm, njs_function_t *function,
- - const njs_value_t *args, nxt_uint_t nargs, njs_index_t retval);
- static nxt_int_t njs_vm_handle_events(njs_vm_t *vm);
- @@ -218,20 +216,20 @@ njs_vm_destroy(njs_vm_t *vm)
- nxt_int_t
- njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end)
- {
- - nxt_int_t ret;
- + nxt_int_t ret;
- njs_lexer_t *lexer;
- njs_parser_t *parser, *prev;
- - njs_generator_t *generator;
- + njs_generator_t generator;
- +
- + if (vm->parser != NULL && !vm->options.accumulative) {
- + return NJS_ERROR;
- + }
- parser = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_parser_t));
- if (nxt_slow_path(parser == NULL)) {
- return NJS_ERROR;
- }
- - if (vm->parser != NULL && !vm->options.accumulative) {
- - return NJS_ERROR;
- - }
- -
- prev = vm->parser;
- vm->parser = parser;
- @@ -271,24 +269,16 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
- */
- vm->code = NULL;
- - generator = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t),
- - sizeof(njs_generator_t));
- + nxt_memzero(&generator, sizeof(njs_generator_t));
- - if (nxt_slow_path(generator == NULL)) {
- - goto fail;
- - }
- -
- - nxt_memzero(generator, sizeof(njs_generator_t));
- -
- - ret = njs_generate_scope(vm, generator, parser->scope);
- + ret = njs_generate_scope(vm, &generator, parser->scope);
- if (nxt_slow_path(ret != NXT_OK)) {
- goto fail;
- }
- - vm->current = generator->code_start;
- -
- - vm->global_scope = generator->local_scope;
- - vm->scope_size = generator->scope_size;
- + vm->current = generator.code_start;
- + vm->global_scope = generator.local_scope;
- + vm->scope_size = generator.scope_size;
- vm->variables_hash = parser->scope->variables;
- @@ -458,11 +448,11 @@ nxt_int_t
- njs_vm_call(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args,
- nxt_uint_t nargs)
- {
- - return njs_vm_invoke(vm, function, args, nargs, NJS_INDEX_GLOBAL_RETVAL);
- + return njs_vm_invoke(vm, function, args, nargs, NJS_INDEX_GLOBAL_RETVAL);
- }
- -static nxt_int_t
- +nxt_int_t
- njs_vm_invoke(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args,
- nxt_uint_t nargs, njs_index_t retval)
- {
- diff -r 304c90cab85a -r 9c17b088408c njs/njs.h
- --- a/njs/njs.h Sun Feb 17 13:52:16 2019 +0800
- +++ b/njs/njs.h Sun Feb 17 13:52:53 2019 +0800
- @@ -193,6 +193,8 @@ NXT_EXPORT nxt_int_t njs_vm_posted(njs_v
- */
- NXT_EXPORT nxt_int_t njs_vm_call(njs_vm_t *vm, njs_function_t *function,
- const njs_value_t *args, nxt_uint_t nargs);
- +NXT_EXPORT nxt_int_t njs_vm_invoke(njs_vm_t *vm, njs_function_t *function,
- + const njs_value_t *args, nxt_uint_t nargs, njs_index_t retval);
- /*
- * Runs posted events.
- diff -r 304c90cab85a -r 9c17b088408c njs/njs_generator.c
- --- a/njs/njs_generator.c Sun Feb 17 13:52:16 2019 +0800
- +++ b/njs/njs_generator.c Sun Feb 17 13:52:53 2019 +0800
- @@ -2282,19 +2282,13 @@ njs_generate_function_scope(njs_vm_t *vm
- size_t size;
- nxt_int_t ret;
- nxt_array_t *closure;
- - njs_generator_t *generator;
- -
- - generator = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t),
- - sizeof(njs_generator_t));
- - if (nxt_slow_path(generator == NULL)) {
- - return NXT_ERROR;
- - }
- -
- - nxt_memzero(generator, sizeof(njs_generator_t));
- + njs_generator_t generator;
- node = node->right;
- - ret = njs_generate_scope(vm, generator, node->scope);
- + nxt_memzero(&generator, sizeof(njs_generator_t));
- +
- + ret = njs_generate_scope(vm, &generator, node->scope);
- if (nxt_fast_path(ret == NXT_OK)) {
- size = 0;
- @@ -2309,16 +2303,13 @@ njs_generate_function_scope(njs_vm_t *vm
- lambda->closure_size = size;
- lambda->nesting = node->scope->nesting;
- - lambda->arguments_object = generator->arguments_object;
- -
- - lambda->local_size = generator->scope_size;
- - lambda->local_scope = generator->local_scope;
- -
- - lambda->start = generator->code_start;
- + lambda->arguments_object = generator.arguments_object;
- +
- + lambda->start = generator.code_start;
- + lambda->local_size = generator.scope_size;
- + lambda->local_scope = generator.local_scope;
- }
- - nxt_mp_free(vm->mem_pool, generator);
- -
- return ret;
- }
- diff -r 304c90cab85a -r 9c17b088408c njs/njs_parser.c
- --- a/njs/njs_parser.c Sun Feb 17 13:52:16 2019 +0800
- +++ b/njs/njs_parser.c Sun Feb 17 13:52:53 2019 +0800
- @@ -167,6 +167,7 @@ njs_parser_scope_begin(njs_vm_t *vm, njs
- nxt_int_t ret;
- nxt_uint_t nesting;
- nxt_array_t *values;
- + njs_lexer_t *lexer;
- njs_parser_scope_t *scope, *parent;
- nesting = 0;
- @@ -232,8 +233,10 @@ njs_parser_scope_begin(njs_vm_t *vm, njs
- scope->values[0] = values;
- scope->values[1] = NULL;
- - if (parser->lexer->file.start != NULL) {
- - ret = njs_name_copy(vm, &scope->file, &parser->lexer->file);
- + lexer = parser->lexer;
- +
- + if (lexer->file.start != NULL) {
- + ret = njs_name_copy(vm, &scope->file, &lexer->file);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NXT_ERROR;
- }
- @@ -2178,11 +2181,7 @@ njs_parser_builtin(njs_vm_t *vm, njs_par
- njs_variable_t *var;
- njs_parser_scope_t *scope;
- - scope = parser->scope;
- -
- - while (scope->type != NJS_SCOPE_GLOBAL) {
- - scope = scope->parent;
- - }
- + scope = njs_parser_global_scope(vm);
- var = njs_variable_add(vm, scope, name, hash, NJS_VARIABLE_VAR);
- if (nxt_slow_path(var == NULL)) {
- diff -r 304c90cab85a -r 9c17b088408c njs/njs_parser.h
- --- a/njs/njs_parser.h Sun Feb 17 13:52:16 2019 +0800
- +++ b/njs/njs_parser.h Sun Feb 17 13:52:53 2019 +0800
- @@ -360,6 +360,21 @@ njs_parser_node_new(njs_vm_t *vm, njs_pa
- }
- +nxt_inline njs_parser_scope_t *
- +njs_parser_global_scope(njs_vm_t *vm)
- +{
- + njs_parser_scope_t *scope;
- +
- + scope = vm->parser->scope;
- +
- + while (scope->type != NJS_SCOPE_GLOBAL) {
- + scope = scope->parent;
- + }
- +
- + return scope;
- +}
- +
- +
- extern const nxt_lvlhsh_proto_t njs_keyword_hash_proto;
- diff -r 304c90cab85a -r 9c17b088408c njs/njs_variable.c
- --- a/njs/njs_variable.c Sun Feb 17 13:52:16 2019 +0800
- +++ b/njs/njs_variable.c Sun Feb 17 13:52:53 2019 +0800
- @@ -144,7 +144,7 @@ njs_variable_reference(njs_vm_t *vm, njs
- ret = nxt_lvlhsh_insert(&scope->references, &lhq);
- - if (nxt_slow_path(ret != NXT_ERROR)) {
- + if (nxt_fast_path(ret != NXT_ERROR)) {
- ret = NXT_OK;
- }
- }
- @@ -356,7 +356,7 @@ njs_variable_reference_resolve(njs_vm_t
- njs_parser_scope_t *node_scope)
- {
- nxt_lvlhsh_query_t lhq;
- - njs_parser_scope_t *scope, *parent, *previous;
- + njs_parser_scope_t *scope, *previous;
- lhq.key_hash = vr->hash;
- lhq.key = vr->name;
- @@ -395,9 +395,7 @@ njs_variable_reference_resolve(njs_vm_t
- return NXT_OK;
- }
- - parent = scope->parent;
- -
- - if (parent == NULL) {
- + if (scope->parent == NULL) {
- /* A global scope. */
- vr->scope = scope;
- @@ -405,7 +403,7 @@ njs_variable_reference_resolve(njs_vm_t
- }
- previous = scope;
- - scope = parent;
- + scope = scope->parent;
- }
- }
- @@ -495,7 +493,7 @@ njs_name_copy(njs_vm_t *vm, nxt_str_t *d
- dst->start = nxt_mp_alloc(vm->mem_pool, src->length);
- - if (nxt_slow_path(dst->start != NULL)) {
- + if (nxt_fast_path(dst->start != NULL)) {
- (void) memcpy(dst->start, src->start, src->length);
- return NXT_OK;
- # HG changeset patch
- # User hongzhidao <hongzhidao@gmail.com>
- # Date 1550383270 -28800
- # Node ID fae8a5305fdb5563f8b6e3d0600625b6c1185bca
- # Parent 9c17b088408cc2c8f32d706972ef09d10d713d1e
- Introduced module.
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs.c
- --- a/njs/njs.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs.c Sun Feb 17 14:01:10 2019 +0800
- @@ -6,6 +6,7 @@
- #include <njs_core.h>
- #include <njs_regexp.h>
- +#include <njs_module.h>
- #include <string.h>
- @@ -330,6 +331,8 @@ njs_vm_clone(njs_vm_t *vm, njs_external_
- nvm->variables_hash = vm->variables_hash;
- nvm->values_hash = vm->values_hash;
- +
- + nvm->modules = vm->modules;
- nvm->modules_hash = vm->modules_hash;
- nvm->externals_hash = vm->externals_hash;
- @@ -578,6 +581,11 @@ njs_vm_start(njs_vm_t *vm)
- {
- njs_ret_t ret;
- + ret = njs_module_load(vm);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return ret;
- + }
- +
- ret = njs_vmcode_interpreter(vm);
- if (ret == NJS_STOP) {
- @@ -626,6 +634,30 @@ njs_vm_handle_events(njs_vm_t *vm)
- }
- +nxt_int_t
- +njs_vm_add_path(njs_vm_t *vm, nxt_str_t *path)
- +{
- + nxt_str_t *item;
- +
- + if (vm->paths == NULL) {
- + vm->paths = nxt_array_create(4, sizeof(nxt_str_t),
- + &njs_array_mem_proto, vm->mem_pool);
- + if (nxt_slow_path(vm->paths == NULL)) {
- + return NXT_ERROR;
- + }
- + }
- +
- + item = nxt_array_add(vm->paths, &njs_array_mem_proto, vm->mem_pool);
- + if (nxt_slow_path(item == NULL)) {
- + return NXT_ERROR;
- + }
- +
- + *item = *path;
- +
- + return NXT_OK;
- +}
- +
- +
- nxt_noinline njs_value_t *
- njs_vm_retval(njs_vm_t *vm)
- {
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs.h
- --- a/njs/njs.h Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs.h Sun Feb 17 14:01:10 2019 +0800
- @@ -215,6 +215,8 @@ NXT_EXPORT nxt_int_t njs_vm_run(njs_vm_t
- */
- NXT_EXPORT nxt_int_t njs_vm_start(njs_vm_t *vm);
- +NXT_EXPORT nxt_int_t njs_vm_add_path(njs_vm_t *vm, nxt_str_t *path);
- +
- NXT_EXPORT const njs_extern_t *njs_vm_external_prototype(njs_vm_t *vm,
- njs_external_t *external);
- NXT_EXPORT nxt_int_t njs_vm_external_create(njs_vm_t *vm,
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_builtin.c
- --- a/njs/njs_builtin.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_builtin.c Sun Feb 17 14:01:10 2019 +0800
- @@ -294,6 +294,8 @@ njs_builtin_objects_create(njs_vm_t *vm)
- return NJS_ERROR;
- }
- + module->function.native = 1;
- +
- ret = njs_object_hash_create(vm, &module->object.shared_hash,
- obj->properties, obj->items);
- if (nxt_slow_path(ret != NXT_OK)) {
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_generator.c
- --- a/njs/njs_generator.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_generator.c Sun Feb 17 14:01:10 2019 +0800
- @@ -6,6 +6,7 @@
- */
- #include <njs_core.h>
- +#include <njs_module.h>
- #include <string.h>
- @@ -142,6 +143,10 @@ static nxt_int_t njs_generate_try_statem
- njs_generator_t *generator, njs_parser_node_t *node);
- static nxt_int_t njs_generate_throw_statement(njs_vm_t *vm,
- njs_generator_t *generator, njs_parser_node_t *node);
- +static nxt_int_t njs_generate_import_statement(njs_vm_t *vm,
- + njs_generator_t *generator, njs_parser_node_t *node);
- +static nxt_int_t njs_generate_export_statement(njs_vm_t *vm,
- + njs_generator_t *generator, njs_parser_node_t *node);
- static nxt_noinline njs_index_t njs_generate_dest_index(njs_vm_t *vm,
- njs_generator_t *generator, njs_parser_node_t *node);
- static nxt_noinline njs_index_t
- @@ -430,6 +435,12 @@ njs_generator(njs_vm_t *vm, njs_generato
- case NJS_TOKEN_THROW:
- return njs_generate_throw_statement(vm, generator, node);
- + case NJS_TOKEN_IMPORT:
- + return njs_generate_import_statement(vm, generator, node);
- +
- + case NJS_TOKEN_EXPORT:
- + return njs_generate_export_statement(vm, generator, node);
- +
- default:
- nxt_thread_log_debug("unknown token: %d", node->token);
- njs_syntax_error(vm, "unknown token");
- @@ -2975,6 +2986,72 @@ njs_generate_throw_statement(njs_vm_t *v
- }
- +static nxt_int_t
- +njs_generate_import_statement(njs_vm_t *vm, njs_generator_t *generator,
- + njs_parser_node_t *node)
- +{
- + nxt_int_t ret;
- + njs_index_t index;
- + njs_module_t *module;
- + njs_parser_node_t *lvalue, *expr;
- + njs_vmcode_object_copy_t *copy;
- +
- + lvalue = node->left;
- + expr = node->right;
- +
- + index = njs_variable_index(vm, lvalue);
- + if (nxt_slow_path(index == NJS_INDEX_ERROR)) {
- + return NXT_ERROR;
- + }
- +
- + if (expr->left != NULL) {
- + ret = njs_generator(vm, generator, expr->left);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return ret;
- + }
- + }
- +
- + module = (njs_module_t *) expr->index;
- +
- + njs_generate_code(generator, njs_vmcode_object_copy_t, copy);
- + copy->code.operation = njs_vmcode_object_copy;
- + copy->code.operands = NJS_VMCODE_2OPERANDS;
- + copy->code.retval = NJS_VMCODE_RETVAL;
- + copy->retval = index;
- + copy->object = module->index;
- +
- + return NXT_OK;
- +}
- +
- +
- +static nxt_int_t
- +njs_generate_export_statement(njs_vm_t *vm, njs_generator_t *generator,
- + njs_parser_node_t *node)
- +{
- + nxt_int_t ret;
- + njs_parser_node_t *obj;
- + njs_vmcode_return_t *code;
- +
- + obj = node->right;
- +
- + ret = njs_generator(vm, generator, obj);
- +
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return ret;
- + }
- +
- + njs_generate_code(generator, njs_vmcode_return_t, code);
- + code->code.operation = njs_vmcode_return;
- + code->code.operands = NJS_VMCODE_1OPERAND;
- + code->code.retval = NJS_VMCODE_NO_RETVAL;
- +
- + code->retval = obj->index;
- + node->index = obj->index;
- +
- + return NXT_OK;
- +}
- +
- +
- static nxt_noinline njs_index_t
- njs_generate_dest_index(njs_vm_t *vm, njs_generator_t *generator,
- njs_parser_node_t *node)
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_lexer_keyword.c
- --- a/njs/njs_lexer_keyword.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_lexer_keyword.c Sun Feb 17 14:01:10 2019 +0800
- @@ -93,6 +93,11 @@ static const njs_keyword_t njs_keywords
- { nxt_string("setImmediate"), NJS_TOKEN_SET_IMMEDIATE, 0 },
- { nxt_string("clearTimeout"), NJS_TOKEN_CLEAR_TIMEOUT, 0 },
- + /* Module. */
- + { nxt_string("import"), NJS_TOKEN_IMPORT, 0 },
- + { nxt_string("from"), NJS_TOKEN_FROM, 0 },
- + { nxt_string("export"), NJS_TOKEN_EXPORT, 0 },
- +
- /* Reserved words. */
- { nxt_string("await"), NJS_TOKEN_RESERVED, 0 },
- @@ -100,10 +105,8 @@ static const njs_keyword_t njs_keywords
- { nxt_string("const"), NJS_TOKEN_RESERVED, 0 },
- { nxt_string("debugger"), NJS_TOKEN_RESERVED, 0 },
- { nxt_string("enum"), NJS_TOKEN_RESERVED, 0 },
- - { nxt_string("export"), NJS_TOKEN_RESERVED, 0 },
- { nxt_string("extends"), NJS_TOKEN_RESERVED, 0 },
- { nxt_string("implements"), NJS_TOKEN_RESERVED, 0 },
- - { nxt_string("import"), NJS_TOKEN_RESERVED, 0 },
- { nxt_string("interface"), NJS_TOKEN_RESERVED, 0 },
- { nxt_string("let"), NJS_TOKEN_RESERVED, 0 },
- { nxt_string("package"), NJS_TOKEN_RESERVED, 0 },
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_module.c
- --- a/njs/njs_module.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_module.c Sun Feb 17 14:01:10 2019 +0800
- @@ -8,6 +8,377 @@
- #include <njs_module.h>
- #include <string.h>
- #include <stdio.h>
- +#include <errno.h>
- +#include <fcntl.h>
- +#include <string.h>
- +#include <stdlib.h>
- +#include <sys/stat.h>
- +#include <limits.h>
- +
- +
- +typedef struct {
- + int fd;
- + nxt_str_t *name;
- + nxt_str_t file;
- + nxt_bool_t relative;
- +} njs_module_info_t;
- +
- +
- +static nxt_int_t njs_module_lookup(njs_vm_t *vm, nxt_str_t *cwd,
- + njs_module_info_t *info);
- +static nxt_int_t njs_module_absolute_path(njs_vm_t *vm, njs_module_info_t *info);
- +static nxt_int_t njs_module_relative_path(njs_vm_t *vm, nxt_str_t *path,
- + njs_module_info_t *info);
- +static nxt_int_t njs_module_read(njs_vm_t *vm, int fd, nxt_str_t *body);
- +static njs_module_t *njs_module_find(njs_vm_t *vm, nxt_str_t *name);
- +static njs_module_t *njs_module_add(njs_vm_t *vm, nxt_str_t *name);
- +static nxt_int_t njs_module_insert(njs_vm_t *vm, njs_module_t *module);
- +
- +
- +nxt_int_t
- +njs_module_load(njs_vm_t *vm)
- +{
- + nxt_int_t ret;
- + nxt_uint_t i;
- + njs_value_t *value;
- + njs_module_t **item, *module;
- +
- + if (vm->modules == NULL) {
- + return NXT_OK;
- + }
- +
- + item = vm->modules->start;
- +
- + for (i = 0; i < vm->modules->items; i++) {
- + module = *item;
- +
- + if (module->function.native) {
- + value = njs_vmcode_operand(vm, module->index);
- + value->data.u.object = &module->object;
- + value->type = NJS_OBJECT;
- + value->data.truth = 1;
- +
- + } else {
- + ret = njs_vm_invoke(vm, &module->function, NULL, 0, module->index);
- + if (ret == NXT_ERROR) {
- + return NXT_ERROR;
- + }
- + }
- +
- + item++;
- + }
- +
- + return NXT_OK;
- +}
- +
- +
- +nxt_int_t
- +njs_parser_module(njs_vm_t *vm, njs_parser_t *parser)
- +{
- + u_char ch;
- + nxt_int_t ret;
- + nxt_str_t *name, body;
- + nxt_bool_t native, relative;
- + njs_lexer_t *prev, lexer;
- + njs_token_t token;
- + njs_module_t *module;
- + njs_parser_node_t *node;
- + njs_module_info_t info;
- +
- + name = &parser->lexer->text;
- +
- + parser->node = NULL;
- +
- + native = 1;
- + relative = 0;
- +
- + ch = name->start[0];
- +
- + if (ch == '/' || ch == '.') {
- + native = 0;
- + relative = (ch != '/') ? 1 : 0;
- + }
- +
- + module = njs_module_find(vm, name);
- + if (module != NULL) {
- + goto found;
- + }
- +
- + if (native && module == NULL) {
- + goto not_found;
- + }
- +
- + if (vm->options.sandbox) {
- + goto not_found;
- + }
- +
- + /* Search non-native module. */
- +
- + prev = parser->lexer;
- +
- + nxt_memzero(&info, sizeof(njs_module_info_t));
- +
- + info.relative = relative;
- + info.name = name;
- +
- + ret = njs_module_lookup(vm, &parser->scope->cwd, &info);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + goto fail;
- + }
- +
- + if (nxt_strncmp(prev->file.start, info.file.start, prev->file.length)
- + == 0)
- + {
- + njs_parser_syntax_error(vm, parser, "Cannot import itself \"%V\"", name);
- + return NXT_ERROR;
- + }
- +
- + nxt_memzero(&body, sizeof(nxt_str_t));
- +
- + ret = njs_module_read(vm, info.fd, &body);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + goto fail;
- + }
- +
- + nxt_memzero(&lexer, sizeof(njs_lexer_t));
- +
- + lexer.file = info.file;
- + lexer.start = body.start;
- + lexer.end = body.start + body.length;
- + lexer.line = 1;
- + lexer.keywords_hash = prev->keywords_hash;
- +
- + parser->lexer = &lexer;
- +
- + token = njs_parser_token(parser);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + goto fail;
- + }
- +
- + token = njs_parser_module_lambda(vm, parser);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + goto fail;
- + }
- +
- + /* The token is NJS_TOKEN_END here, needn't check. */
- +
- + module = njs_module_add(vm, name);
- + if (nxt_slow_path(module == NULL)) {
- + goto fail;
- + }
- +
- + module->function.u.lambda = parser->node->u.value.data.u.lambda;
- +
- + nxt_mp_free(vm->mem_pool, body.start);
- +
- + parser->lexer = prev;
- +
- +found:
- +
- + node = njs_parser_node_new(vm, parser, 0);
- + if (nxt_slow_path(node == NULL)) {
- + return NXT_ERROR;
- + }
- +
- + node->left = parser->node;
- +
- + if (module->index == 0) {
- + ret = njs_module_insert(vm, module);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return NXT_ERROR;
- + }
- + }
- +
- + node->index = (njs_index_t) module;
- +
- + parser->node = node;
- +
- + return NXT_OK;
- +
- +not_found:
- +
- + njs_parser_syntax_error(vm, parser, "Cannot find module \"%V\"", name);
- +
- + return NXT_ERROR;
- +
- +fail:
- +
- + if (body.start != NULL) {
- + nxt_mp_free(vm->mem_pool, body.start);
- + }
- +
- + njs_parser_syntax_error(vm, parser, "Cannot find module \"%V\"", name);
- +
- + parser->lexer = prev;
- +
- + return NXT_ERROR;
- +}
- +
- +
- +static nxt_int_t
- +njs_module_lookup(njs_vm_t *vm, nxt_str_t *cwd, njs_module_info_t *info)
- +{
- + nxt_int_t ret;
- + nxt_str_t *path;
- + nxt_uint_t i;
- +
- + if (!info->relative) {
- + return njs_module_absolute_path(vm, info);
- + }
- +
- + ret = njs_module_relative_path(vm, cwd, info);
- + if (ret == NXT_OK) {
- + return ret;
- + }
- +
- + if (vm->paths == NULL) {
- + return NXT_DECLINED;
- + }
- +
- + path = vm->paths->start;
- +
- + for (i = 0; i < vm->paths->items; i++) {
- + ret = njs_module_relative_path(vm, path, info);
- + if (ret == NXT_OK) {
- + return ret;
- + }
- +
- + path++;
- + }
- +
- + return NXT_DECLINED;
- +}
- +
- +
- +static nxt_int_t
- +njs_module_absolute_path(njs_vm_t *vm, njs_module_info_t *info)
- +{
- + nxt_str_t file;
- +
- + file.length = info->name->length + 1;
- + file.start = nxt_mp_alloc(vm->mem_pool, file.length);
- + if (nxt_slow_path(file.start == NULL)) {
- + return NXT_ERROR;
- + }
- +
- + memcpy(file.start, info->name->start, info->name->length);
- + *(file.start + file.length) = '\0';
- +
- + file.length--;
- +
- + info->fd = open((char *) file.start, O_RDONLY);
- + if (info->fd == -1) {
- + nxt_mp_free(vm->mem_pool, file.start);
- + return NXT_DECLINED;
- + }
- +
- + info->file = file;
- +
- + return NXT_OK;
- +}
- +
- +
- +static nxt_int_t
- +njs_module_relative_path(njs_vm_t *vm, nxt_str_t *path, njs_module_info_t *info)
- +{
- + u_char *p;
- + nxt_str_t file;
- +
- + file.length = path->length;
- +
- + if (path->start[path->length - 1] != '/') {
- + file.length++;
- + }
- +
- + file.length += info->name->length + 1;
- +
- + file.start = nxt_mp_alloc(vm->mem_pool, file.length);
- + if (nxt_slow_path(file.start == NULL)) {
- + return NXT_ERROR;
- + }
- +
- + p = file.start;
- +
- + p = nxt_cpymem(p, path->start, path->length);
- +
- + if (path->start[path->length - 1] != '/') {
- + *p++ = '/';
- + }
- +
- + p = nxt_cpymem(p, info->name->start, info->name->length);
- + *p = '\0';
- +
- + file.length--;
- +
- + info->fd = open((char *) file.start, O_RDONLY);
- + if (info->fd == -1) {
- + nxt_mp_free(vm->mem_pool, file.start);
- + return NXT_DECLINED;
- + }
- +
- + info->file = file;
- +
- + return NXT_OK;
- +}
- +
- +
- +#define NJS_MODULE_START "function() {"
- +#define NJS_MODULE_END "}"
- +
- +static nxt_int_t
- +njs_module_read(njs_vm_t *vm, int fd, nxt_str_t *body)
- +{
- + u_char *p;
- + ssize_t n;
- + struct stat sb;
- +
- + if (fstat(fd, &sb) == -1) {
- + goto fail;
- + }
- +
- + body->length = nxt_length(NJS_MODULE_START);
- +
- + if (S_ISREG(sb.st_mode) && sb.st_size) {
- + body->length += sb.st_size;
- + }
- +
- + body->length += nxt_length(NJS_MODULE_END);
- +
- + body->start = nxt_mp_alloc(vm->mem_pool, body->length);
- + if (body->start == NULL) {
- + goto fail;
- + }
- +
- + p = nxt_cpymem(body->start, NJS_MODULE_START, nxt_length(NJS_MODULE_START));
- +
- + n = read(fd, p, sb.st_size);
- +
- + if (n < 0) {
- + goto fail;
- + }
- +
- + if (n != sb.st_size) {
- + goto fail;
- + }
- +
- + p += n;
- +
- + memcpy(p, NJS_MODULE_END, nxt_length(NJS_MODULE_END));
- +
- + close(fd);
- +
- + return NXT_OK;
- +
- +fail:
- +
- + if (body->start != NULL) {
- + nxt_mp_free(vm->mem_pool, body->start);
- + }
- +
- + close(fd);
- +
- + return NXT_ERROR;
- +}
- static nxt_int_t
- @@ -36,6 +407,98 @@ const nxt_lvlhsh_proto_t njs_modules_ha
- };
- +static njs_module_t *
- +njs_module_find(njs_vm_t *vm, nxt_str_t *name)
- +{
- + nxt_lvlhsh_query_t lhq;
- +
- + lhq.key = *name;
- + lhq.key_hash = nxt_djb_hash(name->start, name->length);;
- + lhq.proto = &njs_modules_hash_proto;
- +
- + if (nxt_lvlhsh_find(&vm->modules_hash, &lhq) == NXT_OK) {
- + return lhq.value;
- + }
- +
- + return NULL;
- +}
- +
- +
- +static njs_module_t *
- +njs_module_add(njs_vm_t *vm, nxt_str_t *name)
- +{
- + nxt_int_t ret;
- + njs_module_t *module;
- + nxt_lvlhsh_query_t lhq;
- +
- + module = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_module_t));
- + if (nxt_slow_path(module == NULL)) {
- + njs_memory_error(vm);
- + return NULL;
- + }
- +
- + ret = njs_name_copy(vm, &module->name, name);
- +
- + if (nxt_fast_path(ret != NXT_OK)) {
- + nxt_mp_free(vm->mem_pool, module);
- + return NULL;
- + }
- +
- + lhq.replace = 0;
- + lhq.key = *name;
- + lhq.key_hash = nxt_djb_hash(name->start, name->length);
- + lhq.value = module;
- + lhq.pool = vm->mem_pool;
- + lhq.proto = &njs_modules_hash_proto;
- +
- + ret = nxt_lvlhsh_insert(&vm->modules_hash, &lhq);
- +
- + if (nxt_fast_path(ret == NXT_OK)) {
- + return module;
- + }
- +
- + nxt_mp_free(vm->mem_pool, module->name.start);
- + nxt_mp_free(vm->mem_pool, module);
- +
- + njs_type_error(vm, "lvlhsh insert failed");
- +
- + return NULL;
- +}
- +
- +
- +static nxt_int_t
- +njs_module_insert(njs_vm_t *vm, njs_module_t *module)
- +{
- + njs_module_t **value;
- + njs_parser_scope_t *scope;
- +
- + scope = njs_parser_global_scope(vm);
- +
- + module->index = njs_scope_next_index(vm, scope, NJS_SCOPE_INDEX_LOCAL,
- + &njs_value_void);
- + if (nxt_slow_path(module->index == NJS_INDEX_ERROR)) {
- + return NXT_ERROR;
- + }
- +
- + if (vm->modules == NULL) {
- + vm->modules = nxt_array_create(4, sizeof(njs_module_t *),
- + &njs_array_mem_proto, vm->mem_pool);
- + if (nxt_slow_path(vm->modules == NULL)) {
- + return NXT_OK;
- + }
- + }
- +
- + value = nxt_array_add(vm->modules, &njs_array_mem_proto, vm->mem_pool);
- + if (nxt_slow_path(value == NULL)) {
- + return NXT_ERROR;
- + }
- +
- + *value = module;
- +
- + return NXT_OK;
- +}
- +
- +
- njs_ret_t njs_module_require(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused)
- {
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_module.h
- --- a/njs/njs_module.h Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_module.h Sun Feb 17 14:01:10 2019 +0800
- @@ -11,9 +11,13 @@
- typedef struct {
- nxt_str_t name;
- njs_object_t object;
- + njs_index_t index;
- + njs_function_t function;
- } njs_module_t;
- +nxt_int_t njs_module_load(njs_vm_t *vm);
- +nxt_int_t njs_parser_module(njs_vm_t *vm, njs_parser_t *parser);
- njs_ret_t njs_module_require(njs_vm_t *vm, njs_value_t *args,
- nxt_uint_t nargs, njs_index_t unused);
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_parser.c
- --- a/njs/njs_parser.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_parser.c Sun Feb 17 14:01:10 2019 +0800
- @@ -6,6 +6,7 @@
- #include <njs_core.h>
- #include <njs_regexp.h>
- +#include <njs_module.h>
- #include <string.h>
- #include <stdio.h>
- @@ -50,6 +51,13 @@ static njs_token_t njs_parser_try_statem
- static njs_token_t njs_parser_try_block(njs_vm_t *vm, njs_parser_t *parser);
- static njs_token_t njs_parser_throw_statement(njs_vm_t *vm,
- njs_parser_t *parser);
- +static njs_token_t njs_parser_import_statement(njs_vm_t *vm,
- + njs_parser_t *parser);
- +static njs_token_t njs_parser_export_statement(njs_vm_t *vm,
- + njs_parser_t *parser);
- +static nxt_int_t njs_parser_import_hoist(njs_vm_t *vm, njs_parser_t *parser,
- + njs_parser_node_t *new_node);
- +static nxt_int_t njs_parser_export_sink(njs_vm_t *vm, njs_parser_t *parser);
- static njs_token_t njs_parser_grouping_expression(njs_vm_t *vm,
- njs_parser_t *parser);
- static njs_parser_node_t *njs_parser_reference(njs_vm_t *vm,
- @@ -164,7 +172,6 @@ njs_parser(njs_vm_t *vm, njs_parser_t *p
- static njs_ret_t
- njs_parser_scope_begin(njs_vm_t *vm, njs_parser_t *parser, njs_scope_t type)
- {
- - nxt_int_t ret;
- nxt_uint_t nesting;
- nxt_array_t *values;
- njs_lexer_t *lexer;
- @@ -236,10 +243,7 @@ njs_parser_scope_begin(njs_vm_t *vm, njs
- lexer = parser->lexer;
- if (lexer->file.start != NULL) {
- - ret = njs_name_copy(vm, &scope->file, &lexer->file);
- - if (nxt_slow_path(ret != NXT_OK)) {
- - return NXT_ERROR;
- - }
- + nxt_file_resolve(&scope->cwd, &scope->file, &lexer->file);
- }
- parent = parser->scope;
- @@ -281,30 +285,28 @@ njs_parser_statement_chain(njs_vm_t *vm,
- token = njs_parser_statement(vm, parser, token);
- - if (nxt_fast_path(token > NJS_TOKEN_ILLEGAL)) {
- -
- - if (parser->node != NULL) {
- - /* The statement is not empty block or just semicolon. */
- -
- - node = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
- - if (nxt_slow_path(node == NULL)) {
- - return NJS_TOKEN_ERROR;
- - }
- -
- - node->left = last;
- - node->right = parser->node;
- - *dest = node;
- -
- - while (token == NJS_TOKEN_SEMICOLON) {
- - token = njs_parser_token(parser);
- - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- - break;
- - }
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return njs_parser_unexpected_token(vm, parser, token);
- + }
- +
- + if (parser->node != NULL) {
- + /* The statement is not empty block or just semicolon. */
- +
- + node = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
- + if (nxt_slow_path(node == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + node->left = last;
- + node->right = parser->node;
- + *dest = node;
- +
- + while (token == NJS_TOKEN_SEMICOLON) {
- + token = njs_parser_token(parser);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + break;
- }
- }
- -
- - } else if (!njs_is_error(&vm->retval)) {
- - (void) njs_parser_unexpected_token(vm, parser, token);
- }
- return token;
- @@ -340,6 +342,12 @@ njs_parser_statement(njs_vm_t *vm, njs_p
- case NJS_TOKEN_TRY:
- return njs_parser_try_statement(vm, parser);
- + case NJS_TOKEN_IMPORT:
- + return njs_parser_import_statement(vm, parser);
- +
- + case NJS_TOKEN_EXPORT:
- + return njs_parser_export_statement(vm, parser);
- +
- case NJS_TOKEN_SEMICOLON:
- return njs_parser_token(parser);
- @@ -644,6 +652,37 @@ njs_parser_function_expression(njs_vm_t
- static njs_token_t
- +njs_parser_lambda(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
- +{
- + token = njs_parser_token(parser);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + if (nxt_slow_path(token != NJS_TOKEN_OPEN_BRACE)) {
- + return NJS_TOKEN_ILLEGAL;
- + }
- +
- + token = njs_parser_token(parser);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + parser->node = NULL;
- +
- + while (token != NJS_TOKEN_CLOSE_BRACE) {
- + token = njs_parser_statement_chain(vm, parser, token,
- + &njs_parser_chain_top(parser));
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- + }
- +
- + return njs_parser_token(parser);
- +}
- +
- +
- +static njs_token_t
- njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser,
- njs_function_lambda_t *lambda, njs_token_t token)
- {
- @@ -714,32 +753,9 @@ njs_parser_function_lambda(njs_vm_t *vm,
- lambda->nargs = njs_scope_offset(index) / sizeof(njs_value_t) - 1;
- - token = njs_parser_token(parser);
- - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- - return token;
- - }
- -
- - if (nxt_slow_path(token != NJS_TOKEN_OPEN_BRACE)) {
- - return NJS_TOKEN_ILLEGAL;
- - }
- -
- - token = njs_parser_token(parser);
- - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- - return token;
- - }
- -
- parent = parser->node;
- - parser->node = NULL;
- -
- - while (token != NJS_TOKEN_CLOSE_BRACE) {
- - token = njs_parser_statement_chain(vm, parser, token,
- - &njs_parser_chain_top(parser));
- - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- - return token;
- - }
- - }
- -
- - token = njs_parser_token(parser);
- +
- + token = njs_parser_lambda(vm, parser, token);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
- @@ -801,9 +817,13 @@ njs_parser_return_statement(njs_vm_t *vm
- njs_parser_scope_t *scope;
- for (scope = parser->scope;
- - scope->type != NJS_SCOPE_FUNCTION;
- + scope != NULL;
- scope = scope->parent)
- {
- + if (scope->type == NJS_SCOPE_FUNCTION && !scope->module) {
- + break;
- + }
- +
- if (scope->type == NJS_SCOPE_GLOBAL) {
- njs_parser_syntax_error(vm, parser, "Illegal return statement");
- @@ -1737,6 +1757,300 @@ njs_parser_throw_statement(njs_vm_t *vm,
- static njs_token_t
- +njs_parser_import_statement(njs_vm_t *vm, njs_parser_t *parser)
- +{
- + njs_ret_t ret;
- + njs_token_t token;
- + njs_variable_t *var;
- + njs_parser_node_t *name, *import;
- +
- + if (parser->scope->type != NJS_SCOPE_GLOBAL
- + && !parser->scope->module)
- + {
- + njs_parser_syntax_error(vm, parser, "Illegal import statement");
- +
- + return NXT_ERROR;
- + }
- +
- + token = njs_parser_token(parser);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + if (token != NJS_TOKEN_NAME) {
- + return NJS_TOKEN_ILLEGAL;
- + }
- +
- + var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR);
- + if (nxt_slow_path(var == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + name = njs_parser_node_new(vm, parser, NJS_TOKEN_NAME);
- + if (nxt_slow_path(name == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + ret = njs_parser_variable_reference(vm, parser, name, NJS_DECLARATION);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + token = njs_parser_token(parser);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + token = njs_parser_match(vm, parser, token, NJS_TOKEN_FROM);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + if (token != NJS_TOKEN_STRING) {
- + return NJS_TOKEN_ILLEGAL;
- + }
- +
- + ret = njs_parser_module(vm, parser);
- +
- + token = njs_lexer_token(parser->lexer);
- +
- + switch (token) {
- +
- + case NJS_TOKEN_LINE_END:
- + token = njs_parser_token(parser);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + /* Fall through. */
- +
- + case NJS_TOKEN_SEMICOLON:
- + case NJS_TOKEN_END:
- + break;
- +
- + default:
- + return NJS_TOKEN_ILLEGAL;
- + }
- +
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + import = njs_parser_node_new(vm, parser, NJS_TOKEN_IMPORT);
- + if (nxt_slow_path(import == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + import->left = name;
- + import->right = parser->node;
- +
- + ret = njs_parser_import_hoist(vm, parser, import);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + parser->node = NULL;
- +
- + return token;
- +}
- +
- +
- +njs_token_t
- +njs_parser_module_lambda(njs_vm_t *vm, njs_parser_t *parser)
- +{
- + njs_ret_t ret;
- + njs_token_t token;
- + njs_parser_node_t *node, *parent;
- + njs_function_lambda_t *lambda;
- +
- + node = njs_parser_node_new(vm, parser, NJS_TOKEN_FUNCTION_EXPRESSION);
- + if (nxt_slow_path(node == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + node->token_line = parser->lexer->token_line;
- +
- + token = njs_parser_token(parser);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t));
- + if (nxt_slow_path(lambda == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + node->u.value.data.u.lambda = lambda;
- + parser->node = node;
- +
- + ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + parser->scope->module = 1;
- +
- + token = njs_parser_match(vm, parser, token, NJS_TOKEN_OPEN_PARENTHESIS);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + parent = parser->node;
- +
- + token = njs_parser_lambda(vm, parser, token);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + ret = njs_parser_export_sink(vm, parser);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + parent->right = njs_parser_chain_top(parser);
- +
- + parser->node = parent;
- +
- + njs_parser_scope_end(vm, parser);
- +
- + return token;
- +}
- +
- +
- +static njs_token_t
- +njs_parser_export_statement(njs_vm_t *vm, njs_parser_t *parser)
- +{
- + njs_token_t token;
- + njs_parser_node_t *node;
- +
- + if (!parser->scope->module) {
- + njs_parser_syntax_error(vm, parser, "Illegal export statement");
- +
- + return NXT_ERROR;
- + }
- +
- + node = njs_parser_node_new(vm, parser, NJS_TOKEN_EXPORT);
- + if (nxt_slow_path(node == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + parser->node = node;
- +
- + token = njs_lexer_token(parser->lexer);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + token = njs_parser_match(vm, parser, token, NJS_TOKEN_DEFAULT);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + token = njs_parser_expression(vm, parser, token);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + if (parser->node->token != NJS_TOKEN_OBJECT) {
- + njs_parser_syntax_error(vm, parser, "Illegal export value");
- + return NXT_ERROR;
- + }
- +
- + node->right = parser->node;
- + parser->node = node;
- +
- + return token;
- +}
- +
- +
- +static nxt_int_t
- +njs_parser_import_hoist(njs_vm_t *vm, njs_parser_t *parser,
- + njs_parser_node_t *new_node)
- +{
- + njs_parser_node_t *node, *stmt, **child;
- +
- + child = &njs_parser_chain_top(parser);
- +
- + while (*child != NULL) {
- + node = *child;
- +
- + if (node->right != NULL
- + && node->right->token == NJS_TOKEN_IMPORT)
- + {
- + break;
- + }
- +
- + child = &node->left;
- + }
- +
- + stmt = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
- + if (nxt_slow_path(stmt == NULL)) {
- + return NXT_ERROR;
- + }
- +
- + stmt->left = *child;
- + stmt->right = new_node;
- +
- + *child = stmt;
- +
- + return NXT_OK;
- +}
- +
- +
- +static nxt_int_t
- +njs_parser_export_sink(njs_vm_t *vm, njs_parser_t *parser)
- +{
- + nxt_uint_t n;
- + njs_parser_node_t *node, *prev;
- +
- + for (n = 0, node = njs_parser_chain_top(parser);
- + node != NULL;
- + node = node->left)
- + {
- + if (node->right != NULL
- + && node->right->token == NJS_TOKEN_EXPORT)
- + {
- + n++;
- + }
- + }
- +
- + if (n != 1) {
- + njs_parser_syntax_error(vm, parser,
- + (n == 0) ? "export statement is required."
- + : "Identifier \"default\" has already been declared");
- +
- + return NXT_ERROR;
- + }
- +
- + node = njs_parser_chain_top(parser);
- +
- + if (node->right && node->right->token == NJS_TOKEN_EXPORT) {
- + return NXT_OK;
- + }
- +
- + prev = njs_parser_chain_top(parser);
- +
- + while (prev->left != NULL) {
- + node = prev->left;
- +
- + if (node->right != NULL
- + && node->right->token == NJS_TOKEN_EXPORT)
- + {
- + prev->left = node->left;
- + break;
- + }
- +
- + prev = prev->left;
- + }
- +
- + node->left = njs_parser_chain_top(parser);
- + njs_parser_chain_top_set(parser, node);
- +
- + return NXT_OK;
- +}
- +
- +
- +static njs_token_t
- njs_parser_grouping_expression(njs_vm_t *vm, njs_parser_t *parser)
- {
- njs_token_t token;
- @@ -2737,6 +3051,10 @@ njs_parser_scope_error(njs_vm_t *vm, njs
- u_char *p, *end;
- nxt_str_t *file;
- + if (njs_is_error(&vm->retval)) {
- + return;
- + }
- +
- file = &scope->file;
- p = msg;
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_parser.h
- --- a/njs/njs_parser.h Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_parser.h Sun Feb 17 14:01:10 2019 +0800
- @@ -203,6 +203,10 @@ typedef enum {
- NJS_TOKEN_SET_IMMEDIATE,
- NJS_TOKEN_CLEAR_TIMEOUT,
- + NJS_TOKEN_IMPORT,
- + NJS_TOKEN_FROM,
- + NJS_TOKEN_EXPORT,
- +
- NJS_TOKEN_RESERVED,
- } njs_token_t;
- @@ -252,11 +256,13 @@ struct njs_parser_scope_s {
- nxt_array_t *values[2]; /* Array of njs_value_t. */
- njs_index_t next_index[2];
- + nxt_str_t cwd;
- nxt_str_t file;
- njs_scope_t type:8;
- uint8_t nesting; /* 4 bits */
- uint8_t argument_closures;
- + uint8_t module;
- };
- @@ -319,6 +325,7 @@ njs_token_t njs_parser_var_expression(nj
- njs_token_t token);
- njs_token_t njs_parser_assignment_expression(njs_vm_t *vm,
- njs_parser_t *parser, njs_token_t token);
- +njs_token_t njs_parser_module_lambda(njs_vm_t *vm, njs_parser_t *parser);
- njs_token_t njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser,
- njs_token_t token);
- njs_token_t njs_parser_property_token(njs_vm_t *vm, njs_parser_t *parser);
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_shell.c
- --- a/njs/njs_shell.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_shell.c Sun Feb 17 14:01:10 2019 +0800
- @@ -21,6 +21,7 @@
- typedef struct {
- char *file;
- + char *path;
- nxt_int_t version;
- nxt_int_t disassemble;
- nxt_int_t interactive;
- @@ -216,7 +217,8 @@ main(int argc, char **argv)
- if (!opts.quiet) {
- if (opts.file != NULL) {
- - nxt_file_name(&vm_options.file, opts.file);
- + vm_options.file.start = (u_char *) opts.file;
- + vm_options.file.length = strlen(opts.file);
- } else {
- vm_options.file = nxt_string_value("shell");
- @@ -254,6 +256,7 @@ njs_get_options(njs_opts_t *opts, int ar
- " -d print disassembled code.\n"
- " -q disable interactive introduction prompt.\n"
- " -s sandbox mode.\n"
- + " -p set an path prefix for modules.\n"
- " -v print njs version and exit.\n"
- " <filename> | - run code from a file or stdin.\n";
- @@ -289,6 +292,15 @@ njs_get_options(njs_opts_t *opts, int ar
- opts->sandbox = 1;
- break;
- + case 'p':
- + if (argv[++i]) {
- + opts->path = argv[i];
- + break;
- + }
- +
- + fprintf(stderr, "option \"-p\" requires directory name\n");
- + return NXT_ERROR;
- +
- case 'v':
- case 'V':
- opts->version = 1;
- @@ -367,7 +379,8 @@ static nxt_int_t
- njs_interactive_shell(njs_opts_t *opts, njs_vm_opt_t *vm_options)
- {
- njs_vm_t *vm;
- - nxt_str_t line;
- + nxt_int_t ret;
- + nxt_str_t line, path;
- if (njs_editline_init() != NXT_OK) {
- fprintf(stderr, "failed to init completions\n");
- @@ -380,6 +393,17 @@ njs_interactive_shell(njs_opts_t *opts,
- return NXT_ERROR;
- }
- + if (opts->path != NULL) {
- + path.start = (u_char *) opts->path;
- + path.length = strlen(opts->path);
- +
- + ret = njs_vm_add_path(vm, &path);
- + if (ret != NXT_OK) {
- + fprintf(stderr, "failed to add path\n");
- + return NXT_ERROR;
- + }
- + }
- +
- if (njs_externals_init(vm, vm_options->external) != NXT_OK) {
- fprintf(stderr, "failed to add external protos\n");
- return NXT_ERROR;
- @@ -425,7 +449,7 @@ njs_process_file(njs_opts_t *opts, njs_v
- ssize_t n;
- njs_vm_t *vm;
- nxt_int_t ret;
- - nxt_str_t script;
- + nxt_str_t path, script;
- struct stat sb;
- file = opts->file;
- @@ -509,6 +533,18 @@ njs_process_file(njs_opts_t *opts, njs_v
- goto done;
- }
- + if (opts->path != NULL) {
- + path.start = (u_char *) opts->path;
- + path.length = strlen(opts->path);
- +
- + ret = njs_vm_add_path(vm, &path);
- + if (ret != NXT_OK) {
- + fprintf(stderr, "failed to add path\n");
- + ret = NXT_ERROR;
- + goto done;
- + }
- + }
- +
- ret = njs_externals_init(vm, vm_options->external);
- if (ret != NXT_OK) {
- fprintf(stderr, "failed to add external protos\n");
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_variable.c
- --- a/njs/njs_variable.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_variable.c Sun Feb 17 14:01:10 2019 +0800
- @@ -395,7 +395,7 @@ njs_variable_reference_resolve(njs_vm_t
- return NXT_OK;
- }
- - if (scope->parent == NULL) {
- + if (scope->module || scope->parent == NULL) {
- /* A global scope. */
- vr->scope = scope;
- diff -r 9c17b088408c -r fae8a5305fdb njs/njs_vm.h
- --- a/njs/njs_vm.h Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/njs_vm.h Sun Feb 17 14:01:10 2019 +0800
- @@ -1023,6 +1023,8 @@ struct njs_vm_s {
- /* njs_vm_t must be aligned to njs_value_t due to scratch value. */
- njs_value_t retval;
- + nxt_array_t *paths;
- +
- u_char *current;
- njs_value_t *scopes[NJS_SCOPES];
- @@ -1039,6 +1041,8 @@ struct njs_vm_s {
- nxt_lvlhsh_t variables_hash;
- nxt_lvlhsh_t values_hash;
- +
- + nxt_array_t *modules;
- nxt_lvlhsh_t modules_hash;
- uint32_t event_id;
- diff -r 9c17b088408c -r fae8a5305fdb njs/test/module/lib1.js
- --- /dev/null Thu Jan 01 00:00:00 1970 +0000
- +++ b/njs/test/module/lib1.js Sun Feb 17 14:01:10 2019 +0800
- @@ -0,0 +1,9 @@
- +function hash() {
- + var h = crypto.createHash('md5');
- + var v = h.update('AB').digest('hex');
- + return v;
- +}
- +
- +import crypto from 'crypto';
- +
- +export default {hash: hash};
- diff -r 9c17b088408c -r fae8a5305fdb njs/test/module/lib2.js
- --- /dev/null Thu Jan 01 00:00:00 1970 +0000
- +++ b/njs/test/module/lib2.js Sun Feb 17 14:01:10 2019 +0800
- @@ -0,0 +1,7 @@
- +function hash() {
- + return lib3.hash();
- +}
- +
- +import lib3 from './lib3.js';
- +
- +export default {hash: hash};
- diff -r 9c17b088408c -r fae8a5305fdb njs/test/module/lib3.js
- --- /dev/null Thu Jan 01 00:00:00 1970 +0000
- +++ b/njs/test/module/lib3.js Sun Feb 17 14:01:10 2019 +0800
- @@ -0,0 +1,7 @@
- +function hash() {
- + return sub1.hash();
- +}
- +
- +import sub1 from './sub/sub1.js';
- +
- +export default {hash: hash}
- diff -r 9c17b088408c -r fae8a5305fdb njs/test/module/libs/hash.js
- --- /dev/null Thu Jan 01 00:00:00 1970 +0000
- +++ b/njs/test/module/libs/hash.js Sun Feb 17 14:01:10 2019 +0800
- @@ -0,0 +1,9 @@
- +function hash() {
- + var h = crypto.createHash('md5');
- + var v = h.update('AB').digest('hex');
- + return v;
- +}
- +
- +import crypto from 'crypto';
- +
- +export default {hash: hash}
- diff -r 9c17b088408c -r fae8a5305fdb njs/test/module/main.js
- --- /dev/null Thu Jan 01 00:00:00 1970 +0000
- +++ b/njs/test/module/main.js Sun Feb 17 14:01:10 2019 +0800
- @@ -0,0 +1,16 @@
- +import lib1 from './lib1.js';
- +import lib2 from './lib2.js';
- +
- +import crypto from 'crypto';
- +var h = crypto.createHash('md5');
- +var hash = h.update('AB').digest('hex');
- +
- +if (lib1.hash() != hash) {
- + console.log("failed!");
- +}
- +
- +if (lib2.hash() != hash) {
- + console.log("failed!");
- +}
- +
- +console.log("passed!");
- diff -r 9c17b088408c -r fae8a5305fdb njs/test/module/sub/sub1.js
- --- /dev/null Thu Jan 01 00:00:00 1970 +0000
- +++ b/njs/test/module/sub/sub1.js Sun Feb 17 14:01:10 2019 +0800
- @@ -0,0 +1,8 @@
- +function hash() {
- + return sub2.hash(crypto);
- +}
- +
- +import sub2 from './sub2.js';
- +import crypto from 'crypto';
- +
- +export default {hash: hash};
- diff -r 9c17b088408c -r fae8a5305fdb njs/test/module/sub/sub2.js
- --- /dev/null Thu Jan 01 00:00:00 1970 +0000
- +++ b/njs/test/module/sub/sub2.js Sun Feb 17 14:01:10 2019 +0800
- @@ -0,0 +1,7 @@
- +function hash(crypto) {
- + return hashlib.hash();
- +}
- +
- +import hashlib from './hash.js';
- +
- +export default {hash: hash}
- diff -r 9c17b088408c -r fae8a5305fdb njs/test/njs_expect_test.exp
- --- a/njs/test/njs_expect_test.exp Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/test/njs_expect_test.exp Sun Feb 17 14:01:10 2019 +0800
- @@ -613,3 +613,13 @@ njs_test {
- {"var crypto = require('crypto')\r\n"
- "undefined\r\n"}
- } "-s"
- +
- +# module
- +
- +proc njs_load {file output} {
- + spawn -nottycopy njs -p njs/test/module/libs $file
- + expect $output
- + expect eof
- +}
- +
- +njs_load "./njs/test/module/main.js" "passed!"
- diff -r 9c17b088408c -r fae8a5305fdb njs/test/njs_unit_test.c
- --- a/njs/test/njs_unit_test.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/njs/test/njs_unit_test.c Sun Feb 17 14:01:10 2019 +0800
- @@ -11105,6 +11105,20 @@ static njs_unit_test_t njs_test[] =
- { nxt_string("typeof(null) === \"object\""),
- nxt_string("true") },
- + /* Module. */
- +
- + { nxt_string("import;"),
- + nxt_string("SyntaxError: Unexpected token \";\" in 1") },
- +
- + { nxt_string("import x from y;"),
- + nxt_string("SyntaxError: Unexpected token \"y\" in 1") },
- +
- + { nxt_string("import x from 'crypto';"),
- + nxt_string("undefined") },
- +
- + { nxt_string("export;"),
- + nxt_string("SyntaxError: Illegal export statement in 1") },
- +
- };
- diff -r 9c17b088408c -r fae8a5305fdb nxt/nxt_file.c
- --- a/nxt/nxt_file.c Sun Feb 17 13:52:53 2019 +0800
- +++ b/nxt/nxt_file.c Sun Feb 17 14:01:10 2019 +0800
- @@ -14,21 +14,25 @@
- void
- -nxt_file_name(nxt_str_t *name, char *path)
- +nxt_file_resolve(nxt_str_t *cwd, nxt_str_t *file, nxt_str_t *path)
- {
- - char *p, *last;
- - size_t length;
- + u_char *p, *last;
- - length = strlen(path);
- - last = path;
- + last = path->start;
- - for (p = path + length; p >= path; p--) {
- - if (*p == '/') {
- - last = p + 1;
- - break;
- - }
- + for (p = path->start + path->length;
- + p >= path->start;
- + p--)
- + {
- + if (*p == '/') {
- + last = p + 1;
- + break;
- + }
- }
- - name->start = (u_char *) last;
- - name->length = length - (last - path);
- + cwd->start = path->start;
- + cwd->length = last - path->start;
- +
- + file->start = last;
- + file->length = path->length - cwd->length;
- }
- diff -r 9c17b088408c -r fae8a5305fdb nxt/nxt_file.h
- --- a/nxt/nxt_file.h Sun Feb 17 13:52:53 2019 +0800
- +++ b/nxt/nxt_file.h Sun Feb 17 14:01:10 2019 +0800
- @@ -8,7 +8,7 @@
- #define _NXT_FILE_H_INCLUDED_
- -void nxt_file_name(nxt_str_t *name, char *path);
- +void nxt_file_resolve(nxt_str_t *cwd, nxt_str_t *file, nxt_str_t *path);
- #endif /* _NXT_FILE_H_INCLUDED_ */
Add Comment
Please, Sign In to add comment