Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index f0556cb35531f2e3feea74bf7a708356ccea6d73..1bab4a61797acd54807a10cd7baa9d15c4783e18 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -1221,13 +1221,14 @@ Block* Parser::ParseModuleDeclaration(bool* ok) { |
// Create new block with one expected declaration. |
Block* block = factory()->NewBlock(NULL, 1, true); |
Handle<String> name = ParseIdentifier(CHECK_OK); |
- // top_scope_->AddDeclaration( |
- // factory()->NewModuleDeclaration(proxy, module, top_scope_)); |
- VariableProxy* proxy = Declare(name, LET, NULL, true, CHECK_OK); |
- Module* module = ParseModule(ok); |
+ Module* module = ParseModule(CHECK_OK); |
+ VariableProxy* proxy = NewUnresolved(name, LET); |
+ Declaration* declaration = |
+ factory()->NewModuleDeclaration(proxy, module, top_scope_); |
+ Declare(declaration, true, CHECK_OK); |
+ |
// TODO(rossberg): Add initialization statement to block. |
- USE(proxy); |
- USE(module); |
+ |
return block; |
} |
@@ -1497,21 +1498,22 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
} |
-VariableProxy* Parser::Declare(Handle<String> name, |
- VariableMode mode, |
- FunctionLiteral* fun, |
- bool resolve, |
- bool* ok) { |
- Variable* var = NULL; |
+VariableProxy* Parser::NewUnresolved(Handle<String> name, VariableMode mode) { |
// If we are inside a function, a declaration of a var/const variable is a |
// truly local variable, and the scope of the variable is always the function |
// scope. |
// Let/const variables in harmony mode are always added to the immediately |
// enclosing scope. |
- Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY) |
- ? top_scope_ : top_scope_->DeclarationScope(); |
- InitializationFlag init_flag = (fun != NULL || mode == VAR) |
- ? kCreatedInitialized : kNeedsInitialization; |
+ return DeclarationScope(mode)->NewUnresolved( |
+ factory(), name, scanner().location().beg_pos); |
+} |
+ |
+ |
+void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
+ Handle<String> name = declaration->proxy()->name(); |
+ VariableMode mode = declaration->mode(); |
+ Scope* declaration_scope = DeclarationScope(mode); |
+ Variable* var = NULL; |
// If a function scope exists, then we can statically declare this |
// variable and also set its mode. In any case, a Declaration node |
@@ -1531,7 +1533,8 @@ VariableProxy* Parser::Declare(Handle<String> name, |
var = declaration_scope->LocalLookup(name); |
if (var == NULL) { |
// Declare the name. |
- var = declaration_scope->DeclareLocal(name, mode, init_flag); |
+ var = declaration_scope->DeclareLocal( |
+ name, mode, declaration->initialization()); |
} else { |
// The name was declared in this scope before; check for conflicting |
// re-declarations. We have a conflict if either of the declarations is |
@@ -1558,7 +1561,7 @@ VariableProxy* Parser::Declare(Handle<String> name, |
Vector<const char*> args(elms, 2); |
ReportMessage("redeclaration", args); |
*ok = false; |
- return NULL; |
+ return; |
} |
const char* type = (var->mode() == VAR) |
? "var" : var->is_const_mode() ? "const" : "let"; |
@@ -1588,10 +1591,7 @@ VariableProxy* Parser::Declare(Handle<String> name, |
// semantic issue as long as we keep the source order, but it may be |
// a performance issue since it may lead to repeated |
// Runtime::DeclareContextSlot() calls. |
- VariableProxy* proxy = declaration_scope->NewUnresolved( |
- factory(), name, scanner().location().beg_pos); |
- declaration_scope->AddDeclaration( |
- factory()->NewVariableDeclaration(proxy, mode, fun, top_scope_)); |
+ declaration_scope->AddDeclaration(declaration); |
if ((mode == CONST || mode == CONST_HARMONY) && |
declaration_scope->is_global_scope()) { |
@@ -1615,7 +1615,7 @@ VariableProxy* Parser::Declare(Handle<String> name, |
mode, |
true, |
kind, |
- init_flag); |
+ declaration->initialization()); |
var->AllocateTo(Variable::LOOKUP, -1); |
resolve = true; |
} |
@@ -1644,9 +1644,7 @@ VariableProxy* Parser::Declare(Handle<String> name, |
// initialization code. Thus, inside the 'with' statement, we need |
// both access to the static and the dynamic context chain; the |
// runtime needs to provide both. |
- if (resolve && var != NULL) proxy->BindTo(var); |
- |
- return proxy; |
+ if (resolve && var != NULL) declaration->proxy()->BindTo(var); |
} |
@@ -1673,7 +1671,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { |
// isn't lazily compiled. The extension structures are only |
// accessible while parsing the first time not when reparsing |
// because of lazy compilation. |
- top_scope_->DeclarationScope()->ForceEagerCompilation(); |
+ DeclarationScope(VAR)->ForceEagerCompilation(); |
// Compute the function template for the native function. |
v8::Handle<v8::FunctionTemplate> fun_template = |
@@ -1698,12 +1696,15 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { |
// TODO(1240846): It's weird that native function declarations are |
// introduced dynamically when we meet their declarations, whereas |
// other functions are set up when entering the surrounding scope. |
+ VariableProxy* proxy = NewUnresolved(name, VAR); |
+ Declaration* declaration = |
+ factory()->NewVariableDeclaration(proxy, VAR, top_scope_); |
+ Declare(declaration, true, CHECK_OK); |
SharedFunctionInfoLiteral* lit = |
factory()->NewSharedFunctionInfoLiteral(shared); |
- VariableProxy* var = Declare(name, VAR, NULL, true, CHECK_OK); |
return factory()->NewExpressionStatement( |
factory()->NewAssignment( |
- Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); |
+ Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); |
} |
@@ -1724,7 +1725,10 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) { |
// scope, we treat is as such and introduce the function with it's |
// initial value upon entering the corresponding scope. |
VariableMode mode = is_extended_mode() ? LET : VAR; |
- Declare(name, mode, fun, true, CHECK_OK); |
+ VariableProxy* proxy = NewUnresolved(name, mode); |
+ Declaration* declaration = |
+ factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); |
+ Declare(declaration, true, CHECK_OK); |
return factory()->NewEmptyStatement(); |
} |
@@ -1902,8 +1906,8 @@ Block* Parser::ParseVariableDeclarations( |
UNREACHABLE(); // by current callers |
} |
- Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY) |
- ? top_scope_ : top_scope_->DeclarationScope(); |
+ Scope* declaration_scope = DeclarationScope(mode); |
+ |
// The scope of a var/const declared variable anywhere inside a function |
// is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can |
// transform a source-level var/const declaration into a (Function) |
@@ -1950,7 +1954,10 @@ Block* Parser::ParseVariableDeclarations( |
// For let/const declarations in harmony mode, we can also immediately |
// pre-resolve the proxy because it resides in the same scope as the |
// declaration. |
- VariableProxy* proxy = Declare(name, mode, NULL, mode != VAR, CHECK_OK); |
+ VariableProxy* proxy = NewUnresolved(name, mode); |
+ Declaration* declaration = |
+ factory()->NewVariableDeclaration(proxy, mode, top_scope_); |
+ Declare(declaration, mode != VAR, CHECK_OK); |
nvars++; |
if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
ReportMessageAt(scanner().location(), "too_many_variables", |