[njs] Parser refactoring.

Alexander Borisov alexander.borisov at nginx.com
Fri May 29 17:01:07 UTC 2020


details:   https://hg.nginx.org/njs/rev/86f55a7dc4a4
branches:  
changeset: 1407:86f55a7dc4a4
user:      Alexander Borisov <alexander.borisov at nginx.com>
date:      Fri May 29 20:00:32 2020 +0300
description:
Parser refactoring.

diffstat:

 auto/sources                |     2 -
 src/njs_function.c          |     7 +-
 src/njs_lexer.c             |   202 +-
 src/njs_lexer.h             |    91 +-
 src/njs_lexer_tables.h      |   491 +-
 src/njs_module.c            |   175 +-
 src/njs_module.h            |     3 +-
 src/njs_parser.c            |  9622 ++++++++++++++++++++++++++++++++++--------
 src/njs_parser.h            |   316 +-
 src/njs_parser_expression.c |  1121 -----
 src/njs_parser_terminal.c   |  1296 -----
 src/njs_regexp.c            |    95 +-
 src/njs_regexp.h            |     4 +-
 src/njs_variable.c          |    24 +-
 src/njs_vm.c                |     3 +-
 src/test/njs_unit_test.c    |    57 +-
 test/njs_expect_test.exp    |     4 +-
 utils/lexer_keyword.py      |   129 +-
 18 files changed, 8745 insertions(+), 4897 deletions(-)

diffs (truncated from 14514 to 1000 lines):

diff -r 1d071c0e23e8 -r 86f55a7dc4a4 auto/sources
--- a/auto/sources	Fri May 29 14:49:36 2020 +0300
+++ b/auto/sources	Fri May 29 20:00:32 2020 +0300
@@ -49,8 +49,6 @@ NJS_LIB_SRCS=" \
    src/njs_lexer.c \
    src/njs_lexer_keyword.c \
    src/njs_parser.c \
-   src/njs_parser_terminal.c \
-   src/njs_parser_expression.c \
    src/njs_generator.c \
    src/njs_disassembler.c \
    src/njs_array_buffer.c \
diff -r 1d071c0e23e8 -r 86f55a7dc4a4 src/njs_function.c
--- a/src/njs_function.c	Fri May 29 14:49:36 2020 +0300
+++ b/src/njs_function.c	Fri May 29 20:00:32 2020 +0300
@@ -889,7 +889,9 @@ njs_function_constructor(njs_vm_t *vm, n
             return ret;
         }
 
-        njs_chb_append_literal(&chain, ",");
+        if (i != (nargs - 2)) {
+            njs_chb_append_literal(&chain, ",");
+        }
     }
 
     njs_chb_append_literal(&chain, "){");
@@ -923,9 +925,10 @@ njs_function_constructor(njs_vm_t *vm, n
         return ret;
     }
 
+    parser->vm = vm;
     parser->lexer = &lexer;
 
-    ret = njs_parser(vm, parser, NULL);
+    ret = njs_parser(parser, NULL);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
diff -r 1d071c0e23e8 -r 86f55a7dc4a4 src/njs_lexer.c
--- a/src/njs_lexer.c	Fri May 29 14:49:36 2020 +0300
+++ b/src/njs_lexer.c	Fri May 29 20:00:32 2020 +0300
@@ -27,10 +27,6 @@ static void njs_lexer_multi(njs_lexer_t 
     const njs_lexer_multi_t *multi, size_t length);
 static void njs_lexer_division(njs_lexer_t *lexer, njs_lexer_token_t *token);
 
-static njs_lexer_token_t *njs_lexer_token_push(njs_vm_t *vm,
-    njs_lexer_t *lexer);
-static njs_lexer_token_t *njs_lexer_token_pop(njs_lexer_t *lexer);
-
 
 const njs_lvlhsh_proto_t  njs_lexer_hash_proto
     njs_aligned(64) =
@@ -311,102 +307,19 @@ njs_lexer_init(njs_vm_t *vm, njs_lexer_t
 }
 
 
