Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index f32e9177b5a9120905a287fb1fdac1891c3eb7a6..948c21acc84cef9f04a1c9ef828159de6afa27a5 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -1210,7 +1210,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
Statement* stmt = NULL; |
switch (peek()) { |
case Token::LBRACE: |
- return ParseBlock(labels, ok); |
+ return ParseScopedBlock(labels, ok); |
case Token::CONST: // fall through |
case Token::VAR: |
@@ -1510,6 +1510,53 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
} |
+Statement* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
+ if (!FLAG_harmony_block_scoping) return ParseBlock(labels, ok); |
Kevin Millikin (Chromium)
2011/08/10 11:19:27
This is OK for now, but you should try to think of
Steven
2011/08/10 12:21:00
Yes sure. But indeed I think this should be done w
|
+ |
+ // 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()); |
+ body->set_block_scope(block_scope); |
+ block_scope->DeclareLocal(isolate()->factory()->block_scope_symbol(), |
+ Variable::VAR); |
+ 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); |
+ { |
+ Target target_body(&this->target_stack_, body); |
+ InitializationBlockFinder block_finder(top_scope_, target_stack_); |
+ |
+ while (peek() != Token::RBRACE) { |
+ Statement* stat = ParseStatement(NULL, CHECK_OK); |
+ if (stat && !stat->IsEmpty()) { |
+ body->AddStatement(stat); |
+ block_finder.Update(stat); |
+ } |
+ } |
+ } |
+ Expect(Token::RBRACE, CHECK_OK); |
+ |
+ // Create exit block. |
+ Block* exit = new(zone()) Block(isolate(), NULL, 1, false); |
+ exit->AddStatement(new(zone()) ExitContextStatement()); |
+ |
+ // Return a try-finally statement. |
+ TryFinallyStatement* result = new(zone()) TryFinallyStatement(body, exit); |
+ result->set_escaping_targets(collector.targets()); |
+ top_scope_ = saved_scope; |
+ return result; |
+} |
+ |
+ |
Block* Parser::ParseVariableStatement(bool* ok) { |
// VariableStatement :: |
// VariableDeclarations ';' |
@@ -5103,6 +5150,8 @@ bool ParserApi::Parse(CompilationInfo* info) { |
ASSERT(info->function() == NULL); |
FunctionLiteral* result = NULL; |
Handle<Script> script = info->script(); |
+ bool save_block_scoping = FLAG_harmony_block_scoping; |
+ FLAG_harmony_block_scoping = !info->is_native() && FLAG_harmony_block_scoping; |
Kevin Millikin (Chromium)
2011/08/10 11:19:27
I'm always nervous about assigning to the flags.
Steven
2011/08/10 12:21:00
Done.
|
if (info->is_lazy()) { |
Parser parser(script, true, NULL, NULL); |
result = parser.ParseLazy(info); |
@@ -5130,7 +5179,7 @@ bool ParserApi::Parse(CompilationInfo* info) { |
info->StrictMode()); |
} |
} |
- |
+ FLAG_harmony_block_scoping = save_block_scoping; |
info->SetFunction(result); |
return (result != NULL); |
} |