Welcome! Log In Create A New Profile

Advanced

[njs] Code generator is separated from parser structure.

Dmitry Volyntsev
December 07, 2018 09:18AM
details: https://hg.nginx.org/njs/rev/2a13aff6aa1f
branches:
changeset: 687:2a13aff6aa1f
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Fri Dec 07 17:15:21 2018 +0300
description:
Code generator is separated from parser structure.

diffstat:

Makefile | 7 +-
njs/njs.c | 22 +-
njs/njs_function.h | 1 -
njs/njs_generator.c | 1126 ++++++++++++++++++++++++---------------------
njs/njs_generator.h | 22 +-
njs/njs_parser.c | 20 +-
njs/njs_parser.h | 54 --
njs/njs_string.c | 9 +-
njs/njs_string.h | 4 +-
njs/njs_vm.h | 1 +
njs/test/njs_unit_test.c | 9 +
11 files changed, 664 insertions(+), 611 deletions(-)

diffs (truncated from 3210 to 1000 lines):

diff -r 8eb112dcca79 -r 2a13aff6aa1f Makefile
--- a/Makefile Fri Dec 07 17:11:33 2018 +0300
+++ b/Makefile Fri Dec 07 17:15:21 2018 +0300
@@ -141,6 +141,7 @@ dist:
njs/njs_object.h \
njs/njs_function.h \
njs/njs_parser.h \
+ njs/njs_generator.h \
njs/njs.h \
njs/njs.c \

@@ -503,12 +504,8 @@ dist:
njs/njs.h \
njs/njs_core.h \
njs/njs_vm.h \
- njs/njs_number.h \
- njs/njs_string.h \
- njs/njs_object.h \
- njs/njs_function.h \
- njs/njs_variable.h \
njs/njs_parser.h \
+ njs/njs_generator.h \
njs/njs_generator.c \

$(NXT_CC) -c -o $(NXT_BUILDDIR)/njs_generator.o $(NXT_CFLAGS) \
diff -r 8eb112dcca79 -r 2a13aff6aa1f njs/njs.c
--- a/njs/njs.c Fri Dec 07 17:11:33 2018 +0300
+++ b/njs/njs.c Fri Dec 07 17:15:21 2018 +0300
@@ -220,6 +220,7 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
nxt_int_t ret;
njs_lexer_t *lexer;
njs_parser_t *parser, *prev;
+ njs_generator_t *generator;
njs_parser_node_t *node;

parser = nxt_mem_cache_zalloc(vm->mem_cache_pool, sizeof(njs_parser_t));
@@ -245,9 +246,6 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
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);
}
@@ -272,15 +270,25 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
*/
vm->code = NULL;

- ret = njs_generate_scope(vm, parser, node);
+ generator = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t),
+ 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, node);
if (nxt_slow_path(ret != NXT_OK)) {
goto fail;
}

- vm->current = parser->code_start;
+ vm->current = generator->code_start;

- vm->global_scope = parser->local_scope;
- vm->scope_size = parser->scope_size;
+ vm->global_scope = generator->local_scope;
+ vm->scope_size = generator->scope_size;
+
vm->variables_hash = parser->scope->variables;

