frame->return_address = vm->current + advance;
lambda = function->u.lambda;
- vm->current = lambda->u.start;
+ vm->current = lambda->start;
#if (NXT_DEBUG)
vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = NULL;
njs_value_t *local_scope;
njs_value_t *closure_scope;
- union {
- u_char *start;
- njs_parser_t *parser;
- } u;
+ u_char *start;
+ njs_parser_t *parser;
};
return NXT_ERROR;
}
+ if (!njs_is_function(&var->value)) {
+ /* A variable was declared with the same name. */
+ return NXT_OK;
+ }
+
lambda = var->value.data.u.function->u.lambda;
ret = njs_generate_function_scope(vm, lambda, node);
nxt_array_t *closure;
njs_parser_t *parser;
- parser = lambda->u.parser;
+ parser = lambda->parser;
node = node->right;
parser->code_size += node->scope->argument_closures
lambda->local_size = parser->scope_size;
lambda->local_scope = parser->local_scope;
- lambda->u.start = parser->code_start;
+ lambda->start = parser->code_start;
}
return ret;
return NJS_TOKEN_ERROR;
}
- function->u.lambda->u.parser = parser;
+ function->u.lambda->parser = parser;
token = njs_parser_function_lambda(vm, function->u.lambda, token);
}
node->u.value.data.u.lambda = lambda;
- lambda->u.parser = parser;
+ lambda->parser = parser;
token = njs_parser_function_lambda(vm, lambda, token);
njs_variable_t *arg;
njs_parser_node_t *node, *body, *last;
- parser = lambda->u.parser;
+ parser = lambda->parser;
ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION);
if (nxt_slow_path(ret != NXT_OK)) {
}
}
+ if (nxt_lvlhsh_find(&scope->variables, &lhq) == NXT_OK) {
+ var = lhq.value;
+ return var;
+ }
+
var = njs_variable_alloc(vm, &lhq.key, type);
if (nxt_slow_path(var == NULL)) {
return var;
}
- lhq.replace = vm->options.accumulative;
+ lhq.replace = 0;
lhq.value = var;
lhq.pool = vm->mem_cache_pool;
nxt_mem_cache_free(vm->mem_cache_pool, var->name.start);
nxt_mem_cache_free(vm->mem_cache_pool, var);
- if (ret == NXT_ERROR) {
- return NULL;
- }
-
- /* ret == NXT_DECLINED. */
-
- njs_parser_syntax_error(vm, parser, "Identifier \"%.*s\" "
- "has already been declared",
- (int) lhq.key.length, lhq.key.start);
+ njs_type_error(vm, "lvlhsh insert failed");
return NULL;
}
{ nxt_string("if(1)if(0){0?0:0}else\nvar a\nelse\nvar b"),
nxt_string("undefined") },
- { nxt_string("function f(){} function f(){}"),
- nxt_string("SyntaxError: Identifier \"f\" has already been declared in 1") },
+ { nxt_string("var a = 1; var a; a"),
+ nxt_string("1") },
+
+ { nxt_string("(function (x) {if (x) { var a = 3; return a} else { var a = 4; return a}})(1)"),
+ nxt_string("3") },
+
+ { nxt_string("(function (x) {if (x) { var a = 3; return a} else { var a = 4; return a}})(0)"),
+ nxt_string("4") },
+
+ { nxt_string("function f(){return 2}; var f; f()"),
+ nxt_string("2") },
+
+ { nxt_string("function f(){return 2}; var f = 1; f()"),
+ nxt_string("TypeError: number is not a function") },
- { nxt_string("var f = 1; function f() {}"),
- nxt_string("SyntaxError: Identifier \"f\" has already been declared in 1") },
+ { nxt_string("function f(){return 1}; function f(){return 2}; f()"),
+ nxt_string("2") },
+
+ { nxt_string("var f = 1; function f() {}; f"),
+ nxt_string("1") },
+
+#if 0 /* TODO */
+ { nxt_string("var a; Object.getOwnPropertyDescriptor(this, 'a').value"),
+ nxt_string("undefined") },
+
+ { nxt_string("this.a = 1; a"),
+ nxt_string("1") },
+#endif
{ nxt_string("f() = 1"),
nxt_string("ReferenceError: Invalid left-hand side in assignment in 1") },