to the shared function table.
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,
&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,
&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 } },
{ 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__"),
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;
}
objects[i].shared = 1;
}
- prototypes = vm->shared->prototypes;
+ functions = vm->shared->functions;
- for (i = NJS_PROTOTYPE_OBJECT; i < NJS_PROTOTYPE_MAX; i++) {
- ret = njs_object_hash_create(vm, &prototypes[i].shared_hash,
- prototype_init[i]->properties,
- prototype_init[i]->items);
+ 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 = vm->shared->functions;
- for (i = NJS_FUNCTION_OBJECT; i < NJS_FUNCTION_MAX; i++) {
- functions[i].object.shared = 0;
+ 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];
+ }
- ret = njs_object_hash_create(vm, &functions[i].object.shared_hash,
- function_init[i]->properties,
- function_init[i]->items);
+ prototypes = vm->shared->prototypes;
+
+ for (i = NJS_PROTOTYPE_OBJECT; i < NJS_PROTOTYPE_MAX; i++) {
+ ret = njs_object_hash_create(vm, &prototypes[i].shared_hash,
+ prototype_init[i]->properties,
+ prototype_init[i]->items);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NXT_ERROR;
+ }
+ }
+
+ constructors = vm->shared->constructors;
+
+ 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, &constructors[i].object.shared_hash,
+ constructor_init[i]->properties,
+ constructor_init[i]->items);
if (nxt_slow_path(ret != NXT_OK)) {
return NXT_ERROR;
}
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);
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;
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;
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:
{ 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. */
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,
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,
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;
}
+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_FUNCTION_CONSTRUCTOR,
NJS_TOKEN_REGEXP_CONSTRUCTOR,
NJS_TOKEN_DATE_CONSTRUCTOR,
+
+#define NJS_TOKEN_FIRST_FUNCTION NJS_TOKEN_EVAL
+
NJS_TOKEN_EVAL,
NJS_TOKEN_RESERVED,
* 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,
enum njs_prototypes_e {
- NJS_PROTOTYPE_OBJECT = 0,
+ NJS_PROTOTYPE_OBJECT = 0,
NJS_PROTOTYPE_ARRAY,
NJS_PROTOTYPE_BOOLEAN,
NJS_PROTOTYPE_NUMBER,
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)
};
(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)
};
((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) \
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;
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];
};