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; |