-njs_token_type_t
-njs_lexer_token(njs_vm_t *vm, njs_lexer_t *lexer)
-{
-    njs_lexer_token_t  *lt;
-
-    lexer->prev_start = lexer->start;
-
-    if (lexer->token != NULL) {
-        lexer->prev_type = lexer->token->type;
-        njs_mp_free(vm->mem_pool, lexer->token);
-    }
-
-    if (njs_queue_is_empty(&lexer->preread)) {
-        lt = njs_lexer_token_push(vm, lexer);
-        if (njs_slow_path(lt == NULL)) {
-            return NJS_TOKEN_ERROR;
-        }
-    }
-
-    lexer->token = njs_lexer_token_pop(lexer);
-
-    return lexer->token->type;
-}
-
-
-njs_token_type_t
-njs_lexer_peek_token(njs_vm_t *vm, njs_lexer_t *lexer, size_t offset)
-{
-    size_t             i;
-    njs_queue_link_t   *link;
-    njs_lexer_token_t  *lt;
-
-    /* GCC and Clang complain about uninitialized lt. */
-    lt = NULL;
-
-    link = njs_queue_first(&lexer->preread);
-
-    for (i = 0; i <= offset; i++) {
-
-        if (link != njs_queue_tail(&lexer->preread)) {
-
-            lt = njs_queue_link_data(link, njs_lexer_token_t, link);
-
-            /* NJS_TOKEN_DIVISION stands for regexp literal. */
-
-            if (lt->type == NJS_TOKEN_DIVISION || lt->type == NJS_TOKEN_END) {
-                break;
-            }
-
-            link = njs_queue_next(link);
-
-        } else {
-
-            lt = njs_lexer_token_push(vm, lexer);
-
-            if (njs_slow_path(lt == NULL)) {
-                return NJS_TOKEN_ERROR;
-            }
-        }
-    }
-
-    return lt->type;
-}
-
-
-njs_int_t
-njs_lexer_rollback(njs_vm_t *vm, njs_lexer_t *lexer)
-{
-    njs_lexer_token_t  *lt;
-
-    lt = njs_mp_zalloc(vm->mem_pool, sizeof(njs_lexer_token_t));
-    if (njs_slow_path(lt == NULL)) {
-        return NJS_ERROR;
-    }
-
-    *lt = *lexer->token;
-
-    njs_queue_insert_head(&lexer->preread, &lt->link);
-
-    return NJS_OK;
-}
-
-
-static njs_lexer_token_t *
-njs_lexer_token_push(njs_vm_t *vm, njs_lexer_t *lexer)
+njs_inline njs_lexer_token_t *
+njs_lexer_next_token(njs_lexer_t *lexer)
 {
     njs_int_t          ret;
     njs_lexer_token_t  *token;
 
-    token = njs_mp_zalloc(vm->mem_pool, sizeof(njs_lexer_token_t));
+    token = njs_mp_zalloc(lexer->mem_pool, sizeof(njs_lexer_token_t));
     if (njs_slow_path(token == NULL)) {
         return NULL;
     }
 
     do {
-        ret = njs_lexer_next_token(lexer, token);
+        ret = njs_lexer_make_token(lexer, token);
         if (njs_slow_path(ret != NJS_OK)) {
             return NULL;
         }
@@ -419,20 +332,109 @@ njs_lexer_token_push(njs_vm_t *vm, njs_l
 }
 
 
-static njs_lexer_token_t *
-njs_lexer_token_pop(njs_lexer_t *lexer)
+njs_lexer_token_t *
+njs_lexer_token(njs_lexer_t *lexer, njs_bool_t with_end_line)
 {
-    njs_queue_link_t  *lnk;
+    njs_queue_link_t   *lnk;
+    njs_lexer_token_t  *token;
 
     lnk = njs_queue_first(&lexer->preread);
-    njs_queue_remove(lnk);
+
+    while (lnk != njs_queue_head(&lexer->preread)) {
+        token = njs_queue_link_data(lnk, njs_lexer_token_t, link);
+
+        if (!with_end_line && token->type == NJS_TOKEN_LINE_END) {
+            lexer->prev_type = token->type;
+
+            lnk = njs_queue_next(&token->link);
+            continue;
+        }
+
+        return token;
+    }
+
+    do {
+        token = njs_lexer_next_token(lexer);
+        if (token == NULL) {
+            return NULL;
+        }
+
+        if (!with_end_line && token->type == NJS_TOKEN_LINE_END) {
+            lexer->prev_type = token->type;
+            continue;
+        }
+
+        break;
+
+    } while (1);
+
+    return token;
+}
+
+
+njs_lexer_token_t *
+njs_lexer_peek_token(njs_lexer_t *lexer, njs_lexer_token_t *current,
+    njs_bool_t with_end_line)
+{
+    njs_queue_link_t   *lnk;
+    njs_lexer_token_t  *token;
+
+    lnk = njs_queue_next(&current->link);
+
+    while (lnk != njs_queue_head(&lexer->preread)) {
+        token = njs_queue_link_data(lnk, njs_lexer_token_t, link);
 
-    return njs_queue_link_data(lnk, njs_lexer_token_t, link);
+        if (!with_end_line && token->type == NJS_TOKEN_LINE_END) {
+            lnk = njs_queue_next(&token->link);
+            continue;
+        }
+
+        return token;
+    }
+
+    do {
+        token = njs_lexer_next_token(lexer);
+        if (token == NULL) {
+            return NULL;
+        }
+
+        if (!with_end_line && token->type == NJS_TOKEN_LINE_END) {
+            continue;
+        }
+
+        break;
+
+    } while (1);
+
+    return token;
+}
+
+
+void
+njs_lexer_consume_token(njs_lexer_t *lexer, unsigned length)
+{
+    njs_queue_link_t   *lnk;
+    njs_lexer_token_t  *token;
+
+    while (length > 0) {
+        lnk = njs_queue_first(&lexer->preread);
+        token = njs_queue_link_data(lnk, njs_lexer_token_t, link);
+
+        lexer->prev_type = token->type;
+
+        if (token->type != NJS_TOKEN_LINE_END) {
+            length--;
+        }
+
+        njs_queue_remove(lnk);
+
+        njs_mp_free(lexer->mem_pool, token);
+    }
 }
 
 
 njs_int_t
-njs_lexer_next_token(njs_lexer_t *lexer, njs_lexer_token_t *token)
+njs_lexer_make_token(njs_lexer_t *lexer, njs_lexer_token_t *token)
 {
     u_char  c, *p;
 
@@ -446,7 +448,6 @@ njs_lexer_next_token(njs_lexer_t *lexer,
         }
     }
 
-    lexer->keyword = 0;
     token->type = njs_tokens[c];
 
     switch (token->type) {
@@ -565,6 +566,7 @@ njs_lexer_next_token(njs_lexer_t *lexer,
         /* Fall through. */
 
     default:
+        token->line = lexer->line;
         token->text.start = lexer->start - 1;
         token->text.length = lexer->start - token->text.start;
 
@@ -694,12 +696,14 @@ njs_lexer_word(njs_lexer_t *lexer, njs_l
         }
 
         token->type = NJS_TOKEN_NAME;
+        token->keyword_type = NJS_KEYWORD_TYPE_UNDEF;
 
     } else {
         entry = &key_entry->value->entry;
         token->type = key_entry->value->type;
 
-        lexer->keyword = 1;
+        token->keyword_type = NJS_KEYWORD_TYPE_KEYWORD;
+        token->keyword_type |= key_entry->value->reserved;
     }
 
     token->unique_id = (uintptr_t) entry;
diff -r 1d071c0e23e8 -r 86f55a7dc4a4 src/njs_lexer.h
--- a/src/njs_lexer.h	Fri May 29 14:49:36 2020 +0300
+++ b/src/njs_lexer.h	Fri May 29 20:00:32 2020 +0300
@@ -99,6 +99,7 @@ typedef enum {
     NJS_TOKEN_COALESCE,
 
     NJS_TOKEN_IN,
+    NJS_TOKEN_OF,
     NJS_TOKEN_INSTANCEOF,
     NJS_TOKEN_TYPEOF,
     NJS_TOKEN_VOID,
@@ -178,7 +179,14 @@ typedef enum {
     NJS_TOKEN_IMPORT,
     NJS_TOKEN_EXPORT,
 
+    NJS_TOKEN_TARGET,
+
+    NJS_TOKEN_FROM,
+
+    NJS_TOKEN_META,
+
     NJS_TOKEN_AWAIT,
+    NJS_TOKEN_ASYNC,
     NJS_TOKEN_CLASS,
     NJS_TOKEN_CONST,
     NJS_TOKEN_DEBUGGER,
@@ -198,6 +206,13 @@ typedef enum {
 } njs_token_type_t;
 
 
+typedef enum {
+    NJS_KEYWORD_TYPE_UNDEF    = 0,
+    NJS_KEYWORD_TYPE_RESERVED = 1,
+    NJS_KEYWORD_TYPE_KEYWORD  = 2
+} njs_keyword_type_t;
+
+
 typedef struct {
     njs_str_t                       name;
 } njs_lexer_entry_t;
@@ -206,6 +221,7 @@ typedef struct {
 typedef struct {
     njs_lexer_entry_t               entry;
     njs_token_type_t                type;
+    njs_bool_t                      reserved;
 } njs_keyword_t;
 
 
@@ -220,6 +236,7 @@ typedef struct {
 
 typedef struct {
     njs_token_type_t                type:16;
+    njs_keyword_type_t              keyword_type;
     uint32_t                        line;
     uintptr_t                       unique_id;
     njs_str_t                       text;
@@ -231,10 +248,10 @@ typedef struct {
 typedef struct {
     njs_lexer_token_t               *token;
     njs_queue_t                     preread; /*  of njs_lexer_token_t */
-    uint8_t                         keyword;
 
     u_char                          *prev_start;
     njs_token_type_t                prev_type:16;
+    njs_token_type_t                last_type:16;
 
     uint32_t                        line;
     njs_str_t                       file;
@@ -251,12 +268,12 @@ typedef struct {
 njs_int_t njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, njs_str_t *file,
     u_char *start, u_char *end);
 
-njs_token_type_t njs_lexer_token(njs_vm_t *vm, njs_lexer_t *lexer);
-njs_token_type_t njs_lexer_peek_token(njs_vm_t *vm, njs_lexer_t *lexer,
-    size_t offset);
-njs_int_t njs_lexer_rollback(njs_vm_t *vm, njs_lexer_t *lexer);
-
-njs_int_t njs_lexer_next_token(njs_lexer_t *lexer, njs_lexer_token_t *token);
+njs_lexer_token_t *njs_lexer_token(njs_lexer_t *lexer,
+    njs_bool_t with_end_line);
+njs_lexer_token_t *njs_lexer_peek_token(njs_lexer_t *lexer,
+    njs_lexer_token_t *current, njs_bool_t with_end_line);
+void njs_lexer_consume_token(njs_lexer_t *lexer, unsigned length);
+njs_int_t njs_lexer_make_token(njs_lexer_t *lexer, njs_lexer_token_t *token);
 
 const njs_lexer_keyword_entry_t *njs_lexer_keyword(const u_char *key,
     size_t length);
@@ -270,6 +287,66 @@ njs_lexer_entry(uintptr_t unique_id)
 }
 
 
+njs_inline njs_bool_t
+njs_lexer_token_is_keyword(njs_lexer_token_t *token)
+{
+    return token->keyword_type & NJS_KEYWORD_TYPE_KEYWORD;
+}
+
+
+njs_inline njs_bool_t
+njs_lexer_token_is_reserved(njs_lexer_token_t *token)
+{
+    return token->keyword_type & NJS_KEYWORD_TYPE_RESERVED;
+}
+
+
+njs_inline njs_bool_t
+njs_lexer_token_is_name(njs_lexer_token_t *token)
+{
+    return token->type == NJS_TOKEN_NAME
+           || (!njs_lexer_token_is_reserved(token)
+               && njs_lexer_token_is_keyword(token));
+}
+
+
+njs_inline njs_bool_t
+njs_lexer_token_is_identifier_name(njs_lexer_token_t *token)
+{
+    return token->type == NJS_TOKEN_NAME || njs_lexer_token_is_keyword(token);
+}
+
+
+njs_inline njs_bool_t
+njs_lexer_token_is_binding_identifier(njs_lexer_token_t *token)
+{
+    switch (token->type) {
+    case NJS_TOKEN_NAME:
+    case NJS_TOKEN_YIELD:
+    case NJS_TOKEN_AWAIT:
+        return 1;
+
+    default:
+        return (!njs_lexer_token_is_reserved(token)
+                && njs_lexer_token_is_keyword(token));
+    };
+}
+
+
+njs_inline njs_bool_t
+njs_lexer_token_is_label_identifier(njs_lexer_token_t *token)
+{
+    return njs_lexer_token_is_binding_identifier(token);
+}
+
+
+njs_inline njs_bool_t
+njs_lexer_token_is_identifier_reference(njs_lexer_token_t *token)
+{
+    return njs_lexer_token_is_binding_identifier(token);
+}
+
+
 extern const njs_lvlhsh_proto_t  njs_lexer_hash_proto;
 
 
diff -r 1d071c0e23e8 -r 86f55a7dc4a4 src/njs_lexer_tables.h
--- a/src/njs_lexer_tables.h	Fri May 29 14:49:36 2020 +0300
+++ b/src/njs_lexer_tables.h	Fri May 29 20:00:32 2020 +0300
@@ -10,135 +10,428 @@
 #define _NJS_LEXER_TABLES_H_INCLUDED_
 
 
-static const njs_keyword_t njs_lexer_kws[48] =
+static const njs_keyword_t njs_lexer_kws[53] =
 {
-    { .entry = { njs_str("null") }, .type = NJS_TOKEN_NULL },
-    { .entry = { njs_str("false") }, .type = NJS_TOKEN_FALSE },
-    { .entry = { njs_str("true") }, .type = NJS_TOKEN_TRUE },
-    { .entry = { njs_str("in") }, .type = NJS_TOKEN_IN },
-    { .entry = { njs_str("typeof") }, .type = NJS_TOKEN_TYPEOF },
-    { .entry = { njs_str("instanceof") }, .type = NJS_TOKEN_INSTANCEOF },
-    { .entry = { njs_str("void") }, .type = NJS_TOKEN_VOID },
-    { .entry = { njs_str("new") }, .type = NJS_TOKEN_NEW },
-    { .entry = { njs_str("delete") }, .type = NJS_TOKEN_DELETE },
-    { .entry = { njs_str("yield") }, .type = NJS_TOKEN_YIELD },
-    { .entry = { njs_str("var") }, .type = NJS_TOKEN_VAR },
-    { .entry = { njs_str("if") }, .type = NJS_TOKEN_IF },
-    { .entry = { njs_str("else") }, .type = NJS_TOKEN_ELSE },
-    { .entry = { njs_str("while") }, .type = NJS_TOKEN_WHILE },
-    { .entry = { njs_str("do") }, .type = NJS_TOKEN_DO },
-    { .entry = { njs_str("for") }, .type = NJS_TOKEN_FOR },
-    { .entry = { njs_str("break") }, .type = NJS_TOKEN_BREAK },
-    { .entry = { njs_str("continue") }, .type = NJS_TOKEN_CONTINUE },
-    { .entry = { njs_str("switch") }, .type = NJS_TOKEN_SWITCH },
-    { .entry = { njs_str("case") }, .type = NJS_TOKEN_CASE },
-    { .entry = { njs_str("default") }, .type = NJS_TOKEN_DEFAULT },
-    { .entry = { njs_str("function") }, .type = NJS_TOKEN_FUNCTION },
-    { .entry = { njs_str("return") }, .type = NJS_TOKEN_RETURN },
-    { .entry = { njs_str("with") }, .type = NJS_TOKEN_WITH },
-    { .entry = { njs_str("try") }, .type = NJS_TOKEN_TRY },
-    { .entry = { njs_str("catch") }, .type = NJS_TOKEN_CATCH },
-    { .entry = { njs_str("finally") }, .type = NJS_TOKEN_FINALLY },
-    { .entry = { njs_str("throw") }, .type = NJS_TOKEN_THROW },
-    { .entry = { njs_str("import") }, .type = NJS_TOKEN_IMPORT },
-    { .entry = { njs_str("export") }, .type = NJS_TOKEN_EXPORT },
-    { .entry = { njs_str("this") }, .type = NJS_TOKEN_THIS },
-    { .entry = { njs_str("arguments") }, .type = NJS_TOKEN_ARGUMENTS },
-    { .entry = { njs_str("eval") }, .type = NJS_TOKEN_EVAL },
-    { .entry = { njs_str("await") }, .type = NJS_TOKEN_AWAIT },
-    { .entry = { njs_str("class") }, .type = NJS_TOKEN_CLASS },
-    { .entry = { njs_str("const") }, .type = NJS_TOKEN_CONST },
-    { .entry = { njs_str("debugger") }, .type = NJS_TOKEN_DEBUGGER },
-    { .entry = { njs_str("enum") }, .type = NJS_TOKEN_ENUM },
-    { .entry = { njs_str("extends") }, .type = NJS_TOKEN_EXTENDS },
-    { .entry = { njs_str("implements") }, .type = NJS_TOKEN_IMPLEMENTS },
-    { .entry = { njs_str("interface") }, .type = NJS_TOKEN_INTERFACE },
-    { .entry = { njs_str("let") }, .type = NJS_TOKEN_LET },
-    { .entry = { njs_str("package") }, .type = NJS_TOKEN_PACKAGE },
-    { .entry = { njs_str("private") }, .type = NJS_TOKEN_PRIVATE },
-    { .entry = { njs_str("protected") }, .type = NJS_TOKEN_PROTECTED },
-    { .entry = { njs_str("public") }, .type = NJS_TOKEN_PUBLIC },
-    { .entry = { njs_str("static") }, .type = NJS_TOKEN_STATIC },
-    { .entry = { njs_str("super") }, .type = NJS_TOKEN_SUPER },
+    {
+        .entry = { njs_str("arguments") },
+        .type = NJS_TOKEN_ARGUMENTS,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("async") },
+        .type = NJS_TOKEN_ASYNC,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("await") },
+        .type = NJS_TOKEN_AWAIT,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("break") },
+        .type = NJS_TOKEN_BREAK,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("case") },
+        .type = NJS_TOKEN_CASE,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("catch") },
+        .type = NJS_TOKEN_CATCH,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("class") },
+        .type = NJS_TOKEN_CLASS,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("const") },
+        .type = NJS_TOKEN_CONST,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("continue") },
+        .type = NJS_TOKEN_CONTINUE,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("debugger") },
+        .type = NJS_TOKEN_DEBUGGER,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("default") },
+        .type = NJS_TOKEN_DEFAULT,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("delete") },
+        .type = NJS_TOKEN_DELETE,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("do") },
+        .type = NJS_TOKEN_DO,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("else") },
+        .type = NJS_TOKEN_ELSE,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("enum") },
+        .type = NJS_TOKEN_ENUM,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("eval") },
+        .type = NJS_TOKEN_EVAL,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("export") },
+        .type = NJS_TOKEN_EXPORT,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("extends") },
+        .type = NJS_TOKEN_EXTENDS,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("false") },
+        .type = NJS_TOKEN_FALSE,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("finally") },
+        .type = NJS_TOKEN_FINALLY,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("for") },
+        .type = NJS_TOKEN_FOR,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("from") },
+        .type = NJS_TOKEN_FROM,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("function") },
+        .type = NJS_TOKEN_FUNCTION,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("if") },
+        .type = NJS_TOKEN_IF,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("implements") },
+        .type = NJS_TOKEN_IMPLEMENTS,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("import") },
+        .type = NJS_TOKEN_IMPORT,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("in") },
+        .type = NJS_TOKEN_IN,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("instanceof") },
+        .type = NJS_TOKEN_INSTANCEOF,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("interface") },
+        .type = NJS_TOKEN_INTERFACE,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("let") },
+        .type = NJS_TOKEN_LET,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("meta") },
+        .type = NJS_TOKEN_META,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("new") },
+        .type = NJS_TOKEN_NEW,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("null") },
+        .type = NJS_TOKEN_NULL,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("of") },
+        .type = NJS_TOKEN_OF,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("package") },
+        .type = NJS_TOKEN_PACKAGE,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("private") },
+        .type = NJS_TOKEN_PRIVATE,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("protected") },
+        .type = NJS_TOKEN_PROTECTED,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("public") },
+        .type = NJS_TOKEN_PUBLIC,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("return") },
+        .type = NJS_TOKEN_RETURN,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("static") },
+        .type = NJS_TOKEN_STATIC,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("super") },
+        .type = NJS_TOKEN_SUPER,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("switch") },
+        .type = NJS_TOKEN_SWITCH,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("target") },
+        .type = NJS_TOKEN_TARGET,
+        .reserved = 0
+    },
+
+    {
+        .entry = { njs_str("this") },
+        .type = NJS_TOKEN_THIS,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("throw") },
+        .type = NJS_TOKEN_THROW,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("true") },
+        .type = NJS_TOKEN_TRUE,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("try") },
+        .type = NJS_TOKEN_TRY,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("typeof") },
+        .type = NJS_TOKEN_TYPEOF,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("var") },
+        .type = NJS_TOKEN_VAR,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("void") },
+        .type = NJS_TOKEN_VOID,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("while") },
+        .type = NJS_TOKEN_WHILE,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("with") },
+        .type = NJS_TOKEN_WITH,
+        .reserved = 1
+    },
+
+    {
+        .entry = { njs_str("yield") },
+        .type = NJS_TOKEN_YIELD,
+        .reserved = 1
+    },
 };
 
 
