njs_parser_node_t *node);
static nxt_int_t njs_generate_builtin_object(njs_vm_t *vm,
njs_generator_t *generator, njs_parser_node_t *node);
-static nxt_int_t njs_generate_arguments_object(njs_vm_t *vm,
- njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_variable(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
static nxt_int_t njs_generate_var_statement(njs_vm_t *vm,
static nxt_int_t njs_generate_function_scope(njs_vm_t *vm,
njs_function_lambda_t *lambda, njs_parser_node_t *node,
const nxt_str_t *name);
-static nxt_int_t njs_generate_argument_closures(njs_vm_t *vm,
+static nxt_int_t njs_generate_lambda_variables(njs_vm_t *vm,
njs_generator_t *generator, njs_parser_node_t *node);
static nxt_int_t njs_generate_return_statement(njs_vm_t *vm,
njs_generator_t *generator, njs_parser_node_t *node);
return NXT_OK;
case NJS_TOKEN_NAME:
+ case NJS_TOKEN_ARGUMENTS:
return njs_generate_name(vm, generator, node);
case NJS_TOKEN_GLOBAL_THIS:
case NJS_TOKEN_CLEAR_TIMEOUT:
return njs_generate_builtin_object(vm, generator, node);
- case NJS_TOKEN_ARGUMENTS:
- return njs_generate_arguments_object(vm, generator, node);
-
case NJS_TOKEN_FUNCTION:
return njs_generate_function_declaration(vm, generator, node);
}
-static nxt_int_t
-njs_generate_arguments_object(njs_vm_t *vm, njs_generator_t *generator,
- njs_parser_node_t *node)
-{
- njs_vmcode_arguments_t *gen;
-
- node->index = njs_generate_object_dest_index(vm, generator, node);
- if (nxt_slow_path(node->index == NJS_INDEX_ERROR)) {
- return NXT_ERROR;
- }
-
- njs_generate_code(generator, njs_vmcode_arguments_t, gen,
- njs_vmcode_arguments, 1, 1);
- gen->retval = node->index;
-
- return NXT_OK;
-}
-
-
static nxt_int_t
njs_generate_variable(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
lambda->closure_size = size;
lambda->nesting = node->scope->nesting;
- lambda->arguments_object = node->scope->arguments_object;
lambda->start = generator.code_start;
lambda->local_size = generator.scope_size;
generator->code_start = p;
generator->code_end = p;
- ret = njs_generate_argument_closures(vm, generator, scope->top);
+ ret = njs_generate_lambda_variables(vm, generator, scope->top);
if (nxt_slow_path(ret != NXT_OK)) {
return NXT_ERROR;
}
static nxt_int_t
-njs_generate_argument_closures(njs_vm_t *vm, njs_generator_t *generator,
+njs_generate_lambda_variables(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
- nxt_uint_t n;
- njs_index_t index;
- njs_variable_t *var;
- njs_vmcode_move_t *move;
- nxt_lvlhsh_each_t lhe;
-
- n = node->scope->argument_closures;
-
- if (n == 0) {
- return NXT_OK;
- }
+ njs_index_t index;
+ njs_variable_t *var;
+ njs_vmcode_move_t *move;
+ nxt_lvlhsh_each_t lhe;
+ njs_vmcode_arguments_t *arguments;
nxt_lvlhsh_each_init(&lhe, &njs_variables_hash_proto);
- do {
+ for ( ;; ) {
var = nxt_lvlhsh_each(&node->scope->variables, &lhe);
+ if (var == NULL) {
+ break;
+ }
+
if (var->argument != 0) {
index = njs_scope_index((var->argument - 1), NJS_SCOPE_ARGUMENTS);
njs_generate_code_move(generator, move, var->index, index);
-
- n--;
}
- } while (n != 0);
+ if (var->arguments_object) {
+ njs_generate_code(generator, njs_vmcode_arguments_t, arguments,
+ njs_vmcode_arguments, 1, 0);
+ arguments->dst = var->index;
+ }
+ }
return NXT_OK;
}
{
njs_ret_t ret;
njs_value_t *ext;
+ njs_variable_t *var;
njs_parser_node_t *node;
njs_parser_scope_t *scope;
break;
- case NJS_TOKEN_ARGUMENTS:
- nxt_thread_log_debug("JS: arguments");
-
- if (parser->scope->type <= NJS_SCOPE_GLOBAL) {
- njs_parser_syntax_error(vm, parser, "\"%V\" object "
- "in global scope", name);
-
- return NULL;
- }
-
- parser->scope->arguments_object = 1;
-
- break;
-
case NJS_TOKEN_OBJECT_CONSTRUCTOR:
node->index = NJS_INDEX_OBJECT;
break;
break;
+ case NJS_TOKEN_ARGUMENTS:
+ nxt_thread_log_debug("JS: arguments");
+
+ if (parser->scope->type <= NJS_SCOPE_GLOBAL) {
+ njs_parser_syntax_error(vm, parser, "\"%V\" object "
+ "in global scope", name);
+
+ return NULL;
+ }
+
+ node->token_line = token_line;
+
+ ret = njs_variable_reference(vm, parser->scope, node, name, hash,
+ NJS_REFERENCE);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NULL;
+ }
+
+ var = njs_variable_add(vm, parser->scope, name, hash, NJS_VARIABLE_VAR);
+ if (nxt_slow_path(var == NULL)) {
+ return NULL;
+ }
+
+ var->arguments_object = 1;
+
+ break;
+
case NJS_TOKEN_NAME:
nxt_thread_log_debug("JS: %V", name);