Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(748)

Unified Diff: src/parser.cc

Issue 1234213004: [parser] use-strict directives in function body affect init block (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698