-static const njs_lexer_keyword_entry_t njs_lexer_keyword_entries[75] =
+static const njs_lexer_keyword_entry_t njs_lexer_keyword_entries[99] =
 {
-    { NULL, NULL, 74, 0 },
-    { "case", &njs_lexer_kws[19], 4, 0 },
-    { "continue", &njs_lexer_kws[17], 8, 0 },
-    { "do", &njs_lexer_kws[14], 2, 0 },
-    { "enum", &njs_lexer_kws[37], 4, 0 },
-    { "extends", &njs_lexer_kws[38], 7, 0 },
-    { "instanceof", &njs_lexer_kws[5], 10, 0 },
-    { "public", &njs_lexer_kws[45], 6, 0 },
-    { "static", &njs_lexer_kws[46], 6, 0 },
-    { "in", &njs_lexer_kws[3], 2, 0 },
-    { "await", &njs_lexer_kws[33], 5, 0 },
-    { "private", &njs_lexer_kws[43], 7, 0 },
+    { NULL, NULL, 98, 0 },
+    { "continue", &njs_lexer_kws[8], 8, 0 },
+    { "finally", &njs_lexer_kws[19], 7, 0 },
+    { "return", &njs_lexer_kws[38], 6, 0 },
+    { "static", &njs_lexer_kws[39], 6, 0 },
+    { "async", &njs_lexer_kws[1], 5, 0 },
+    { "break", &njs_lexer_kws[3], 5, 0 },
+    { "interface", &njs_lexer_kws[28], 9, 0 },
+    { "case", &njs_lexer_kws[4], 4, 0 },
+    { "import", &njs_lexer_kws[25], 6, 0 },
+    { "protected", &njs_lexer_kws[36], 9, 0 },
+    { "switch", &njs_lexer_kws[41], 6, 0 },
+    { "catch", &njs_lexer_kws[5], 5, 1 },
+    { "delete", &njs_lexer_kws[11], 6, 0 },
+    { "else", &njs_lexer_kws[13], 4, 0 },
+    { "private", &njs_lexer_kws[35], 7, 0 },
+    { "extends", &njs_lexer_kws[17], 7, 0 },
+    { "this", &njs_lexer_kws[43], 4, 0 },
+    { "false", &njs_lexer_kws[18], 5, 0 },
+    { "await", &njs_lexer_kws[2], 5, 0 },
     { NULL, NULL, 0, 0 },
-    { "debugger", &njs_lexer_kws[36], 8, 0 },
-    { "for", &njs_lexer_kws[15], 3, 1 },
+    { "public", &njs_lexer_kws[37], 6, 0 },
     { NULL, NULL, 0, 0 },
-    { "catch", &njs_lexer_kws[25], 5, 0 },
+    { "class", &njs_lexer_kws[6], 5, 0 },
+    { "const", &njs_lexer_kws[7], 5, 4 },
     { NULL, NULL, 0, 0 },
-    { "super", &njs_lexer_kws[47], 5, 2 },
+    { "try", &njs_lexer_kws[46], 3, 0 },
+    { "null", &njs_lexer_kws[32], 4, 0 },
     { NULL, NULL, 0, 0 },
-    { "const", &njs_lexer_kws[35], 5, 0 },
+    { "do", &njs_lexer_kws[12], 2, 0 },
+    { "var", &njs_lexer_kws[48], 3, 0 },
+    { "if", &njs_lexer_kws[23], 2, 7 },
+    { "implements", &njs_lexer_kws[24], 10, 0 },
+    { "with", &njs_lexer_kws[51], 4, 0 },
     { NULL, NULL, 0, 0 },
-    { "false", &njs_lexer_kws[1], 5, 0 },
-    { "with", &njs_lexer_kws[23], 4, 0 },
-    { "implements", &njs_lexer_kws[39], 10, 0 },
-    { "this", &njs_lexer_kws[30], 4, 0 },
-    { "let", &njs_lexer_kws[41], 3, 0 },
+    { "eval", &njs_lexer_kws[15], 4, 9 },
+    { NULL, NULL, 0, 0 },
+    { "target", &njs_lexer_kws[42], 6, 0 },
+    { "enum", &njs_lexer_kws[14], 4, 10 },
+    { "instanceof", &njs_lexer_kws[27], 10, 0 },
+    { NULL, NULL, 0, 0 },
+    { "debugger", &njs_lexer_kws[9], 8, 0 },
     { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
-    { "true", &njs_lexer_kws[2], 4, 0 },
+    { "default", &njs_lexer_kws[10], 7, 0 },
+    { "void", &njs_lexer_kws[49], 4, 0 },
+    { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
-    { "export", &njs_lexer_kws[29], 6, 0 },
     { NULL, NULL, 0, 0 },
-    { "interface", &njs_lexer_kws[40], 9, 0 },
+    { "from", &njs_lexer_kws[21], 4, 0 },
+    { "package", &njs_lexer_kws[34], 7, 15 },
     { NULL, NULL, 0, 0 },
-    { "eval", &njs_lexer_kws[32], 4, 0 },
-    { "protected", &njs_lexer_kws[44], 9, 0 },
-    { "while", &njs_lexer_kws[13], 5, 0 },
+    { "yield", &njs_lexer_kws[52], 5, 0 },
     { NULL, NULL, 0, 0 },
-    { "void", &njs_lexer_kws[6], 4, 0 },
+    { NULL, NULL, 0, 0 },
+    { "of", &njs_lexer_kws[33], 2, 0 },
     { NULL, NULL, 0, 0 },
-    { "return", &njs_lexer_kws[22], 6, 0 },
+    { "function", &njs_lexer_kws[22], 8, 0 },
     { NULL, NULL, 0, 0 },
-    { "delete", &njs_lexer_kws[8], 6, 0 },
-    { "yield", &njs_lexer_kws[9], 5, 0 },
-    { "null", &njs_lexer_kws[0], 4, 0 },
-    { "throw", &njs_lexer_kws[27], 5, 0 },
+    { "true", &njs_lexer_kws[45], 4, 16 },
+    { "new", &njs_lexer_kws[31], 3, 0 },
+    { "export", &njs_lexer_kws[16], 6, 0 },
     { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
-    { "import", &njs_lexer_kws[28], 6, 0 },
+    { NULL, NULL, 0, 0 },
+    { NULL, NULL, 0, 0 },
+    { "for", &njs_lexer_kws[20], 3, 0 },
+    { "while", &njs_lexer_kws[50], 5, 0 },
     { NULL, NULL, 0, 0 },
-    { "switch", &njs_lexer_kws[18], 6, 0 },
-    { "try", &njs_lexer_kws[24], 3, 0 },
-    { "function", &njs_lexer_kws[21], 8, 0 },
+    { NULL, NULL, 0, 0 },
+    { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
-    { "if", &njs_lexer_kws[11], 2, 0 },
-    { "break", &njs_lexer_kws[16], 5, 0 },
+    { NULL, NULL, 0, 0 },
+    { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
-    { "var", &njs_lexer_kws[10], 3, 4 },
+    { "typeof", &njs_lexer_kws[47], 6, 0 },
+    { NULL, NULL, 0, 0 },
+    { NULL, NULL, 0, 0 },
+    { "super", &njs_lexer_kws[40], 5, 0 },
     { NULL, NULL, 0, 0 },
-    { "default", &njs_lexer_kws[20], 7, 0 },
-    { "arguments", &njs_lexer_kws[31], 9, 6 },
-    { "finally", &njs_lexer_kws[26], 7, 0 },
+    { NULL, NULL, 0, 0 },
+    { NULL, NULL, 0, 0 },
+    { "let", &njs_lexer_kws[29], 3, 19 },
+    { "in", &njs_lexer_kws[26], 2, 0 },
     { NULL, NULL, 0, 0 },
-    { "else", &njs_lexer_kws[12], 4, 0 },
-    { "class", &njs_lexer_kws[34], 5, 7 },
-    { "new", &njs_lexer_kws[7], 3, 8 },
+    { NULL, NULL, 0, 0 },
+    { "throw", &njs_lexer_kws[44], 5, 0 },
+    { "arguments", &njs_lexer_kws[0], 9, 0 },
+    { "meta", &njs_lexer_kws[30], 4, 0 },
     { NULL, NULL, 0, 0 },
-    { "package", &njs_lexer_kws[42], 7, 11 },
-    { "typeof", &njs_lexer_kws[4], 6, 0 },
+    { NULL, NULL, 0, 0 },
+    { NULL, NULL, 0, 0 },
+    { NULL, NULL, 0, 0 },
+    { NULL, NULL, 0, 0 },
     { NULL, NULL, 0, 0 },
 };
 
diff -r 1d071c0e23e8 -r 86f55a7dc4a4 src/njs_module.c
--- a/src/njs_module.c	Fri May 29 14:49:36 2020 +0300
+++ b/src/njs_module.c	Fri May 29 20:00:32 2020 +0300
@@ -15,6 +15,19 @@ typedef struct {
 } njs_module_info_t;
 
 
+typedef struct {


More information about the nginx-devel mailing list