[njs] Renamed njscript to njs.

Dmitry Volyntsev xeioex at nginx.com
Thu May 3 15:29:59 UTC 2018


details:   http://hg.nginx.org/njs/rev/71455987b770
branches:  
changeset: 515:71455987b770
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Thu May 03 18:29:26 2018 +0300
description:
Renamed njscript to njs.

njscript.c -> njs.c
njscript.h -> njs.h
njs.c -> njs_shell.c

diffstat:

 Makefile                        |    74 +-
 nginx/ngx_http_js_module.c      |     2 +-
 nginx/ngx_stream_js_module.c    |     2 +-
 njs/njs.c                       |  1137 ++++++++++++++++++++------------------
 njs/njs.h                       |   223 +++++++
 njs/njs_core.h                  |     2 +-
 njs/njs_shell.c                 |   651 ++++++++++++++++++++++
 njs/njscript.h                  |   223 -------
 njs/test/njs_benchmark.c        |     2 +-
 njs/test/njs_interactive_test.c |     2 +-
 10 files changed, 1512 insertions(+), 806 deletions(-)

diffs (truncated from 2722 to 1000 lines):

diff -r 2b64817dd8f6 -r 71455987b770 Makefile
--- a/Makefile	Fri Apr 27 14:21:39 2018 +0300
+++ b/Makefile	Thu May 03 18:29:26 2018 +0300
@@ -7,7 +7,7 @@ NXT_BUILDDIR =	build
 
 $(NXT_BUILDDIR)/libnjs.a: \
 	$(NXT_LIB)/nxt_auto_config.h \
-	$(NXT_BUILDDIR)/njscript.o \
+	$(NXT_BUILDDIR)/njs_shell.o \
 	$(NXT_BUILDDIR)/njs_vm.o \
 	$(NXT_BUILDDIR)/njs_boolean.o \
 	$(NXT_BUILDDIR)/njs_number.o \
@@ -49,7 +49,7 @@ NXT_BUILDDIR =	build
 	$(NXT_BUILDDIR)/nxt_mem_cache_pool.o \
 
 	ar -r -c $(NXT_BUILDDIR)/libnjs.a \
-		$(NXT_BUILDDIR)/njscript.o \
+		$(NXT_BUILDDIR)/njs_shell.o \
 		$(NXT_BUILDDIR)/njs_vm.o \
 		$(NXT_BUILDDIR)/njs_boolean.o \
 		$(NXT_BUILDDIR)/njs_number.o \
@@ -110,7 +110,7 @@ clean:
 	rm -f $(NXT_LIB)/Makefile.conf $(NXT_LIB)/nxt_auto_config.h
 
 dist:
-	NJS_VER=`grep NJS_VERSION njs/njscript.h | sed -e 's/.*"\(.*\)".*/\1/'`; \
+	NJS_VER=`grep NJS_VERSION njs/njs.h | sed -e 's/.*"\(.*\)".*/\1/'`; \
 	rm -rf njs-$${NJS_VER} \
 	&& hg archive njs-$${NJS_VER}.tar.gz \
 		      -p njs-$${NJS_VER} \
@@ -123,25 +123,25 @@ dist:
 	@echo
 	@exit 1
 
-$(NXT_BUILDDIR)/njscript.o: \
+$(NXT_BUILDDIR)/njs_shell.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_string.h \
 	njs/njs_object.h \
 	njs/njs_function.h \
 	njs/njs_parser.h \
-	njs/njscript.h \
-	njs/njscript.c \
+	njs/njs.h \
+	njs/njs.c \
 
-	$(NXT_CC) -c -o $(NXT_BUILDDIR)/njscript.o $(NXT_CFLAGS) \
+	$(NXT_CC) -c -o $(NXT_BUILDDIR)/njs_shell.o $(NXT_CFLAGS) \
 		-I$(NXT_LIB) -Injs \
-		njs/njscript.c
+		njs/njs.c
 
 $(NXT_BUILDDIR)/njs_vm.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_number.h \
