Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index e8d18106165515f7e43e58ba700d5fcf5d63a4cd..69453307249544295c0c7d66dd9fd3d7446b7bee 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -407,9 +407,9 @@ unsigned* ScriptDataImpl::ReadAddress(int position) { |
} |
-Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) { |
+Scope* Parser::NewScope(Scope* parent, Scope::Type type) { |
Scope* result = new(zone()) Scope(parent, type); |
- result->Initialize(inside_with); |
+ result->Initialize(); |
return result; |
} |
@@ -459,13 +459,31 @@ class TargetScope BASE_EMBEDDED { |
// ---------------------------------------------------------------------------- |
-// LexicalScope is a support class to facilitate manipulation of the |
-// Parser's scope stack. The constructor sets the parser's top scope |
-// to the incoming scope, and the destructor resets it. |
-// |
-// Additionally, it stores transient information used during parsing. |
-// These scopes are not kept around after parsing or referenced by syntax |
-// trees so they can be stack-allocated and hence used by the pre-parser. |
+// LexicalScope and SaveScope are stack allocated support classes to facilitate |
+// anipulation of the Parser's scope stack. The constructor sets the parser's |
+// top scope to the incoming scope, and the destructor resets it. Additionally, |
+// LexicalScope stores transient information used during parsing. |
+ |
+ |
+class SaveScope BASE_EMBEDDED { |
+ public: |
+ SaveScope(Parser* parser, Scope* scope) |
+ : parser_(parser), |
+ previous_top_scope_(parser->top_scope_) { |
+ parser->top_scope_ = scope; |
+ } |
+ |
+ ~SaveScope() { |
+ parser_->top_scope_ = previous_top_scope_; |
+ } |
+ |
+ private: |
+ // Bookkeeping |
+ Parser* parser_; |
+ // Previous values |
+ Scope* previous_top_scope_; |
+}; |
+ |
class LexicalScope BASE_EMBEDDED { |
public: |
@@ -516,7 +534,6 @@ class LexicalScope BASE_EMBEDDED { |
// Previous values |
LexicalScope* lexical_scope_parent_; |
Scope* previous_scope_; |
- int previous_with_nesting_level_; |
unsigned previous_ast_node_id_; |
}; |
@@ -529,11 +546,9 @@ LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate) |
parser_(parser), |
lexical_scope_parent_(parser->lexical_scope_), |
previous_scope_(parser->top_scope_), |
- previous_with_nesting_level_(parser->with_nesting_level_), |
previous_ast_node_id_(isolate->ast_node_id()) { |
parser->top_scope_ = scope; |
parser->lexical_scope_ = this; |
- parser->with_nesting_level_ = 0; |
isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); |
} |
@@ -541,7 +556,6 @@ LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate) |
LexicalScope::~LexicalScope() { |
parser_->top_scope_ = previous_scope_; |
parser_->lexical_scope_ = lexical_scope_parent_; |
- parser_->with_nesting_level_ = previous_with_nesting_level_; |
parser_->isolate()->set_ast_node_id(previous_ast_node_id_); |
} |
@@ -578,7 +592,6 @@ Parser::Parser(Handle<Script> script, |
script_(script), |
scanner_(isolate_->unicode_cache()), |
top_scope_(NULL), |
- with_nesting_level_(0), |
lexical_scope_(NULL), |
target_stack_(NULL), |
allow_natives_syntax_(allow_natives_syntax), |
@@ -637,7 +650,7 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source, |
Handle<String> no_name = isolate()->factory()->empty_symbol(); |
FunctionLiteral* result = NULL; |
- { Scope* scope = NewScope(top_scope_, type, inside_with()); |
+ { Scope* scope = NewScope(top_scope_, type); |
LexicalScope lexical_scope(this, scope, isolate()); |
if (strict_mode == kStrictMode) { |
top_scope_->EnableStrictMode(); |
@@ -727,7 +740,7 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, |
{ |
// Parse the function literal. |
- Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
+ Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE); |
if (!info->closure().is_null()) { |
scope = Scope::DeserializeScopeChain(info, scope); |
} |
@@ -1405,7 +1418,7 @@ VariableProxy* Parser::Declare(Handle<String> name, |
// a performance issue since it may lead to repeated |
// Runtime::DeclareContextSlot() calls. |
VariableProxy* proxy = declaration_scope->NewUnresolved( |
- name, false, scanner().location().beg_pos); |
+ name, scanner().location().beg_pos); |
declaration_scope->AddDeclaration( |
new(zone()) Declaration(proxy, mode, fun, top_scope_)); |
@@ -1557,20 +1570,16 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
// Construct block expecting 16 statements. |
Block* body = new(zone()) Block(isolate(), labels, 16, false); |
- Scope* saved_scope = top_scope_; |
- Scope* block_scope = NewScope(top_scope_, |
- Scope::BLOCK_SCOPE, |
- inside_with()); |
+ Scope* block_scope = NewScope(top_scope_, Scope::BLOCK_SCOPE); |
if (top_scope_->is_strict_mode()) { |
block_scope->EnableStrictMode(); |
} |
- top_scope_ = block_scope; |
// Parse the statements and collect escaping labels. |
- TargetCollector collector; |
- Target target(&this->target_stack_, &collector); |
Expect(Token::LBRACE, CHECK_OK); |
- { |
+ { SaveScope save_scope(this, block_scope); |
+ TargetCollector collector; |
+ Target target(&this->target_stack_, &collector); |
Target target_body(&this->target_stack_, body); |
InitializationBlockFinder block_finder(top_scope_, target_stack_); |
@@ -1583,7 +1592,6 @@ Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
} |
} |
Expect(Token::RBRACE, CHECK_OK); |
- top_scope_ = saved_scope; |
block_scope = block_scope->FinalizeBlockScope(); |
body->set_block_scope(block_scope); |
@@ -2078,10 +2086,12 @@ Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
Expression* expr = ParseExpression(true, CHECK_OK); |
Expect(Token::RPAREN, CHECK_OK); |
- ++with_nesting_level_; |
top_scope_->DeclarationScope()->RecordWithStatement(); |
- Statement* stmt = ParseStatement(labels, CHECK_OK); |
- --with_nesting_level_; |
+ Scope* with_scope = NewScope(top_scope_, Scope::WITH_SCOPE); |
+ Statement* stmt; |
+ { SaveScope save_scope(this, with_scope); |
+ stmt = ParseStatement(labels, CHECK_OK); |
+ } |
return new(zone()) WithStatement(expr, stmt); |
} |
@@ -2218,7 +2228,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
if (peek() == Token::LBRACE) { |
Target target(&this->target_stack_, &catch_collector); |
- catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); |
+ catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE); |
if (top_scope_->is_strict_mode()) { |
catch_scope->EnableStrictMode(); |
} |
@@ -2226,10 +2236,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
? Variable::LET : Variable::VAR; |
catch_variable = catch_scope->DeclareLocal(name, mode); |
- Scope* saved_scope = top_scope_; |
- top_scope_ = catch_scope; |
+ SaveScope save_scope(this, catch_scope); |
catch_block = ParseBlock(NULL, CHECK_OK); |
- top_scope_ = saved_scope; |
} else { |
Expect(Token::LBRACE, CHECK_OK); |
} |
@@ -2348,7 +2356,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
ParseVariableDeclarations(kForStatement, &name, CHECK_OK); |
if (peek() == Token::IN && !name.is_null()) { |
- VariableProxy* each = top_scope_->NewUnresolved(name, inside_with()); |
+ VariableProxy* each = top_scope_->NewUnresolved(name); |
ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); |
Target target(&this->target_stack_, loop); |
@@ -3058,9 +3066,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) { |
case Token::FUTURE_STRICT_RESERVED_WORD: { |
Handle<String> name = ParseIdentifier(CHECK_OK); |
if (fni_ != NULL) fni_->PushVariableName(name); |
- result = top_scope_->NewUnresolved(name, |
- inside_with(), |
- scanner().location().beg_pos); |
+ result = top_scope_->NewUnresolved(name, scanner().location().beg_pos); |
break; |
} |
@@ -3709,8 +3715,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
// are not hoisted. |
Scope* scope = (type == FunctionLiteral::DECLARATION && |
!harmony_block_scoping_) |
- ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) |
- : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
+ ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE) |
+ : NewScope(top_scope_, Scope::FUNCTION_SCOPE); |
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); |
int materialized_literal_count; |
int expected_property_count; |
@@ -3776,8 +3782,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
// instead of Variables and Proxis as is the case now. |
if (type == FunctionLiteral::NAMED_EXPRESSION) { |
Variable* fvar = top_scope_->DeclareFunctionVar(function_name); |
- VariableProxy* fproxy = |
- top_scope_->NewUnresolved(function_name, inside_with()); |
+ VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); |
fproxy->BindTo(fvar); |
body->Add(new(zone()) ExpressionStatement( |
new(zone()) Assignment(isolate(), |