[njs] Introduced "debugger" token support.
Dmitry Volyntsev
xeioex at nginx.com
Fri Jun 18 15:07:42 UTC 2021
details: https://hg.nginx.org/njs/rev/7717b6523cd4
branches:
changeset: 1666:7717b6523cd4
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Fri Jun 18 15:01:48 2021 +0000
description:
Introduced "debugger" token support.
diffstat:
src/njs_disassembler.c | 3 +++
src/njs_generator.c | 23 +++++++++++++++++++++++
src/njs_parser.c | 19 +++++++++++++++++--
src/njs_scope.c | 7 +++++++
src/njs_scope.h | 1 +
src/njs_vmcode.c | 29 +++++++++++++++++++++++++++++
src/njs_vmcode.h | 7 +++++++
src/test/njs_unit_test.c | 17 +++++++++++++++++
8 files changed, 104 insertions(+), 2 deletions(-)
diffs (235 lines):
diff -r 9aed07704f30 -r 7717b6523cd4 src/njs_disassembler.c
--- a/src/njs_disassembler.c Fri Jun 18 15:01:13 2021 +0000
+++ b/src/njs_disassembler.c Fri Jun 18 15:01:48 2021 +0000
@@ -153,6 +153,9 @@ static njs_code_name_t code_names[] = {
{ NJS_VMCODE_ASSIGNMENT_ERROR, sizeof(njs_vmcode_variable_t),
njs_str("ASSIGNMENT ERROR") },
+
+ { NJS_VMCODE_DEBUGGER, sizeof(njs_vmcode_debugger_t),
+ njs_str("DEBUGGER ") },
};
diff -r 9aed07704f30 -r 7717b6523cd4 src/njs_generator.c
--- a/src/njs_generator.c Fri Jun 18 15:01:13 2021 +0000
+++ b/src/njs_generator.c Fri Jun 18 15:01:48 2021 +0000
@@ -111,6 +111,8 @@ static njs_int_t njs_generate_continue_s
njs_generator_t *generator, njs_parser_node_t *node);
static njs_int_t njs_generate_break_statement(njs_vm_t *vm,
njs_generator_t *generator, njs_parser_node_t *node);
+static njs_int_t njs_generate_debugger_statement(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node);
static njs_int_t njs_generate_statement(njs_vm_t *vm,
njs_generator_t *generator, njs_parser_node_t *node);
static njs_int_t njs_generate_block_statement(njs_vm_t *vm,
@@ -317,6 +319,9 @@ njs_generate(njs_vm_t *vm, njs_generator
case NJS_TOKEN_BREAK:
return njs_generate_break_statement(vm, generator, node);
+ case NJS_TOKEN_DEBUGGER:
+ return njs_generate_debugger_statement(vm, generator, node);
+
case NJS_TOKEN_STATEMENT:
return njs_generate_statement(vm, generator, node);
@@ -1820,6 +1825,24 @@ syntax_error:
static njs_int_t
+njs_generate_debugger_statement(njs_vm_t *vm, njs_generator_t *generator,
+ njs_parser_node_t *node)
+{
+ njs_vmcode_debugger_t *debugger;
+
+ njs_generate_code(generator, njs_vmcode_debugger_t, debugger,
+ NJS_VMCODE_DEBUGGER, 0, node);
+
+ debugger->retval = njs_generate_dest_index(vm, generator, node);
+ if (njs_slow_path(debugger->retval == NJS_INDEX_ERROR)) {
+ return debugger->retval;
+ }
+
+ return NJS_OK;
+}
+
+
+static njs_int_t
njs_generate_statement(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
diff -r 9aed07704f30 -r 7717b6523cd4 src/njs_parser.c
--- a/src/njs_parser.c Fri Jun 18 15:01:13 2021 +0000
+++ b/src/njs_parser.c Fri Jun 18 15:01:48 2021 +0000
@@ -6545,7 +6545,22 @@ static njs_int_t
njs_parser_debugger_statement(njs_parser_t *parser, njs_lexer_token_t *token,
njs_queue_link_t *current)
{
- return njs_parser_not_supported(parser, token);
+ parser->node = njs_parser_node_new(parser, NJS_TOKEN_DEBUGGER);
+ if (parser->node == NULL) {
+ return NJS_ERROR;
+ }
+
+ parser->node->token_line = parser->line;
+
+ if (token->type != NJS_TOKEN_SEMICOLON
+ && token->type != NJS_TOKEN_END)
+ {
+ return njs_parser_failed(parser);
+ }
+
+ njs_lexer_consume_token(parser->lexer, 1);
+
+ return njs_parser_stack_pop(parser);
}
@@ -8882,6 +8897,7 @@ njs_parser_serialize_node(njs_chb_t *cha
njs_token_serialize(NJS_TOKEN_EVAL);
njs_token_serialize(NJS_TOKEN_IMPORT);
njs_token_serialize(NJS_TOKEN_EXPORT);
+ njs_token_serialize(NJS_TOKEN_DEBUGGER);
#if 0
@@ -8889,7 +8905,6 @@ njs_parser_serialize_node(njs_chb_t *cha
njs_token_serialize(NJS_TOKEN_META);
njs_token_serialize(NJS_TOKEN_ASYNC);
njs_token_serialize(NJS_TOKEN_AWAIT);
- njs_token_serialize(NJS_TOKEN_DEBUGGER);
njs_token_serialize(NJS_TOKEN_ENUM);
njs_token_serialize(NJS_TOKEN_CLASS);
diff -r 9aed07704f30 -r 7717b6523cd4 src/njs_scope.c
--- a/src/njs_scope.c Fri Jun 18 15:01:13 2021 +0000
+++ b/src/njs_scope.c Fri Jun 18 15:01:48 2021 +0000
@@ -111,6 +111,13 @@ njs_scope_global_index(njs_vm_t *vm, con
}
+njs_value_t *
+njs_scope_value_get(njs_vm_t *vm, njs_index_t index)
+{
+ return njs_scope_value(vm, index);
+}
+
+
static njs_int_t
njs_scope_values_hash_test(njs_lvlhsh_query_t *lhq, void *data)
{
diff -r 9aed07704f30 -r 7717b6523cd4 src/njs_scope.h
--- a/src/njs_scope.h Fri Jun 18 15:01:13 2021 +0000
+++ b/src/njs_scope.h Fri Jun 18 15:01:48 2021 +0000
@@ -23,6 +23,7 @@ njs_value_t *njs_scope_create_index_valu
njs_value_t **njs_scope_make(njs_vm_t *vm, uint32_t count);
njs_index_t njs_scope_global_index(njs_vm_t *vm, const njs_value_t *src,
njs_uint_t runtime);
+njs_value_t *njs_scope_value_get(njs_vm_t *vm, njs_index_t index);
njs_inline njs_index_t
diff -r 9aed07704f30 -r 7717b6523cd4 src/njs_vmcode.c
--- a/src/njs_vmcode.c Fri Jun 18 15:01:13 2021 +0000
+++ b/src/njs_vmcode.c Fri Jun 18 15:01:48 2021 +0000
@@ -37,6 +37,7 @@ static njs_jump_off_t njs_vmcode_instanc
njs_value_t *constructor);
static njs_jump_off_t njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value,
njs_value_t *invld);
+static njs_jump_off_t njs_vmcode_debugger(njs_vm_t *vm);
static njs_jump_off_t njs_vmcode_return(njs_vm_t *vm, njs_value_t *invld,
njs_value_t *retval);
@@ -603,6 +604,10 @@ next:
ret = sizeof(njs_vmcode_2addr_t);
break;
+ case NJS_VMCODE_DEBUGGER:
+ ret = njs_vmcode_debugger(vm);
+ break;
+
default:
njs_internal_error(vm, "%d has retval", op);
goto error;
@@ -1517,6 +1522,30 @@ njs_vmcode_typeof(njs_vm_t *vm, njs_valu
static njs_jump_off_t
+njs_vmcode_debugger(njs_vm_t *vm)
+{
+ /*
+ * HOW TO DEBUG JS CODE:
+ * 1) put debugger instruction when certain condition is met
+ * in the JS code:
+ * function test() {
+ * if (<>) debugger;
+ * }
+ * 2) set a breakpoint to njs_vmcode_debugger() in gdb.
+ *
+ * To see the values of certain indices:
+ * 1) use njs -d test.js to dump the byte code
+ * 2) find an appropriate index around DEBUGGER instruction
+ * 3) in gdb: p *njs_scope_value_get(vm, <index as a hex literal>)
+ **/
+
+ njs_set_undefined(&vm->retval);
+
+ return sizeof(njs_vmcode_debugger_t);
+}
+
+
+static njs_jump_off_t
njs_string_concat(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2)
{
u_char *start;
diff -r 9aed07704f30 -r 7717b6523cd4 src/njs_vmcode.h
--- a/src/njs_vmcode.h Fri Jun 18 15:01:13 2021 +0000
+++ b/src/njs_vmcode.h Fri Jun 18 15:01:48 2021 +0000
@@ -126,6 +126,7 @@ enum {
NJS_VMCODE_TYPEOF,
NJS_VMCODE_VOID,
NJS_VMCODE_DELETE,
+ NJS_VMCODE_DEBUGGER,
NJS_VMCODE_NOP = 255
};
@@ -421,6 +422,12 @@ typedef struct {
} njs_vmcode_variable_t;
+typedef struct {
+ njs_vmcode_t code;
+ njs_index_t retval;
+} njs_vmcode_debugger_t;
+
+
njs_int_t njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc);
njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *constructor);
diff -r 9aed07704f30 -r 7717b6523cd4 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Fri Jun 18 15:01:13 2021 +0000
+++ b/src/test/njs_unit_test.c Fri Jun 18 15:01:48 2021 +0000
@@ -16562,6 +16562,23 @@ static njs_unit_test_t njs_test[] =
{ njs_str("parseFloat('-5.7e+abc')"),
njs_str("-5.7") },
+ /* debugger. */
+
+ { njs_str("debugger"),
+ njs_str("undefined") },
+
+ { njs_str("debugger;"),
+ njs_str("undefined") },
+
+ { njs_str("while (false) debugger;"),
+ njs_str("undefined") },
+
+ { njs_str("1 + debugger"),
+ njs_str("SyntaxError: Unexpected token \"debugger\" in 1") },
+
+ { njs_str("debugger + 1"),
+ njs_str("SyntaxError: Unexpected token \"+\" in 1") },
+
/* Top-level objects. */
{ njs_str("var global = this;"
More information about the nginx-devel
mailing list