@@ -162,7 +162,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_boolean.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_vm.h \
 	njs/njs_boolean.h \
 	njs/njs_object.h \
@@ -175,7 +175,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_number.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_number.h \
@@ -191,7 +191,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_string.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_number.h \
@@ -210,7 +210,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_object.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_object.h \
@@ -224,7 +224,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_array.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_number.h \
@@ -241,7 +241,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_json.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_object.h \
@@ -254,7 +254,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_function.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_object.h \
@@ -268,7 +268,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_regexp.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_string.h \
@@ -285,7 +285,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_date.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_string.h \
@@ -300,7 +300,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_error.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_string.h \
@@ -315,7 +315,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_math.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_object.h \
@@ -328,7 +328,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_time.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_object.h \
@@ -341,7 +341,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_module.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_module.h \
@@ -353,7 +353,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_event.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_event.h \
@@ -365,7 +365,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_fs.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_vm.h \
 	njs/njs_fs.h \
 	njs/njs_fs.c \
@@ -376,7 +376,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_crypto.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_crypto.h \
@@ -388,7 +388,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_extern.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_parser.h \
@@ -401,7 +401,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_variable.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_parser.h \
@@ -414,7 +414,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_builtin.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_boolean.h \
@@ -434,7 +434,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_lexer.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_parser.h \
@@ -446,7 +446,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_lexer_keyword.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_vm.h \
 	njs/njs_number.h \
 	njs/njs_object.h \
@@ -459,7 +459,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_parser.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_string.h \
@@ -475,7 +475,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_parser_expression.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_number.h \
@@ -491,7 +491,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_generator.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_number.h \
@@ -508,7 +508,7 @@ dist:
 
 $(NXT_BUILDDIR)/njs_disassembler.o: \
 	$(NXT_BUILDDIR)/libnxt.a \
-	njs/njscript.h \
+	njs/njs.h \
 	njs/njs_core.h \
 	njs/njs_vm.h \
 	njs/njs_object.h \
@@ -522,11 +522,11 @@ dist:
 $(NXT_BUILDDIR)/njs: \
 	$(NXT_BUILDDIR)/libnxt.a \
 	$(NXT_BUILDDIR)/libnjs.a \
-	njs/njs.c \
+	njs/njs_shell.c \
 
 	$(NXT_CC) -o $(NXT_BUILDDIR)/njs $(NXT_CFLAGS) \
 		-I$(NXT_LIB) $(NXT_EDITLINE_CFLAGS) -Injs \
-		njs/njs.c \
+		njs/njs_shell.c \
 		$(NXT_BUILDDIR)/libnjs.a \
 		-lm $(NXT_PCRE_LIB) $(NXT_EDITLINE_LIB)
 
diff -r 2b64817dd8f6 -r 71455987b770 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c	Fri Apr 27 14:21:39 2018 +0300
+++ b/nginx/ngx_http_js_module.c	Thu May 03 18:29:26 2018 +0300
@@ -9,7 +9,7 @@
 #include <ngx_core.h>
 #include <ngx_http.h>
 
