| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index f32e9177b5a9120905a287fb1fdac1891c3eb7a6..1167f43df519321d34a8a7efad9e085b2af7e548 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -584,7 +584,8 @@ Parser::Parser(Handle<Script> script,
|
| pre_data_(pre_data),
|
| fni_(NULL),
|
| stack_overflow_(false),
|
| - parenthesized_function_(false) {
|
| + parenthesized_function_(false),
|
| + harmony_block_scoping_(false) {
|
| AstNode::ResetIds();
|
| }
|
|
|
| @@ -809,6 +810,9 @@ void Parser::ReportMessageAt(Scanner::Location source_location,
|
| isolate()->Throw(*result, &location);
|
| }
|
|
|
| +void Parser::SetHarmonyBlockScoping(bool block_scoping) {
|
| + harmony_block_scoping_ = block_scoping;
|
| +}
|
|
|
| // Base class containing common code for the different finder classes used by
|
| // the parser.
|
| @@ -1487,6 +1491,8 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) {
|
|
|
|
|
| Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
|
| + if (harmony_block_scoping_) return ParseScopedBlock(labels, ok);
|
| +
|
| // Block ::
|
| // '{' Statement* '}'
|
|
|
| @@ -1510,6 +1516,56 @@ 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());
|
| + 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());
|
| +
|
| + // Create a try-finally statement.
|
| + TryFinallyStatement* try_finally =
|
| + new(zone()) TryFinallyStatement(body, exit);
|
| + try_finally->set_escaping_targets(collector.targets());
|
| + top_scope_ = saved_scope;
|
| +
|
| + // Create a result block.
|
| + Block* result = new(zone()) Block(isolate(), NULL, 1, false);
|
| + result->AddStatement(try_finally);
|
| + return result;
|
| +}
|
| +
|
| +
|
| Block* Parser::ParseVariableStatement(bool* ok) {
|
| // VariableStatement ::
|
| // VariableDeclarations ';'
|
| @@ -5105,6 +5161,8 @@ bool ParserApi::Parse(CompilationInfo* info) {
|
| Handle<Script> script = info->script();
|
| if (info->is_lazy()) {
|
| Parser parser(script, true, NULL, NULL);
|
| + parser.SetHarmonyBlockScoping(!info->is_native() &&
|
| + FLAG_harmony_block_scoping);
|
| result = parser.ParseLazy(info);
|
| } else {
|
| // Whether we allow %identifier(..) syntax.
|
| @@ -5112,6 +5170,8 @@ bool ParserApi::Parse(CompilationInfo* info) {
|
| info->allows_natives_syntax() || FLAG_allow_natives_syntax;
|
| ScriptDataImpl* pre_data = info->pre_parse_data();
|
| Parser parser(script, allow_natives_syntax, info->extension(), pre_data);
|
| + parser.SetHarmonyBlockScoping(!info->is_native() &&
|
| + FLAG_harmony_block_scoping);
|
| if (pre_data != NULL && pre_data->has_error()) {
|
| Scanner::Location loc = pre_data->MessageLocation();
|
| const char* message = pre_data->BuildMessage();
|
| @@ -5130,7 +5190,6 @@ bool ParserApi::Parse(CompilationInfo* info) {
|
| info->StrictMode());
|
| }
|
| }
|
| -
|
| info->SetFunction(result);
|
| return (result != NULL);
|
| }
|
|
|