Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index 2b3f482a265c17e99d4202fa2bb798cc4972a0bd..9bac6db5b4cf4a15d8fe555771b855d71fcb7d4c 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -4307,16 +4307,23 @@ Statement* Parser::BuildAssertIsCoercible(Variable* var) { |
| } |
| +bool Parser::NeedsParameterInitializationBlock( |
|
rossberg
2015/07/16 12:53:47
Make this into IsSimpleParameterList, to match wha
caitp (gmail)
2015/07/16 13:03:57
Acknowledged.
|
| + const ParserFormalParameterParsingState& formal_parameters) { |
| + for (auto parameter : formal_parameters.params) { |
| + if (parameter.pattern != nullptr) return true; |
| + } |
| + return false; |
| +} |
| + |
| + |
| Block* Parser::BuildParameterInitializationBlock( |
| const ParserFormalParameterParsingState& formal_parameters, bool* ok) { |
| + DCHECK(NeedsParameterInitializationBlock(formal_parameters)); |
| DCHECK(scope_->is_function_scope()); |
| - Block* init_block = nullptr; |
| + Block* init_block = |
| + factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
| for (auto parameter : formal_parameters.params) { |
| if (parameter.pattern == nullptr) continue; |
| - if (init_block == nullptr) { |
| - init_block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
| - } |
| - |
| DeclarationDescriptor descriptor; |
| descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; |
| descriptor.parser = this; |
| @@ -4346,35 +4353,24 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| // (see comment above). |
| ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); |
| + Statement* init_fvar = nullptr; |
| + |
| if (fvar != NULL) { |
| VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name); |
| fproxy->BindTo(fvar); |
| - result->Add(factory()->NewExpressionStatement( |
| - factory()->NewAssignment(fvar_init_op, |
| - fproxy, |
| + init_fvar = factory()->NewExpressionStatement( |
| + factory()->NewAssignment(fvar_init_op, fproxy, |
| factory()->NewThisFunction(pos), |
| RelocInfo::kNoPosition), |
| - RelocInfo::kNoPosition), zone()); |
| - } |
| - |
| - |
| - // For concise constructors, check that they are constructed, |
| - // not called. |
| - if (i::IsConstructor(kind)) { |
| - AddAssertIsConstruct(result, pos); |
| + RelocInfo::kNoPosition); |
| } |
| ZoneList<Statement*>* body = result; |
| Scope* inner_scope = nullptr; |
| Block* inner_block = nullptr; |
| - Block* init_block = |
| - BuildParameterInitializationBlock(formal_parameters, CHECK_OK); |
| - if (init_block != nullptr) { |
| - body->Add(init_block, zone()); |
| - // Wrap the actual function body into an inner scope. |
| - inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition); |
| - body->Add(inner_block, zone()); |
| - body = inner_block->statements(); |
| + |
| + bool needs_inner_block = NeedsParameterInitializationBlock(formal_parameters); |
| + if (needs_inner_block) { |
| inner_scope = NewScope(scope_, BLOCK_SCOPE); |
| inner_scope->set_is_declaration_scope(); |
| inner_scope->set_start_position(scanner()->location().beg_pos); |
| @@ -4383,6 +4379,17 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| { |
| BlockState block_state(&scope_, inner_scope ? inner_scope : scope_); |
| + if (!needs_inner_block) { |
| + if (fvar != nullptr) { |
|
rossberg
2015/07/16 12:53:47
Hm, why do you need to move (and duplicate) fvar i
caitp (gmail)
2015/07/16 13:03:57
it seems that these need to happen before the init
rossberg
2015/07/16 13:21:05
Not sure I understand. They were happening before
caitp (gmail)
2015/07/16 14:44:31
I've refactored this, it's much cleaner now
|
| + body->Add(init_fvar, zone()); |
| + } |
| + // For concise constructors, check that they are constructed, |
| + // not called. |
| + if (i::IsConstructor(kind)) { |
| + AddAssertIsConstruct(body, pos); |
| + } |
| + } |
| + |
| // For generators, allocate and yield an iterator on function entry. |
| if (IsGeneratorFunction(kind)) { |
| ZoneList<Expression*>* arguments = |
| @@ -4427,11 +4434,32 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| Expect(Token::RBRACE, CHECK_OK); |
| scope_->set_end_position(scanner()->location().end_pos); |
| - if (inner_scope != nullptr) { |
| - DCHECK(inner_block != nullptr); |
| + |
| + if (needs_inner_block) { |
| + DCHECK_NOT_NULL(inner_scope); |
| + scope_->SetLanguageMode(inner_scope->language_mode()); |
| + Block* init_block = |
| + BuildParameterInitializationBlock(formal_parameters, CHECK_OK); |
| + DCHECK_NOT_NULL(init_block); |
| + inner_block = |
| + factory()->NewBlock(NULL, body->length(), true, RelocInfo::kNoPosition); |
| + inner_block->statements()->AddAll(*body, zone()); |
| inner_scope->set_end_position(scanner()->location().end_pos); |
| inner_scope = inner_scope->FinalizeBlockScope(); |
| inner_block->set_scope(inner_scope); |
| + |
| + result = new (zone()) ZoneList<Statement*>(8, zone()); |
| + if (fvar != nullptr) { |
| + result->Add(init_fvar, zone()); |
| + } |
| + // For concise constructors, check that they are constructed, |
| + // not called. |
| + if (i::IsConstructor(kind)) { |
| + AddAssertIsConstruct(result, pos); |
| + } |
| + result->Add(init_block, zone()); |
| + // Wrap the actual function body into an inner scope. |
| + result->Add(inner_block, zone()); |
| } |
| return result; |