-#include <njscript.h>
+#include <njs.h>
 
 
 typedef struct {
diff -r 2b64817dd8f6 -r 71455987b770 nginx/ngx_stream_js_module.c
--- a/nginx/ngx_stream_js_module.c	Fri Apr 27 14:21:39 2018 +0300
+++ b/nginx/ngx_stream_js_module.c	Thu May 03 18:29:26 2018 +0300
@@ -9,7 +9,7 @@
 #include <ngx_core.h>
 #include <ngx_stream.h>
 
-#include <njscript.h>
+#include <njs.h>
 
 
 typedef struct {
diff -r 2b64817dd8f6 -r 71455987b770 njs/njs.c
--- a/njs/njs.c	Fri Apr 27 14:21:39 2018 +0300
+++ b/njs/njs.c	Thu May 03 18:29:26 2018 +0300
@@ -1,651 +1,706 @@
 
 /*
- * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) Igor Sysoev
  * Copyright (C) NGINX, Inc.
  */
 
-
 #include <njs_core.h>
-#include <njs_builtin.h>
-#include <time.h>
-#include <errno.h>
+#include <njs_regexp.h>
 #include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <locale.h>
+
+
+static nxt_int_t njs_vm_init(njs_vm_t *vm);
+static nxt_int_t njs_vm_handle_events(njs_vm_t *vm);
+
 
-#include <readline.h>
+static void *
+njs_alloc(void *mem, size_t size)
+{
+    return nxt_malloc(size);
+}
 
 
-typedef enum {
-    NJS_COMPLETION_GLOBAL = 0,
-    NJS_COMPLETION_SUFFIX,
-} njs_completion_phase_t;
+static void *
+njs_zalloc(void *mem, size_t size)
+{
+    void  *p;
+
+    p = nxt_malloc(size);
+
+    if (p != NULL) {
+        memset(p, 0, size);
+    }
+
+    return p;
+}
 
 
-typedef struct {
-    char                    *file;
-    nxt_int_t               version;
-    nxt_int_t               disassemble;
-    nxt_int_t               interactive;
-} njs_opts_t;
-
-
-typedef struct {
-    size_t                  index;
-    size_t                  length;
-    njs_vm_t                *vm;
-    nxt_array_t             *completions;
-    nxt_array_t             *suffix_completions;
-    nxt_lvlhsh_each_t       lhe;
-    njs_completion_phase_t  phase;
-} njs_completion_t;
+static void *
+njs_align(void *mem, size_t alignment, size_t size)
+{
+    return nxt_memalign(alignment, size);
+}
 
 
-static nxt_int_t njs_get_options(njs_opts_t *opts, int argc, char **argv);
-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);
-static nxt_int_t njs_process_script(njs_vm_t *vm, njs_opts_t *opts,
-    const nxt_str_t *script, nxt_str_t *out);
-static nxt_int_t njs_editline_init(njs_vm_t *vm);
-static char **njs_completion_handler(const char *text, int start, int end);
-static char *njs_completion_generator(const char *text, int state);
+static void
+njs_free(void *mem, void *p)
+{
+    nxt_free(p);
+}
+
 
-static njs_ret_t njs_ext_console_log(njs_vm_t *vm, njs_value_t *args,
-    nxt_uint_t nargs, njs_index_t unused);
-static njs_ret_t njs_ext_console_help(njs_vm_t *vm, njs_value_t *args,
-    nxt_uint_t nargs, njs_index_t unused);
+const nxt_mem_proto_t  njs_vm_mem_cache_pool_proto = {
+    njs_alloc,
+    njs_zalloc,
+    njs_align,
+    NULL,
+    njs_free,
+    NULL,
+    NULL,
+};
 
 
-static njs_external_t  njs_ext_console[] = {
+static void *
+njs_array_mem_alloc(void *mem, size_t size)
+{
+    return nxt_mem_cache_alloc(mem, size);
+}
 
-    { nxt_string("log"),
-      NJS_EXTERN_METHOD,
-      NULL,
-      0,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      njs_ext_console_log,
-      0 },
 
-    { nxt_string("help"),
-      NJS_EXTERN_METHOD,
-      NULL,
-      0,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      njs_ext_console_help,
-      0 },
-};
+static void
+njs_array_mem_free(void *mem, void *p)
+{
+    nxt_mem_cache_free(mem, p);
+}
+
 
-static njs_external_t  njs_externals[] = {
-
-    { nxt_string("console"),
-      NJS_EXTERN_OBJECT,
-      njs_ext_console,
-      nxt_nitems(njs_ext_console),
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      0 },
+const nxt_mem_proto_t  njs_array_mem_proto = {
+    njs_array_mem_alloc,
+    NULL,
+    NULL,
+    NULL,
+    njs_array_mem_free,
+    NULL,
+    NULL,
 };
 
 
-static njs_completion_t  njs_completion;
+njs_vm_t *
+njs_vm_create(njs_vm_opt_t *options)
+{
+    njs_vm_t              *vm;
+    nxt_int_t             ret;
+    nxt_array_t           *debug;
+    nxt_mem_cache_pool_t  *mcp;
+    njs_regexp_pattern_t  *pattern;
+
+    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 NULL;
+    }
+
+    vm = nxt_mem_cache_zalign(mcp, sizeof(njs_value_t), sizeof(njs_vm_t));
+
+    if (nxt_fast_path(vm != NULL)) {
+        vm->mem_cache_pool = mcp;
+
+        ret = njs_regexp_init(vm);
+        if (nxt_slow_path(ret != NXT_OK)) {
+            return NULL;
+        }
+
+        if (options->shared != NULL) {
+            vm->shared = options->shared;
+
+        } else {
+            vm->shared = nxt_mem_cache_zalloc(mcp, sizeof(njs_vm_shared_t));
+            if (nxt_slow_path(vm->shared == NULL)) {
+                return NULL;
+            }
+
+            options->shared = vm->shared;
+
+            nxt_lvlhsh_init(&vm->shared->keywords_hash);
+
+            ret = njs_lexer_keywords_init(mcp, &vm->shared->keywords_hash);
+            if (nxt_slow_path(ret != NXT_OK)) {
+                return NULL;
+            }
+
+            nxt_lvlhsh_init(&vm->shared->values_hash);
+
+            pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)",
+                                                sizeof("(?:)") - 1, 0);
+            if (nxt_slow_path(pattern == NULL)) {
+                return NULL;
+            }
+
+            vm->shared->empty_regexp_pattern = pattern;
+
+            nxt_lvlhsh_init(&vm->modules_hash);
+
+            ret = njs_builtin_objects_create(vm);
+            if (nxt_slow_path(ret != NXT_OK)) {
+                return NULL;
+            }
+        }
+
+        nxt_lvlhsh_init(&vm->values_hash);
+
+        vm->external = options->external;
+
+        vm->external_objects = nxt_array_create(4, sizeof(void *),
+                                                &njs_array_mem_proto,
+                                                vm->mem_cache_pool);
+        if (nxt_slow_path(vm->external_objects == NULL)) {
+            return NULL;
+        }
+
+        nxt_lvlhsh_init(&vm->externals_hash);
+        nxt_lvlhsh_init(&vm->external_prototypes_hash);
+
+        vm->ops = options->ops;
+
+        vm->trace.level = NXT_LEVEL_TRACE;
+        vm->trace.size = 2048;
+        vm->trace.handler = njs_parser_trace_handler;
+        vm->trace.data = vm;
+
+        vm->trailer = options->trailer;
+
+        if (options->backtrace) {
+            debug = nxt_array_create(4, sizeof(njs_function_debug_t),
+                                     &njs_array_mem_proto,
+                                     vm->mem_cache_pool);
+            if (nxt_slow_path(debug == NULL)) {
+                return NULL;
+            }
+
+            vm->debug = debug;
+        }
+
+        vm->accumulative = options->accumulative;
+        if (vm->accumulative) {
+            ret = njs_vm_init(vm);
+            if (nxt_slow_path(ret != NXT_OK)) {
+                return NULL;
+            }
+
+            vm->retval = njs_value_void;
+        }
+    }
+
+    return vm;
+}
 
 
-int
-main(int argc, char **argv)
+void
+njs_vm_destroy(njs_vm_t *vm)
 {
-    nxt_int_t     ret;
-    njs_opts_t    opts;
-    njs_vm_opt_t  vm_options;
+    njs_event_t        *event;
+    nxt_lvlhsh_each_t  lhe;
+
+    if (njs_is_pending_events(vm)) {
+        nxt_lvlhsh_each_init(&lhe, &njs_event_hash_proto);
 
-    memset(&opts, 0, sizeof(njs_opts_t));
-    opts.interactive = 1;
+        for ( ;; ) {
+            event = nxt_lvlhsh_each(&vm->events_hash, &lhe);
 
-    ret = njs_get_options(&opts, argc, argv);
-    if (ret != NXT_OK) {
-        return (ret == NXT_DONE) ? EXIT_SUCCESS : EXIT_FAILURE;
+            if (event == NULL) {
+                break;
+            }
+
+            njs_del_event(vm, event, NJS_EVENT_RELEASE);
+        }
     }
 
-    if (opts.version != 0) {
-        printf("%s\n", NJS_VERSION);
-        return EXIT_SUCCESS;
+    nxt_mem_cache_pool_destroy(vm->mem_cache_pool);
+}
+
+
+nxt_int_t
+njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end)
+{
+    nxt_int_t          ret;
+    njs_lexer_t        *lexer;
+    njs_parser_t       *parser, *prev;
+    njs_parser_node_t  *node;
+
+    parser = nxt_mem_cache_zalloc(vm->mem_cache_pool, sizeof(njs_parser_t));
+    if (nxt_slow_path(parser == NULL)) {
+        return NJS_ERROR;
+    }
+
+    if (vm->parser != NULL && !vm->accumulative) {
+        return NJS_ERROR;
+    }
+
+    prev = vm->parser;
+    vm->parser = parser;
+
+    lexer = nxt_mem_cache_zalloc(vm->mem_cache_pool, sizeof(njs_lexer_t));
+    if (nxt_slow_path(lexer == NULL)) {
+        return NJS_ERROR;
+    }
+
+    parser->lexer = lexer;
+    lexer->start = *start;
+    lexer->end = end;
+    lexer->line = 1;
+    lexer->keywords_hash = vm->shared->keywords_hash;
+
+    parser->code_size = sizeof(njs_vmcode_stop_t);
+    parser->scope_offset = NJS_INDEX_GLOBAL_OFFSET;
+
+    if (vm->backtrace != NULL) {
+        nxt_array_reset(vm->backtrace);
+    }
+
+    node = njs_parser(vm, parser, prev);
+    if (nxt_slow_path(node == NULL)) {
+        goto fail;
+    }
+
+    ret = njs_variables_scope_reference(vm, parser->scope);
+    if (nxt_slow_path(ret != NXT_OK)) {
+        goto fail;
+    }
+
+    *start = parser->lexer->start;
+
+    /*
+     * Reset the code array to prevent it from being disassembled
+     * again in the next iteration of the accumulative mode.
+     */
+    vm->code = NULL;
+
+    ret = njs_generate_scope(vm, parser, node);
+    if (nxt_slow_path(ret != NXT_OK)) {
+        goto fail;
     }
 
-    memset(&vm_options, 0, sizeof(njs_vm_opt_t));
+    vm->current = parser->code_start;
+
+    vm->global_scope = parser->local_scope;
+    vm->scope_size = parser->scope_size;
+    vm->variables_hash = parser->scope->variables;
+
+    return NJS_OK;
 
-    vm_options.accumulative = 1;
-    vm_options.backtrace = 1;
+fail:
+
+    vm->parser = prev;
+
+    return NXT_ERROR;
+}
+
 
-    if (opts.interactive) {
-        ret = njs_interactive_shell(&opts, &vm_options);
+njs_vm_t *
+njs_vm_clone(njs_vm_t *vm, njs_external_ptr_t external)
+{
+    njs_vm_t              *nvm;
+    uint32_t              items;
+    nxt_int_t             ret;
+    nxt_array_t           *externals;
+    nxt_mem_cache_pool_t  *nmcp;
 
-    } else {
-        ret = njs_process_file(&opts, &vm_options);
+    nxt_thread_log_debug("CLONE:");
+
+    if (vm->accumulative) {
+        return NULL;
+    }
+
+    nmcp = nxt_mem_cache_pool_create(&njs_vm_mem_cache_pool_proto, NULL,
+                                    NULL, 2 * nxt_pagesize(), 128, 512, 16);
+    if (nxt_slow_path(nmcp == NULL)) {
+        return NULL;
     }
 
-    return (ret == NXT_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
+    nvm = nxt_mem_cache_zalign(nmcp, sizeof(njs_value_t), sizeof(njs_vm_t));
+
+    if (nxt_fast_path(nvm != NULL)) {
+        nvm->mem_cache_pool = nmcp;
+
+        nvm->shared = vm->shared;
+
+        nvm->variables_hash = vm->variables_hash;
+        nvm->values_hash = vm->values_hash;
+        nvm->modules_hash = vm->modules_hash;
+
+        nvm->externals_hash = vm->externals_hash;
+        nvm->external_prototypes_hash = vm->external_prototypes_hash;
+
+        items = vm->external_objects->items;
+        externals = nxt_array_create(items + 4, sizeof(void *),
+                                     &njs_array_mem_proto, nvm->mem_cache_pool);
+
+        if (nxt_slow_path(externals == NULL)) {
+            return NULL;
+        }
+
+        if (items > 0) {
+            memcpy(externals->start, vm->external_objects->start,
+                   items * sizeof(void *));
+            externals->items = items;
+        }
+
+        nvm->external_objects = externals;
+
+        nvm->ops = vm->ops;
+
+        nvm->current = vm->current;
+
+        nvm->external = external;
+
+        nvm->global_scope = vm->global_scope;
+        nvm->scope_size = vm->scope_size;
+
+        nvm->debug = vm->debug;
+
+        ret = njs_vm_init(nvm);
+        if (nxt_slow_path(ret != NXT_OK)) {
+            goto fail;
+        }
+
+        nvm->retval = njs_value_void;
+
+        return nvm;
+    }
+
+fail:
+
+    nxt_mem_cache_pool_destroy(nmcp);
+
+    return NULL;
 }
 
 
 static nxt_int_t
-njs_get_options(njs_opts_t *opts, int argc, char** argv)
+njs_vm_init(njs_vm_t *vm)
 {
-    char     *p;
-    nxt_int_t  i, ret;
+    size_t       size, scope_size;
+    u_char       *values;
+    nxt_int_t    ret;
+    njs_frame_t  *frame;
+    nxt_array_t  *backtrace;
+
+    scope_size = vm->scope_size + NJS_INDEX_GLOBAL_OFFSET;
+
+    size = NJS_GLOBAL_FRAME_SIZE + scope_size + NJS_FRAME_SPARE_SIZE;
+    size = nxt_align_size(size, NJS_FRAME_SPARE_SIZE);
 
-    ret = NXT_DONE;
+    frame = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), size);
+    if (nxt_slow_path(frame == NULL)) {
+        return NXT_ERROR;
+    }
+
+    memset(frame, 0, NJS_GLOBAL_FRAME_SIZE);
+
+    vm->top_frame = &frame->native;
+    vm->active_frame = frame;
+
+    frame->native.size = size;
+    frame->native.free_size = size - (NJS_GLOBAL_FRAME_SIZE + scope_size);
 
-    for (i = 1; i < argc; i++) {
+    values = (u_char *) frame + NJS_GLOBAL_FRAME_SIZE;
+
+    frame->native.free = values + scope_size;
 
-        p = argv[i];
+    vm->scopes[NJS_SCOPE_GLOBAL] = (njs_value_t *) values;
+    memcpy(values + NJS_INDEX_GLOBAL_OFFSET, vm->global_scope,
+           vm->scope_size);
+
+    ret = njs_regexp_init(vm);
+    if (nxt_slow_path(ret != NXT_OK)) {
+        return NXT_ERROR;
+    }
 
-        if (p[0] != '-' || (p[0] == '-' && p[1] == '\0')) {
-            opts->interactive = 0;
-            opts->file = argv[i];
-            continue;
+    ret = njs_builtin_objects_clone(vm);
+    if (nxt_slow_path(ret != NXT_OK)) {
+        return NXT_ERROR;
+    }
+
+    nxt_lvlhsh_init(&vm->events_hash);
+    nxt_queue_init(&vm->posted_events);
+
+    if (vm->debug != NULL) {
+        backtrace = nxt_array_create(4, sizeof(njs_backtrace_entry_t),
+                                     &njs_array_mem_proto, vm->mem_cache_pool);
+        if (nxt_slow_path(backtrace == NULL)) {
+            return NXT_ERROR;
         }
 
-        p++;
-
-        switch (*p) {
-        case 'd':
-            opts->disassemble = 1;
-            break;
-
-        case 'V':
-            opts->version = 1;
-            break;
+        vm->backtrace = backtrace;
+    }
 
-        default:
-            fprintf(stderr, "Unknown argument: \"%s\"\n", argv[i]);
-            ret = NXT_ERROR;
-
-            /* Fall through. */
-
-        case 'h':
-        case '?':
-            printf("Usage: %s [<file>|-] [-dV]\n", argv[0]);
-            return ret;
-        }
-    }
+    vm->trace.level = NXT_LEVEL_TRACE;
+    vm->trace.size = 2048;
+    vm->trace.handler = njs_parser_trace_handler;
+    vm->trace.data = vm;
 
     return NXT_OK;
 }
 
 
-static nxt_int_t
-njs_externals_init(njs_vm_t *vm)
+nxt_int_t
+njs_vm_call(njs_vm_t *vm, njs_function_t *function, njs_opaque_value_t *args,
+    nxt_uint_t nargs)
 {
-    nxt_uint_t          ret;
-    const njs_extern_t  *proto;
-    njs_opaque_value_t  *value;
-
-    static const nxt_str_t name = nxt_string_value("console");
-
-    proto = njs_vm_external_prototype(vm, &njs_externals[0]);
-    if (proto == NULL) {
-        fprintf(stderr, "failed to add console proto\n");
-        return NXT_ERROR;
-    }
-
-    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;
-}
-
-
-static nxt_int_t
-njs_interactive_shell(njs_opts_t *opts, njs_vm_opt_t *vm_options)
-{
-    njs_vm_t   *vm;
-    nxt_int_t  ret;
-    nxt_str_t  line, out;
+    u_char       *current;
+    njs_ret_t    ret;
+    njs_value_t  *this;
 
-    vm = njs_vm_create(vm_options);
-    if (vm == NULL) {
-        fprintf(stderr, "failed to create vm\n");
-        return NXT_ERROR;
-    }
-
-    if (njs_externals_init(vm) != NXT_OK) {
-        fprintf(stderr, "failed to add external protos\n");
-        return NXT_ERROR;
-    }
-
-    if (njs_editline_init(vm) != NXT_OK) {
-        fprintf(stderr, "failed to init completions\n");
-        return NXT_ERROR;
-    }
-
-    printf("interactive njscript %s\n\n", NJS_VERSION);
-
-    printf("v.<Tab> -> the properties and prototype methods of v.\n");
-    printf("type console.help() for more information\n\n");
+    static const njs_vmcode_stop_t  stop[] = {
+        { .code = { .operation = njs_vmcode_stop,
+                    .operands =  NJS_VMCODE_1OPERAND,
+                    .retval = NJS_VMCODE_NO_RETVAL },
+          .retval = NJS_INDEX_GLOBAL_RETVAL },
+    };
 
-    for ( ;; ) {
-        line.start = (u_char *) readline(">> ");
-        if (line.start == NULL) {
-            break;
-        }
-
-        line.length = strlen((char *) line.start);
-        if (line.length == 0) {
-            continue;
-        }
+    this = (njs_value_t *) &njs_value_void;
 
-        add_history((char *) line.start);


More information about the nginx-devel mailing list