[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