[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