if (vm->options.init) {
diff -r 8eb112dcca79 -r 2a13aff6aa1f njs/njs_function.h
--- a/njs/njs_function.h Fri Dec 07 17:11:33 2018 +0300
+++ b/njs/njs_function.h Fri Dec 07 17:15:21 2018 +0300
@@ -37,7 +37,6 @@ struct njs_function_lambda_s {
njs_value_t *closure_scope;

u_char *start;
- njs_parser_t *parser;
};


diff -r 8eb112dcca79 -r 2a13aff6aa1f njs/njs_generator.c
--- a/njs/njs_generator.c Fri Dec 07 17:11:33 2018 +0300
+++ b/njs/njs_generator.c Fri Dec 07 17:15:21 2018 +0300
@@ -1,6 +1,7 @@

/*
* Copyright (C) Igor Sysoev
+ * Copyright (C) Dmitry Volyntsev
* Copyright (C) NGINX, Inc.
*/

@@ -8,158 +9,195 @@
#include <string.h>


-static nxt_int_t njs_generator(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
-static u_char *njs_generate_reserve(njs_vm_t *vm, njs_parser_t *parser,
- size_t size);
-static nxt_int_t njs_generate_name(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
-static nxt_int_t njs_generate_builtin_object(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
-static nxt_int_t njs_generate_arguments_object(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_int_t njs_generate_variable(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
-static nxt_int_t njs_generate_var_statement(njs_vm_t *vm, njs_parser_t *parser,
+typedef struct njs_generator_patch_s njs_generator_patch_t;
+
+struct njs_generator_patch_s {
+ /*
+ * The jump_offset field points to jump offset field which contains a small
+ * adjustment and the adjustment should be added as (njs_ret_t *) because
+ * pointer to u_char accesses only one byte so this does not work on big
+ * endian platforms.
+ */
+ njs_ret_t jump_offset;
+ njs_generator_patch_t *next;
+};
+
+
+typedef enum {
+ NJS_GENERATOR_BLOCK = 0,
+ NJS_GENERATOR_LOOP,
+ NJS_GENERATOR_SWITCH,
+} njs_generator_block_type_t;
+
+
+struct njs_generator_block_s {
+ njs_generator_block_type_t type; /* 2 bits */
+ nxt_str_t label;
+ njs_generator_patch_t *continuation;
+ njs_generator_patch_t *exit;
+ njs_generator_block_t *next;
+};
+
+
+static nxt_int_t njs_generator(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
-static nxt_int_t njs_generate_if_statement(njs_vm_t *vm, njs_parser_t *parser,
+static u_char *njs_generate_reserve(njs_vm_t *vm, njs_generator_t *generator,
+ size_t size);
+static nxt_int_t njs_generate_name(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
+static nxt_int_t njs_generate_builtin_object(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_arguments_object(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_variable(njs_vm_t *vm, njs_generator_t *generator,
+ njs_parser_node_t *node);
+static nxt_int_t njs_generate_var_statement(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_if_statement(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_cond_expression(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_switch_statement(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_while_statement(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_do_while_statement(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_int_t njs_generate_for_statement(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_for_statement(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_for_in_statement(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_noinline nxt_int_t njs_generate_start_block(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_block_type_t type, const nxt_str_t *label);
+ njs_generator_t *generator, njs_generator_block_type_t type,
+ const nxt_str_t *label);
static nxt_noinline void njs_generate_patch_loop_continuation(njs_vm_t *vm,
- njs_parser_t *parser);
+ njs_generator_t *generator);
static nxt_noinline void njs_generate_patch_block_exit(njs_vm_t *vm,
- njs_parser_t *parser);
+ njs_generator_t *generator);
static nxt_int_t njs_generate_continue_statement(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_break_statement(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_int_t njs_generate_statement(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
-static nxt_int_t njs_generate_children(njs_vm_t *vm, njs_parser_t *parser,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_statement(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_children(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
-static nxt_int_t njs_generate_stop_statement(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
+static nxt_int_t njs_generate_stop_statement(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_comma_expression(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_int_t njs_generate_assignment(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_assignment(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_operation_assignment(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_int_t njs_generate_object(njs_vm_t *vm, njs_parser_t *parser,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_object(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
-static nxt_int_t njs_generate_array(njs_vm_t *vm, njs_parser_t *parser,
+static nxt_int_t njs_generate_array(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
-static nxt_int_t njs_generate_function(njs_vm_t *vm, njs_parser_t *parser,
+static nxt_int_t njs_generate_function(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
-static nxt_int_t njs_generate_regexp(njs_vm_t *vm, njs_parser_t *parser,
+static nxt_int_t njs_generate_regexp(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
static nxt_int_t njs_generate_test_jump_expression(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_3addr_operation(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node, nxt_bool_t swap);
+ njs_generator_t *generator, njs_parser_node_t *node, nxt_bool_t swap);
static nxt_int_t njs_generate_2addr_operation(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_typeof_operation(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_inc_dec_operation(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node, nxt_bool_t post);
+ njs_generator_t *generator, njs_parser_node_t *node, nxt_bool_t post);
static nxt_int_t njs_generate_function_declaration(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_function_scope(njs_vm_t *vm,
njs_function_lambda_t *lambda, njs_parser_node_t *node);
static nxt_int_t njs_generate_argument_closures(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_return_statement(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_int_t njs_generate_function_call(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
-static nxt_int_t njs_generate_method_call(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_function_call(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_method_call(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_noinline nxt_int_t njs_generate_call(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_int_t njs_generate_try_statement(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_try_statement(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_throw_statement(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_noinline njs_index_t njs_generator_dest_index(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+ 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
- njs_generator_object_dest_index(njs_vm_t *vm, njs_parser_t *parser,
+ njs_generate_object_dest_index(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
-static njs_index_t njs_generator_node_temp_index_get(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_noinline njs_index_t njs_generator_temp_index_get(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+static njs_index_t njs_generate_node_temp_index_get(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_noinline njs_index_t njs_generate_temp_index_get(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
static nxt_noinline nxt_int_t
- njs_generator_children_indexes_release(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
-static nxt_noinline nxt_int_t njs_generator_node_index_release(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
-static nxt_noinline nxt_int_t njs_generator_index_release(njs_vm_t *vm,
- njs_parser_t *parser, njs_index_t index);
+ njs_generate_children_indexes_release(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_noinline nxt_int_t njs_generate_node_index_release(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_noinline nxt_int_t njs_generate_index_release(njs_vm_t *vm,
+ njs_generator_t *generator, njs_index_t index);

static nxt_int_t njs_generate_function_debug(njs_vm_t *vm, nxt_str_t *name,
njs_function_lambda_t *lambda, uint32_t line);


-#define njs_generate_code(parser, type, code) \
+static void njs_generate_syntax_error(njs_vm_t *vm, uint32_t token_line,
+ const char* fmt, ...);
+
+
+#define njs_generate_code(generator, type, code) \
do { \
- code = (type *) njs_generate_reserve(vm, parser, sizeof(type)); \
+ code = (type *) njs_generate_reserve(vm, generator, sizeof(type)); \
if (nxt_slow_path(code == NULL)) { \
return NXT_ERROR; \
} \
- parser->code_end += sizeof(type); \
+ generator->code_end += sizeof(type); \
} while (0)


-#define njs_code_offset(parser, code) \
- ((u_char *) code - parser->code_start)
-
-
-#define njs_code_ptr(parser, type, offset) \
- (type *) (parser->code_start + offset)
-
-
-#define njs_code_jump_ptr(parser, offset) \
- (njs_ret_t *) (parser->code_start + offset)
-
-
-#define njs_code_offset_diff(parser, offset) \
- ((parser->code_end - parser->code_start) - offset)
-
-
-#define njs_code_set_offset(parser, offset, target) \
- *(njs_code_jump_ptr(parser, offset)) = njs_code_offset_diff(parser, target)
-
-
-#define njs_code_set_jump_offset(parser, type, code_offset) \
- *(njs_code_jump_ptr(parser, code_offset + offsetof(type, offset))) \
- = njs_code_offset_diff(parser, code_offset)
-
-
-#define njs_code_update_offset(parser, patch) \
- *(njs_code_jump_ptr(parser, patch->jump_offset)) += \
- njs_code_offset_diff(parser, patch->jump_offset)
+#define njs_code_offset(generator, code) \
+ ((u_char *) code - generator->code_start)
+
+
+#define njs_code_ptr(generator, type, offset) \
+ (type *) (generator->code_start + offset)
+
+
+#define njs_code_jump_ptr(generator, offset) \
+ (njs_ret_t *) (generator->code_start + offset)
+
+
+#define njs_code_offset_diff(generator, offset) \
+ ((generator->code_end - generator->code_start) - offset)
+
+
+#define njs_code_set_offset(generator, offset, target) \
+ *(njs_code_jump_ptr(generator, offset)) \
+ = njs_code_offset_diff(generator, target)
+
+
+#define njs_code_set_jump_offset(generator, type, code_offset) \
+ *(njs_code_jump_ptr(generator, code_offset + offsetof(type, offset))) \
+ = njs_code_offset_diff(generator, code_offset)
+
+
+#define njs_code_update_offset(generator, patch) \
+ *(njs_code_jump_ptr(generator, patch->jump_offset)) += \
+ njs_code_offset_diff(generator, patch->jump_offset)
+


static const nxt_str_t no_label = { 0, NULL };


static nxt_int_t
-njs_generator(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node)
+njs_generator(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node)
{
if (node == NULL) {
return NXT_OK;
@@ -168,46 +206,46 @@ njs_generator(njs_vm_t *vm, njs_parser_t
switch (node->token) {

case NJS_TOKEN_VAR:
- return njs_generate_var_statement(vm, parser, node);
+ return njs_generate_var_statement(vm, generator, node);

case NJS_TOKEN_IF:
- return njs_generate_if_statement(vm, parser, node);
+ return njs_generate_if_statement(vm, generator, node);

case NJS_TOKEN_CONDITIONAL:
- return njs_generate_cond_expression(vm, parser, node);
+ return njs_generate_cond_expression(vm, generator, node);

case NJS_TOKEN_SWITCH:
- return njs_generate_switch_statement(vm, parser, node);
+ return njs_generate_switch_statement(vm, generator, node);

case NJS_TOKEN_WHILE:
- return njs_generate_while_statement(vm, parser, node);
+ return njs_generate_while_statement(vm, generator, node);

case NJS_TOKEN_DO:
- return njs_generate_do_while_statement(vm, parser, node);
+ return njs_generate_do_while_statement(vm, generator, node);

case NJS_TOKEN_FOR:
- return njs_generate_for_statement(vm, parser, node);
+ return njs_generate_for_statement(vm, generator, node);

case NJS_TOKEN_FOR_IN:
- return njs_generate_for_in_statement(vm, parser, node);
+ return njs_generate_for_in_statement(vm, generator, node);

case NJS_TOKEN_CONTINUE:
- return njs_generate_continue_statement(vm, parser, node);
+ return njs_generate_continue_statement(vm, generator, node);

case NJS_TOKEN_BREAK:
- return njs_generate_break_statement(vm, parser, node);
+ return njs_generate_break_statement(vm, generator, node);

case NJS_TOKEN_STATEMENT:
- return njs_generate_statement(vm, parser, node);
+ return njs_generate_statement(vm, generator, node);

case NJS_TOKEN_END:
- return njs_generate_stop_statement(vm, parser, node);
+ return njs_generate_stop_statement(vm, generator, node);

case NJS_TOKEN_COMMA:
- return njs_generate_comma_expression(vm, parser, node);
+ return njs_generate_comma_expression(vm, generator, node);

case NJS_TOKEN_ASSIGNMENT:
- return njs_generate_assignment(vm, parser, node);
+ return njs_generate_assignment(vm, generator, node);

case NJS_TOKEN_BITWISE_OR_ASSIGNMENT:
case NJS_TOKEN_BITWISE_XOR_ASSIGNMENT:
@@ -221,7 +259,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t
case NJS_TOKEN_EXPONENTIATION_ASSIGNMENT:
case NJS_TOKEN_DIVISION_ASSIGNMENT:
case NJS_TOKEN_REMAINDER_ASSIGNMENT:
- return njs_generate_operation_assignment(vm, parser, node);
+ return njs_generate_operation_assignment(vm, generator, node);

case NJS_TOKEN_BITWISE_OR:
case NJS_TOKEN_BITWISE_XOR:
@@ -246,7 +284,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t
case NJS_TOKEN_REMAINDER:
case NJS_TOKEN_PROPERTY_DELETE:
case NJS_TOKEN_PROPERTY:
- return njs_generate_3addr_operation(vm, parser, node, 0);
+ return njs_generate_3addr_operation(vm, generator, node, 0);

case NJS_TOKEN_IN:
/*
@@ -255,11 +293,11 @@ njs_generator(njs_vm_t *vm, njs_parser_t
* should be swapped to be uniform with other property operations
* (get/set and delete) to use the property trap.
*/
- return njs_generate_3addr_operation(vm, parser, node, 1);
+ return njs_generate_3addr_operation(vm, generator, node, 1);

case NJS_TOKEN_LOGICAL_AND:
case NJS_TOKEN_LOGICAL_OR:
- return njs_generate_test_jump_expression(vm, parser, node);
+ return njs_generate_test_jump_expression(vm, generator, node);

case NJS_TOKEN_DELETE:
case NJS_TOKEN_VOID:
@@ -267,25 +305,25 @@ njs_generator(njs_vm_t *vm, njs_parser_t
case NJS_TOKEN_UNARY_NEGATION:
case NJS_TOKEN_LOGICAL_NOT:
case NJS_TOKEN_BITWISE_NOT:
- return njs_generate_2addr_operation(vm, parser, node);
+ return njs_generate_2addr_operation(vm, generator, node);

case NJS_TOKEN_TYPEOF:
- return njs_generate_typeof_operation(vm, parser, node);
+ return njs_generate_typeof_operation(vm, generator, node);

case NJS_TOKEN_INCREMENT:
case NJS_TOKEN_DECREMENT:
- return njs_generate_inc_dec_operation(vm, parser, node, 0);
+ return njs_generate_inc_dec_operation(vm, generator, node, 0);

case NJS_TOKEN_POST_INCREMENT:
case NJS_TOKEN_POST_DECREMENT:
- return njs_generate_inc_dec_operation(vm, parser, node, 1);
+ return njs_generate_inc_dec_operation(vm, generator, node, 1);

case NJS_TOKEN_UNDEFINED:
case NJS_TOKEN_NULL:
case NJS_TOKEN_BOOLEAN:
case NJS_TOKEN_NUMBER:
case NJS_TOKEN_STRING:
- node->index = njs_value_index(vm, parser, &node->u.value);
+ node->index = njs_value_index(vm, &node->u.value, generator->runtime);

if (nxt_fast_path(node->index != NJS_INDEX_NONE)) {
return NXT_OK;
@@ -298,16 +336,16 @@ njs_generator(njs_vm_t *vm, njs_parser_t
return NXT_OK;

case NJS_TOKEN_OBJECT:
- return njs_generate_object(vm, parser, node);
+ return njs_generate_object(vm, generator, node);

case NJS_TOKEN_ARRAY:
- return njs_generate_array(vm, parser, node);
+ return njs_generate_array(vm, generator, node);

case NJS_TOKEN_FUNCTION_EXPRESSION:
- return njs_generate_function(vm, parser, node);
+ return njs_generate_function(vm, generator, node);

case NJS_TOKEN_REGEXP:
- return njs_generate_regexp(vm, parser, node);
+ return njs_generate_regexp(vm, generator, node);

case NJS_TOKEN_THIS:
case NJS_TOKEN_OBJECT_CONSTRUCTOR:
@@ -331,7 +369,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t
return NXT_OK;

case NJS_TOKEN_NAME:
- return njs_generate_name(vm, parser, node);
+ return njs_generate_name(vm, generator, node);

case NJS_TOKEN_GLOBAL_THIS:
case NJS_TOKEN_NJS:
@@ -350,28 +388,28 @@ njs_generator(njs_vm_t *vm, njs_parser_t
case NJS_TOKEN_REQUIRE:
case NJS_TOKEN_SET_TIMEOUT:
case NJS_TOKEN_CLEAR_TIMEOUT:
- return njs_generate_builtin_object(vm, parser, node);
+ return njs_generate_builtin_object(vm, generator, node);

case NJS_TOKEN_ARGUMENTS:
- return njs_generate_arguments_object(vm, parser, node);
+ return njs_generate_arguments_object(vm, generator, node);

case NJS_TOKEN_FUNCTION:
- return njs_generate_function_declaration(vm, parser, node);
+ return njs_generate_function_declaration(vm, generator, node);

case NJS_TOKEN_FUNCTION_CALL:
- return njs_generate_function_call(vm, parser, node);
+ return njs_generate_function_call(vm, generator, node);

case NJS_TOKEN_RETURN:
- return njs_generate_return_statement(vm, parser, node);
+ return njs_generate_return_statement(vm, generator, node);

case NJS_TOKEN_METHOD_CALL:
- return njs_generate_method_call(vm, parser, node);
+ return njs_generate_method_call(vm, generator, node);

case NJS_TOKEN_TRY:
- return njs_generate_try_statement(vm, parser, node);
+ return njs_generate_try_statement(vm, generator, node);

case NJS_TOKEN_THROW:
- return njs_generate_throw_statement(vm, parser, node);
+ return njs_generate_throw_statement(vm, generator, node);

default:
nxt_thread_log_debug("unknown token: %d", node->token);
@@ -383,16 +421,18 @@ njs_generator(njs_vm_t *vm, njs_parser_t


static u_char *
-njs_generate_reserve(njs_vm_t *vm, njs_parser_t *parser, size_t size)
+njs_generate_reserve(njs_vm_t *vm, njs_generator_t *generator, size_t size)
{
u_char *p;

- if (parser->code_end + size <= parser->code_start + parser->code_size) {
- return parser->code_end;
+ if (generator->code_end + size <=
+ generator->code_start + generator->code_size)
+ {
+ return generator->code_end;
}

- size = nxt_max(parser->code_end - parser->code_start + size,
- parser->code_size);
+ size = nxt_max(generator->code_end - generator->code_start + size,
+ generator->code_size);

if (size < 1024) {
size *= 2;
@@ -407,20 +447,21 @@ njs_generate_reserve(njs_vm_t *vm, njs_p
return NULL;
}

- parser->code_size = size;
-
- size = parser->code_end - parser->code_start;
- memcpy(p, parser->code_start, size);
-
- parser->code_start = p;
- parser->code_end = p + size;
-
- return parser->code_end;
+ generator->code_size = size;
+
+ size = generator->code_end - generator->code_start;
+ memcpy(p, generator->code_start, size);
+
+ generator->code_start = p;
+ generator->code_end = p + size;
+
+ return generator->code_end;
}


static nxt_int_t
-njs_generate_name(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node)
+njs_generate_name(njs_vm_t *vm, njs_generator_t *generator,
+ njs_parser_node_t *node)
{
njs_variable_t *var;
njs_vmcode_object_copy_t *copy;
@@ -432,12 +473,12 @@ njs_generate_name(njs_vm_t *vm, njs_pars

if (var->type == NJS_VARIABLE_FUNCTION) {

- node->index = njs_generator_dest_index(vm, parser, node);
+ node->index = njs_generate_dest_index(vm, generator, node);
if (nxt_slow_path(node->index == NJS_INDEX_ERROR)) {
return node->index;
}

- njs_generate_code(parser, njs_vmcode_object_copy_t, copy);
+ 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;
@@ -447,12 +488,12 @@ njs_generate_name(njs_vm_t *vm, njs_pars
return NXT_OK;
}

- return njs_generate_variable(vm, parser, node);
+ return njs_generate_variable(vm, generator, node);
}


static nxt_int_t
-njs_generate_builtin_object(njs_vm_t *vm, njs_parser_t *parser,
+njs_generate_builtin_object(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
njs_index_t index;
@@ -463,12 +504,12 @@ njs_generate_builtin_object(njs_vm_t *vm
return NXT_ERROR;
}

- node->index = njs_generator_dest_index(vm, parser, node);
+ node->index = njs_generate_dest_index(vm, generator, node);
if (nxt_slow_path(node->index == NJS_INDEX_ERROR)) {
return NXT_ERROR;
}

- njs_generate_code(parser, njs_vmcode_object_copy_t, copy);
+ 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;
@@ -480,19 +521,19 @@ njs_generate_builtin_object(njs_vm_t *vm


static nxt_int_t
-njs_generate_arguments_object(njs_vm_t *vm, njs_parser_t *parser,
+njs_generate_arguments_object(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
njs_vmcode_arguments_t *gen;

- parser->arguments_object = 1;
-
- node->index = njs_generator_object_dest_index(vm, parser, node);
+ generator->arguments_object = 1;
+
+ node->index = njs_generate_object_dest_index(vm, generator, node);
if (nxt_slow_path(node->index == NJS_INDEX_ERROR)) {
return NXT_ERROR;
}

- njs_generate_code(parser, njs_vmcode_arguments_t, gen);
+ njs_generate_code(generator, njs_vmcode_arguments_t, gen);
gen->code.operation = njs_vmcode_arguments;
gen->code.operands = NJS_VMCODE_1OPERAND;
gen->code.retval = NJS_VMCODE_RETVAL;
@@ -503,7 +544,7 @@ njs_generate_arguments_object(njs_vm_t *


static nxt_int_t
-njs_generate_variable(njs_vm_t *vm, njs_parser_t *parser,
+njs_generate_variable(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
njs_index_t index;
@@ -520,7 +561,7 @@ njs_generate_variable(njs_vm_t *vm, njs_


static nxt_int_t
-njs_generate_var_statement(njs_vm_t *vm, njs_parser_t *parser,
+njs_generate_var_statement(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
nxt_int_t ret;
@@ -546,7 +587,7 @@ njs_generate_var_statement(njs_vm_t *vm,

expr->dest = lvalue;

- ret = njs_generator(vm, parser, expr);
+ ret = njs_generator(vm, generator, expr);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}
@@ -556,7 +597,7 @@ njs_generate_var_statement(njs_vm_t *vm,
* empty object or expression result is stored directly in variable.
*/
if (lvalue->index != expr->index) {
- njs_generate_code(parser, njs_vmcode_move_t, move);
+ njs_generate_code(generator, njs_vmcode_move_t, move);
move->code.operation = njs_vmcode_move;
move->code.operands = NJS_VMCODE_2OPERANDS;
move->code.retval = NJS_VMCODE_RETVAL;
@@ -572,7 +613,7 @@ njs_generate_var_statement(njs_vm_t *vm,


static nxt_int_t
-njs_generate_if_statement(njs_vm_t *vm, njs_parser_t *parser,
+njs_generate_if_statement(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
njs_ret_t jump_offset, label_offset;
@@ -582,23 +623,23 @@ njs_generate_if_statement(njs_vm_t *vm,

/* The condition expression. */

- ret = njs_generator(vm, parser, node->left);
+ ret = njs_generator(vm, generator, node->left);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

- njs_generate_code(parser, njs_vmcode_cond_jump_t, cond_jump);
+ njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump);
cond_jump->code.operation = njs_vmcode_if_false_jump;
cond_jump->code.operands = NJS_VMCODE_2OPERANDS;
cond_jump->code.retval = NJS_VMCODE_NO_RETVAL;
cond_jump->cond = node->left->index;

- ret = njs_generator_node_index_release(vm, parser, node->left);
+ ret = njs_generate_node_index_release(vm, generator, node->left);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

- jump_offset = njs_code_offset(parser, cond_jump);
+ jump_offset = njs_code_offset(generator, cond_jump);
label_offset = jump_offset + offsetof(njs_vmcode_cond_jump_t, offset);

if (node->right != NULL && node->right->token == NJS_TOKEN_BRANCHING) {
@@ -607,24 +648,24 @@ njs_generate_if_statement(njs_vm_t *vm,

node = node->right;

- ret = njs_generator(vm, parser, node->left);
+ ret = njs_generator(vm, generator, node->left);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

- ret = njs_generator_node_index_release(vm, parser, node->left);
+ ret = njs_generate_node_index_release(vm, generator, node->left);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

- njs_generate_code(parser, njs_vmcode_jump_t, jump);
+ njs_generate_code(generator, njs_vmcode_jump_t, jump);
jump->code.operation = njs_vmcode_jump;
jump->code.operands = NJS_VMCODE_NO_OPERAND;
jump->code.retval = NJS_VMCODE_NO_RETVAL;

- njs_code_set_offset(parser, label_offset, jump_offset);
-
- jump_offset = njs_code_offset(parser, jump);
+ njs_code_set_offset(generator, label_offset, jump_offset);
+
+ jump_offset = njs_code_offset(generator, jump);
label_offset = jump_offset + offsetof(njs_vmcode_jump_t, offset);
}

@@ -633,24 +674,24 @@ njs_generate_if_statement(njs_vm_t *vm,
* or the "else" branch in a case of "if/then/else" statement.
*/

- ret = njs_generator(vm, parser, node->right);
+ ret = njs_generator(vm, generator, node->right);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

- ret = njs_generator_node_index_release(vm, parser, node->right);
+ ret = njs_generate_node_index_release(vm, generator, node->right);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

- njs_code_set_offset(parser, label_offset, jump_offset);
+ njs_code_set_offset(generator, label_offset, jump_offset);

return NXT_OK;
}


static nxt_int_t
-njs_generate_cond_expression(njs_vm_t *vm, njs_parser_t *parser,
+njs_generate_cond_expression(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
njs_ret_t jump_offset, cond_jump_offset;
@@ -662,19 +703,19 @@ njs_generate_cond_expression(njs_vm_t *v

/* The condition expression. */

- ret = njs_generator(vm, parser, node->left);
+ ret = njs_generator(vm, generator, node->left);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

- njs_generate_code(parser, njs_vmcode_cond_jump_t, cond_jump);
- cond_jump_offset = njs_code_offset(parser, cond_jump);
+ njs_generate_code(generator, njs_vmcode_cond_jump_t, cond_jump);
+ cond_jump_offset = njs_code_offset(generator, cond_jump);
cond_jump->code.operation = njs_vmcode_if_false_jump;
cond_jump->code.operands = NJS_VMCODE_2OPERANDS;
cond_jump->code.retval = NJS_VMCODE_NO_RETVAL;
cond_jump->cond = node->left->index;

- node->index = njs_generator_dest_index(vm, parser, node);
+ node->index = njs_generate_dest_index(vm, generator, node);
if (nxt_slow_path(node->index == NJS_INDEX_ERROR)) {
return node->index;
}
@@ -683,7 +724,7 @@ njs_generate_cond_expression(njs_vm_t *v

/* The "true" branch. */

- ret = njs_generator(vm, parser, branch->left);
+ ret = njs_generator(vm, generator, branch->left);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}
@@ -695,7 +736,7 @@ njs_generate_cond_expression(njs_vm_t *v
*/

if (node->index != branch->left->index) {
- njs_generate_code(parser, njs_vmcode_move_t, move);
+ njs_generate_code(generator, njs_vmcode_move_t, move);
move->code.operation = njs_vmcode_move;
move->code.operands = NJS_VMCODE_2OPERANDS;
move->code.retval = NJS_VMCODE_RETVAL;
@@ -703,28 +744,29 @@ njs_generate_cond_expression(njs_vm_t *v
move->src = branch->left->index;
}

- ret = njs_generator_node_index_release(vm, parser, branch->left);
+ ret = njs_generate_node_index_release(vm, generator, branch->left);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

- njs_generate_code(parser, njs_vmcode_jump_t, jump);
- jump_offset = njs_code_offset(parser, jump);
+ njs_generate_code(generator, njs_vmcode_jump_t, jump);
+ jump_offset = njs_code_offset(generator, jump);
jump->code.operation = njs_vmcode_jump;
jump->code.operands = NJS_VMCODE_NO_OPERAND;
jump->code.retval = NJS_VMCODE_NO_RETVAL;

- njs_code_set_jump_offset(parser, njs_vmcode_cond_jump_t, cond_jump_offset);
+ njs_code_set_jump_offset(generator, njs_vmcode_cond_jump_t,
+ cond_jump_offset);

/* The "false" branch. */

- ret = njs_generator(vm, parser, branch->right);
+ ret = njs_generator(vm, generator, branch->right);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

if (node->index != branch->right->index) {
- njs_generate_code(parser, njs_vmcode_move_t, move);
+ njs_generate_code(generator, njs_vmcode_move_t, move);
move->code.operation = njs_vmcode_move;
move->code.operands = NJS_VMCODE_2OPERANDS;
move->code.retval = NJS_VMCODE_RETVAL;
@@ -732,9 +774,9 @@ njs_generate_cond_expression(njs_vm_t *v
move->src = branch->right->index;
}

- njs_code_set_jump_offset(parser, njs_vmcode_cond_jump_t, jump_offset);
-
- ret = njs_generator_node_index_release(vm, parser, branch->right);
+ njs_code_set_jump_offset(generator, njs_vmcode_cond_jump_t, jump_offset);
+
+ ret = njs_generate_node_index_release(vm, generator, branch->right);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}
@@ -744,7 +786,7 @@ njs_generate_cond_expression(njs_vm_t *v


static nxt_int_t
-njs_generate_switch_statement(njs_vm_t *vm, njs_parser_t *parser,
+njs_generate_switch_statement(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *swtch)
{
njs_ret_t jump_offset;
@@ -753,14 +795,14 @@ njs_generate_switch_statement(njs_vm_t *
njs_parser_node_t *node, *expr, *branch;
njs_vmcode_move_t *move;
njs_vmcode_jump_t *jump;
- njs_parser_patch_t *patch, *next, *patches, **last;
+ njs_generator_patch_t *patch, *next, *patches, **last;
njs_vmcode_equal_jump_t *equal;

/* The "switch" expression. */

expr = swtch->left;

- ret = njs_generator(vm, parser, expr);
+ ret = njs_generator(vm, generator, expr);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}
@@ -768,12 +810,12 @@ njs_generate_switch_statement(njs_vm_t *
index = expr->index;

if (!expr->temporary) {
- index = njs_generator_temp_index_get(vm, parser, swtch);
+ index = njs_generate_temp_index_get(vm, generator, swtch);
if (nxt_slow_path(index == NJS_INDEX_ERROR)) {
return NXT_ERROR;
}

- njs_generate_code(parser, njs_vmcode_move_t, move);
+ njs_generate_code(generator, njs_vmcode_move_t, move);
move->code.operation = njs_vmcode_move;
move->code.operands = NJS_VMCODE_2OPERANDS;
move->code.retval = NJS_VMCODE_RETVAL;
@@ -781,7 +823,8 @@ njs_generate_switch_statement(njs_vm_t *
move->src = expr->index;
}

- ret = njs_generate_start_block(vm, parser, NJS_PARSER_SWITCH, &no_label);
+ ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_SWITCH,
+ &no_label);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}
@@ -797,12 +840,12 @@ njs_generate_switch_statement(njs_vm_t *

node = branch->right;

- ret = njs_generator(vm, parser, node->left);
+ ret = njs_generator(vm, generator, node->left);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}

- njs_generate_code(parser, njs_vmcode_equal_jump_t, equal);
+ njs_generate_code(generator, njs_vmcode_equal_jump_t, equal);
equal->code.operation = njs_vmcode_if_equal_jump;
equal->code.operands = NJS_VMCODE_3OPERANDS;
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Code generator is separated from parser structure.

Dmitry Volyntsev 163 December 07, 2018 09:18AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 86
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready