[njs] eval() placeholder has been moved from the constructor table

Igor Sysoev igor at sysoev.ru
Wed Jun 1 12:50:25 UTC 2016


details:   http://hg.nginx.org/njs/rev/3f2480c38f8e
branches:  
changeset: 104:3f2480c38f8e
user:      Igor Sysoev <igor at sysoev.ru>
date:      Tue Apr 19 16:08:32 2016 +0300
description:
eval() placeholder has been moved from the constructor table
to the shared function table.

diffstat:

 njs/njs_builtin.c       |  90 ++++++++++++++++++++++++++++++++----------------
 njs/njs_generator.c     |   2 +-
 njs/njs_lexer_keyword.c |   1 +
 njs/njs_object.c        |   2 +-
 njs/njs_parser.c        |  35 +++++++++++++++++-
 njs/njs_parser.h        |   3 +
 njs/njs_vm.h            |  69 ++++++++++++++++++++-----------------
 7 files changed, 135 insertions(+), 67 deletions(-)

diffs (421 lines):

diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_builtin.c
--- a/njs/njs_builtin.c	Tue Apr 19 16:07:33 2016 +0300
+++ b/njs/njs_builtin.c	Tue Apr 19 16:08:32 2016 +0300
@@ -34,10 +34,10 @@ typedef struct {
 nxt_int_t
 njs_builtin_objects_create(njs_vm_t *vm)
 {
-    nxt_int_t                         ret;
-    nxt_uint_t                        i;
-    njs_object_t                      *objects, *prototypes;
-    njs_function_t                    *functions;
+    nxt_int_t       ret;
+    nxt_uint_t      i;
+    njs_object_t    *objects, *prototypes;
+    njs_function_t  *functions, *constructors;
 
     static const njs_object_init_t    *prototype_init[] = {
         &njs_object_prototype_init,
@@ -50,7 +50,7 @@ njs_builtin_objects_create(njs_vm_t *vm)
         &njs_date_prototype_init,
     };
 
-    static const njs_object_init_t    *function_init[] = {
+    static const njs_object_init_t    *constructor_init[] = {
         &njs_object_constructor_init,
         &njs_array_constructor_init,
         &njs_boolean_constructor_init,
@@ -59,11 +59,9 @@ njs_builtin_objects_create(njs_vm_t *vm)
         &njs_function_constructor_init,
         &njs_regexp_constructor_init,
         &njs_date_constructor_init,
-
-        &njs_eval_function_init,
     };
 
-    static const njs_function_init_t  native_functions[] = {
+    static const njs_function_init_t  native_constructors[] = {
         /* SunC does not allow empty array initialization. */
         { njs_object_constructor,   { 0 } },
         { njs_array_constructor,    { 0 } },
@@ -74,14 +72,21 @@ njs_builtin_objects_create(njs_vm_t *vm)
         { njs_regexp_constructor,
           { NJS_SKIP_ARG, NJS_STRING_ARG, NJS_STRING_ARG } },
         { njs_date_constructor,     { 0 } },
-
-        { njs_eval_function,        { 0 } },
     };
 
-    static const njs_object_init_t    *objects_init[] = {
+    static const njs_object_init_t    *object_init[] = {
         &njs_math_object_init,
     };
 
+    static const njs_object_init_t    *function_init[] = {
+        &njs_eval_function_init,
+    };
+
+    static const njs_function_init_t  native_functions[] = {
+        /* SunC does not allow empty array initialization. */
+        { njs_eval_function,        { 0 } },
+    };
+
     static const njs_object_prop_t    null_proto_property = {
         .type = NJS_WHITEOUT,
         .name = njs_string("__proto__"),
@@ -110,8 +115,8 @@ njs_builtin_objects_create(njs_vm_t *vm)
 
     for (i = NJS_OBJECT_MATH; i < NJS_OBJECT_MAX; i++) {
         ret = njs_object_hash_create(vm, &objects[i].shared_hash,
-                                     objects_init[i]->properties,
-                                     objects_init[i]->items);
+                                     object_init[i]->properties,
+                                     object_init[i]->items);
         if (nxt_slow_path(ret != NXT_OK)) {
             return NXT_ERROR;
         }
@@ -119,6 +124,27 @@ njs_builtin_objects_create(njs_vm_t *vm)
         objects[i].shared = 1;
     }
 
+    functions = vm->shared->functions;
+
+    for (i = NJS_FUNCTION_EVAL; i < NJS_FUNCTION_MAX; i++) {
+        ret = njs_object_hash_create(vm, &functions[i].object.shared_hash,
+                                     function_init[i]->properties,
+                                     function_init[i]->items);
+        if (nxt_slow_path(ret != NXT_OK)) {
+            return NXT_ERROR;
+        }
+
+        functions[i].object.shared = 1;
+        functions[i].native = 1;
+        functions[i].args_offset = 1;
+        functions[i].u.native = native_functions[i].native;
+        functions[i].args_types[0] = native_functions[i].args_types[0];
+        functions[i].args_types[1] = native_functions[i].args_types[1];
+        functions[i].args_types[2] = native_functions[i].args_types[2];
+        functions[i].args_types[3] = native_functions[i].args_types[3];
+        functions[i].args_types[4] = native_functions[i].args_types[4];
+    }
+
     prototypes = vm->shared->prototypes;
 
     for (i = NJS_PROTOTYPE_OBJECT; i < NJS_PROTOTYPE_MAX; i++) {
@@ -130,20 +156,22 @@ njs_builtin_objects_create(njs_vm_t *vm)
         }
     }
 
-    functions = vm->shared->functions;
+    constructors = vm->shared->constructors;
 
-    for (i = NJS_FUNCTION_OBJECT; i < NJS_FUNCTION_MAX; i++) {
-        functions[i].object.shared = 0;
-        functions[i].native = 1;
-        functions[i].args_offset = 1;
-        functions[i].u.native = native_functions[i].native;
-        functions[i].args_types[0] = native_functions[i].args_types[0];
-        functions[i].args_types[1] = native_functions[i].args_types[1];
-        functions[i].args_types[2] = native_functions[i].args_types[2];
+    for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_MAX; i++) {
+        constructors[i].object.shared = 0;
+        constructors[i].native = 1;
+        constructors[i].args_offset = 1;
+        constructors[i].u.native = native_constructors[i].native;
+        constructors[i].args_types[0] = native_constructors[i].args_types[0];
+        constructors[i].args_types[1] = native_constructors[i].args_types[1];
+        constructors[i].args_types[2] = native_constructors[i].args_types[2];
+        constructors[i].args_types[3] = native_constructors[i].args_types[3];
+        constructors[i].args_types[4] = native_constructors[i].args_types[4];
 
-        ret = njs_object_hash_create(vm, &functions[i].object.shared_hash,
-                                     function_init[i]->properties,
-                                     function_init[i]->items);
+        ret = njs_object_hash_create(vm, &constructors[i].object.shared_hash,
+                                     constructor_init[i]->properties,
+                                     constructor_init[i]->items);
         if (nxt_slow_path(ret != NXT_OK)) {
             return NXT_ERROR;
         }
@@ -200,11 +228,11 @@ njs_builtin_objects_clone(njs_vm_t *vm)
     njs_object_t  *function_prototype;
 
     /*
-     * Copy both prototypes and functions arrays by one memcpy()
+     * Copy both prototypes and constructors arrays by one memcpy()
      * because they are stored together.
      */
     size = NJS_PROTOTYPE_MAX * sizeof(njs_object_t)
-           + NJS_FUNCTION_MAX * sizeof(njs_function_t);
+           + NJS_CONSTRUCTOR_MAX * sizeof(njs_function_t);
 
     memcpy(vm->prototypes, vm->shared->prototypes, size);
 
@@ -212,14 +240,14 @@ njs_builtin_objects_clone(njs_vm_t *vm)
         vm->prototypes[i].__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT];
     }
 
-    function_prototype = &vm->prototypes[NJS_FUNCTION_FUNCTION];
+    function_prototype = &vm->prototypes[NJS_CONSTRUCTOR_FUNCTION];
     values = vm->scopes[NJS_SCOPE_GLOBAL];
 
-    for (i = NJS_FUNCTION_OBJECT; i < NJS_FUNCTION_MAX; i++) {
+    for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_MAX; i++) {
         values[i].type = NJS_FUNCTION;
         values[i].data.truth = 1;
-        values[i].data.u.function = &vm->functions[i];
-        vm->functions[i].object.__proto__ = function_prototype;
+        values[i].data.u.function = &vm->constructors[i];
+        vm->constructors[i].object.__proto__ = function_prototype;
     }
 
     return NXT_OK;
diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_generator.c
--- a/njs/njs_generator.c	Tue Apr 19 16:07:33 2016 +0300
+++ b/njs/njs_generator.c	Tue Apr 19 16:08:32 2016 +0300
@@ -286,7 +286,6 @@ njs_generator(njs_vm_t *vm, njs_parser_t
     case NJS_TOKEN_FUNCTION_CONSTRUCTOR:
     case NJS_TOKEN_REGEXP_CONSTRUCTOR:
     case NJS_TOKEN_DATE_CONSTRUCTOR:
-    case NJS_TOKEN_EVAL:
     case NJS_TOKEN_EXTERNAL:
         return NXT_OK;
 
@@ -294,6 +293,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t
         return njs_generate_name(vm, parser, node);
 
     case NJS_TOKEN_MATH:
+    case NJS_TOKEN_EVAL:
         return njs_generate_builtin_object(vm, parser, node);
 
     case NJS_TOKEN_FUNCTION:
diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_lexer_keyword.c
--- a/njs/njs_lexer_keyword.c	Tue Apr 19 16:07:33 2016 +0300
+++ b/njs/njs_lexer_keyword.c	Tue Apr 19 16:08:32 2016 +0300
@@ -86,6 +86,7 @@ static const njs_keyword_t  njs_keywords
     { nxt_string("Function"),      NJS_TOKEN_FUNCTION_CONSTRUCTOR, 0 },
     { nxt_string("RegExp"),        NJS_TOKEN_REGEXP_CONSTRUCTOR, 0 },
     { nxt_string("Date"),          NJS_TOKEN_DATE_CONSTRUCTOR, 0 },
+
     { nxt_string("eval"),          NJS_TOKEN_EVAL, 0 },
 
     /* Reserved words. */
diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_object.c
--- a/njs/njs_object.c	Tue Apr 19 16:07:33 2016 +0300
+++ b/njs/njs_object.c	Tue Apr 19 16:08:32 2016 +0300
@@ -359,7 +359,7 @@ njs_object_prototype_create(njs_vm_t *vm
 
     proto = NULL;
     function = value->data.u.function;
-    index = function - vm->functions;
+    index = function - vm->constructors;
 
     if (index >= 0 && index < NJS_PROTOTYPE_MAX) {
         proto = njs_property_prototype_create(vm, &function->object.hash,
diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_parser.c
--- a/njs/njs_parser.c	Tue Apr 19 16:07:33 2016 +0300
+++ b/njs/njs_parser.c	Tue Apr 19 16:08:32 2016 +0300
@@ -71,6 +71,8 @@ static njs_token_t njs_parser_grouping_e
     njs_parser_t *parser);
 static njs_token_t njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser,
     njs_parser_node_t *node);
+static njs_token_t njs_parser_builtin_function(njs_vm_t *vm,
+    njs_parser_t *parser, njs_parser_node_t *node);
 static njs_token_t njs_parser_object(njs_vm_t *vm, njs_parser_t *parser,
     njs_parser_node_t *obj);
 static njs_token_t njs_parser_array(njs_vm_t *vm, njs_parser_t *parser,
@@ -1627,8 +1629,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
         break;
 
     case NJS_TOKEN_EVAL:
-        node->index = NJS_INDEX_EVAL;
-        break;
+        return njs_parser_builtin_function(vm, parser, node);
 
     default:
         vm->exception = &njs_exception_syntax_error;
@@ -1672,6 +1673,36 @@ njs_parser_builtin_object(njs_vm_t *vm, 
 
 
 static njs_token_t
+njs_parser_builtin_function(njs_vm_t *vm, njs_parser_t *parser,
+    njs_parser_node_t *node)
+{
+    nxt_uint_t      index, level;
+    njs_value_t     *value;
+    njs_variable_t  *var;
+
+    var = njs_parser_variable(vm, parser, &level);
+    if (nxt_slow_path(var == NULL)) {
+        return NJS_TOKEN_ERROR;
+    }
+
+    var->state = NJS_VARIABLE_DECLARED;
+    node->index = var->index;
+
+    value = njs_variable_value(parser, node->index);
+
+    index = node->token - NJS_TOKEN_FIRST_FUNCTION;
+    value->data.u.function = &vm->shared->functions[index];
+    value->type = NJS_FUNCTION;
+    value->data.truth = 1;
+
+    parser->node = node;
+    parser->code_size += sizeof(njs_vmcode_object_copy_t);
+
+    return njs_lexer_token(parser->lexer);
+}
+
+
+static njs_token_t
 njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj)
 {
     njs_token_t        token;
diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_parser.h
--- a/njs/njs_parser.h	Tue Apr 19 16:07:33 2016 +0300
+++ b/njs/njs_parser.h	Tue Apr 19 16:08:32 2016 +0300
@@ -171,6 +171,9 @@ typedef enum {
     NJS_TOKEN_FUNCTION_CONSTRUCTOR,
     NJS_TOKEN_REGEXP_CONSTRUCTOR,
     NJS_TOKEN_DATE_CONSTRUCTOR,
+
+#define NJS_TOKEN_FIRST_FUNCTION   NJS_TOKEN_EVAL
+
     NJS_TOKEN_EVAL,
 
     NJS_TOKEN_RESERVED,
diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_vm.h
--- a/njs/njs_vm.h	Tue Apr 19 16:07:33 2016 +0300
+++ b/njs/njs_vm.h	Tue Apr 19 16:08:32 2016 +0300
@@ -86,7 +86,7 @@ typedef enum {
      * NJS_OBJECT_BOOLEAN, NJS_OBJECT_NUMBER, and NJS_OBJECT_STRING must be
      * in the same order as NJS_BOOLEAN, NJS_NUMBER, and NJS_STRING.  It is
      * used in njs_primitive_prototype_index().  The order of object types
-     * is used in vm->prototypes and vm->functions arrays.
+     * is used in vm->prototypes and vm->constructors arrays.
      */
     NJS_OBJECT          = 0x08,
     NJS_ARRAY           = 0x09,
@@ -664,7 +664,7 @@ typedef enum {
 
 
 enum njs_prototypes_e {
-    NJS_PROTOTYPE_OBJECT =   0,
+    NJS_PROTOTYPE_OBJECT =     0,
     NJS_PROTOTYPE_ARRAY,
     NJS_PROTOTYPE_BOOLEAN,
     NJS_PROTOTYPE_NUMBER,
@@ -672,7 +672,7 @@ enum njs_prototypes_e {
     NJS_PROTOTYPE_FUNCTION,
     NJS_PROTOTYPE_REGEXP,
     NJS_PROTOTYPE_DATE,
-#define NJS_PROTOTYPE_MAX    (NJS_PROTOTYPE_DATE + 1)
+#define NJS_PROTOTYPE_MAX      (NJS_PROTOTYPE_DATE + 1)
 };
 
 
@@ -680,24 +680,28 @@ enum njs_prototypes_e {
     (NJS_PROTOTYPE_BOOLEAN + ((type) - NJS_BOOLEAN))
 
 
-enum njs_functions_e {
-    NJS_FUNCTION_OBJECT =    NJS_PROTOTYPE_OBJECT,
-    NJS_FUNCTION_ARRAY =     NJS_PROTOTYPE_ARRAY,
-    NJS_FUNCTION_BOOLEAN =   NJS_PROTOTYPE_BOOLEAN,
-    NJS_FUNCTION_NUMBER =    NJS_PROTOTYPE_NUMBER,
-    NJS_FUNCTION_STRING =    NJS_PROTOTYPE_STRING,
-    NJS_FUNCTION_FUNCTION =  NJS_PROTOTYPE_FUNCTION,
-    NJS_FUNCTION_REGEXP =    NJS_PROTOTYPE_REGEXP,
-    NJS_FUNCTION_DATE =      NJS_PROTOTYPE_DATE,
-
-    NJS_FUNCTION_EVAL,
-#define NJS_FUNCTION_MAX     (NJS_FUNCTION_EVAL + 1)
+enum njs_constructor_e {
+    NJS_CONSTRUCTOR_OBJECT =   NJS_PROTOTYPE_OBJECT,
+    NJS_CONSTRUCTOR_ARRAY =    NJS_PROTOTYPE_ARRAY,
+    NJS_CONSTRUCTOR_BOOLEAN =  NJS_PROTOTYPE_BOOLEAN,
+    NJS_CONSTRUCTOR_NUMBER =   NJS_PROTOTYPE_NUMBER,
+    NJS_CONSTRUCTOR_STRING =   NJS_PROTOTYPE_STRING,
+    NJS_CONSTRUCTOR_FUNCTION = NJS_PROTOTYPE_FUNCTION,
+    NJS_CONSTRUCTOR_REGEXP =   NJS_PROTOTYPE_REGEXP,
+    NJS_CONSTRUCTOR_DATE =     NJS_PROTOTYPE_DATE,
+#define NJS_CONSTRUCTOR_MAX    (NJS_CONSTRUCTOR_DATE + 1)
 };
 
 
 enum njs_object_e {
-    NJS_OBJECT_MATH =        0,
-#define NJS_OBJECT_MAX       (NJS_OBJECT_MATH + 1)
+    NJS_OBJECT_MATH =          0,
+#define NJS_OBJECT_MAX         (NJS_OBJECT_MATH + 1)
+};
+
+
+enum njs_function_e {
+    NJS_FUNCTION_EVAL =        0,
+#define NJS_FUNCTION_MAX       (NJS_FUNCTION_EVAL + 1)
 };
 
 
@@ -708,18 +712,18 @@ enum njs_object_e {
     ((njs_index_t) (((value) << NJS_SCOPE_SHIFT) | NJS_SCOPE_GLOBAL))
 
 
-#define NJS_INDEX_OBJECT         njs_global_scope_index(NJS_FUNCTION_OBJECT)
-#define NJS_INDEX_ARRAY          njs_global_scope_index(NJS_FUNCTION_ARRAY)
-#define NJS_INDEX_BOOLEAN        njs_global_scope_index(NJS_FUNCTION_BOOLEAN)
-#define NJS_INDEX_NUMBER         njs_global_scope_index(NJS_FUNCTION_NUMBER)
-#define NJS_INDEX_STRING         njs_global_scope_index(NJS_FUNCTION_STRING)
-#define NJS_INDEX_FUNCTION       njs_global_scope_index(NJS_FUNCTION_FUNCTION)
-#define NJS_INDEX_REGEXP         njs_global_scope_index(NJS_FUNCTION_REGEXP)
-#define NJS_INDEX_DATE           njs_global_scope_index(NJS_FUNCTION_DATE)
-#define NJS_INDEX_EVAL           njs_global_scope_index(NJS_FUNCTION_EVAL)
+#define NJS_INDEX_OBJECT         njs_global_scope_index(NJS_CONSTRUCTOR_OBJECT)
+#define NJS_INDEX_ARRAY          njs_global_scope_index(NJS_CONSTRUCTOR_ARRAY)
+#define NJS_INDEX_BOOLEAN        njs_global_scope_index(NJS_CONSTRUCTOR_BOOLEAN)
+#define NJS_INDEX_NUMBER         njs_global_scope_index(NJS_CONSTRUCTOR_NUMBER)
+#define NJS_INDEX_STRING         njs_global_scope_index(NJS_CONSTRUCTOR_STRING)
+#define NJS_INDEX_FUNCTION                                                    \
+    njs_global_scope_index(NJS_CONSTRUCTOR_FUNCTION)
+#define NJS_INDEX_REGEXP         njs_global_scope_index(NJS_CONSTRUCTOR_REGEXP)
+#define NJS_INDEX_DATE           njs_global_scope_index(NJS_CONSTRUCTOR_DATE)
 
-#define NJS_INDEX_GLOBAL_RETVAL  njs_global_scope_index(NJS_FUNCTION_MAX)
-#define NJS_INDEX_GLOBAL_OFFSET  njs_scope_index(NJS_FUNCTION_MAX + 1)
+#define NJS_INDEX_GLOBAL_RETVAL  njs_global_scope_index(NJS_CONSTRUCTOR_MAX)
+#define NJS_INDEX_GLOBAL_OFFSET  njs_scope_index(NJS_CONSTRUCTOR_MAX + 1)
 
 
 #define njs_offset(index)                                                     \
@@ -767,12 +771,12 @@ struct njs_vm_s {
     nxt_lvlhsh_t             values_hash;
 
     /*
-     * The prototypes and functions arrays must be togther because
+     * The prototypes and constructors arrays must be togther because
      * they are copied from njs_vm_shared_t by single memcpy()
      * in njs_builtin_objects_clone().
      */
     njs_object_t             prototypes[NJS_PROTOTYPE_MAX];
-    njs_function_t           functions[NJS_FUNCTION_MAX];
+    njs_function_t           constructors[NJS_CONSTRUCTOR_MAX];
 
     nxt_mem_cache_pool_t     *mem_cache_pool;
 
@@ -802,13 +806,14 @@ struct njs_vm_shared_s {
     nxt_lvlhsh_t             function_prototype_hash;
 
     njs_object_t             objects[NJS_OBJECT_MAX];
+    njs_function_t           functions[NJS_FUNCTION_MAX];
 
     /*
-     * The prototypes and functions arrays must be togther because they are
+     * The prototypes and constructors arrays must be togther because they are
      * copied to njs_vm_t by single memcpy() in njs_builtin_objects_clone().
      */
     njs_object_t             prototypes[NJS_PROTOTYPE_MAX];
-    njs_function_t           functions[NJS_FUNCTION_MAX];
+    njs_function_t           constructors[NJS_CONSTRUCTOR_MAX];
 };
 
 



More information about the nginx-devel mailing list