Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 45202cb3a82b922c7d487061cfff03578cc3a3c9..4b71f8ce03664ac02817b62a67f43612aaad0695 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -1323,6 +1323,21 @@ void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, |
token_loc.end_pos - token_loc.beg_pos == |
ast_value_factory()->use_strong_string()->length() + 2; |
if (use_strict_found || use_strong_found) { |
+ if (!scope_->HasSimpleParameters()) { |
+ // A block declaration scope as a child scope of a function scope |
+ // indicates that a function has a non-simple parameter list. |
+ // TC39 deemed "use strict" directives to be an error in this case, |
+ // on 29/7/2015. https://goo.gl/ueA7Ln |
+ // |
+ // In V8, this also applies to "use strong " directives. |
+ const AstRawString* string = literal->raw_value()->AsString(); |
+ ParserTraits::ReportMessageAt( |
+ token_loc, MessageTemplate::kIllegalLanguageModeDirective, |
+ string); |
+ *ok = false; |
+ return nullptr; |
+ } |
+ |
// Strong mode implies strict mode. If there are several "use strict" |
// / "use strong" directives, do the strict mode changes only once. |
if (is_sloppy(scope_->language_mode())) { |
@@ -4254,7 +4269,8 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count, |
int body_end = scanner()->location().end_pos; |
log_->LogFunction(function_block_pos, body_end, *materialized_literal_count, |
*expected_property_count, scope_->language_mode(), |
- scope_->uses_super_property(), scope_->calls_eval()); |
+ scope_->uses_super_property(), scope_->calls_eval(), |
+ scope_->has_simple_parameters()); |
} |
} |
@@ -4305,7 +4321,7 @@ Statement* Parser::BuildAssertIsCoercible(Variable* var) { |
Block* Parser::BuildParameterInitializationBlock( |
const ParserFormalParameters& parameters, bool* ok) { |
- DCHECK(!parameters.is_simple); |
+ if (parameters.is_simple) return nullptr; |
DCHECK(scope_->is_function_scope()); |
Block* init_block = |
factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
@@ -4364,13 +4380,17 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
ZoneList<Statement*>* body = result; |
Scope* inner_scope = nullptr; |
Block* inner_block = nullptr; |
- if (!parameters.is_simple) { |
+ Block* init_block = BuildParameterInitializationBlock(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(); |
inner_scope = NewScope(scope_, BLOCK_SCOPE); |
inner_scope->set_is_declaration_scope(); |
inner_scope->set_start_position(scanner()->location().beg_pos); |
- inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition); |
inner_block->set_scope(inner_scope); |
- body = inner_block->statements(); |
} |
{ |
@@ -4422,20 +4442,12 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
scope_->set_end_position(scanner()->location().end_pos); |
if (!parameters.is_simple) { |
- DCHECK_NOT_NULL(inner_scope); |
- DCHECK_EQ(body, inner_block->statements()); |
- scope_->SetLanguageMode(inner_scope->language_mode()); |
- Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); |
- DCHECK_NOT_NULL(init_block); |
- |
+ DCHECK_NOT_NULL(inner_block); |
inner_scope->set_end_position(scanner()->location().end_pos); |
inner_scope = inner_scope->FinalizeBlockScope(); |
if (inner_scope != nullptr) { |
CheckConflictingVarDeclarations(inner_scope, CHECK_OK); |
} |
- |
- result->Add(init_block, zone()); |
- result->Add(inner_block, zone()); |
} |
if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
@@ -4500,7 +4512,8 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
#undef SET_ALLOW |
} |
PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
- language_mode(), function_state_->kind(), logger, bookmark); |
+ language_mode(), function_state_->kind(), scope_->has_simple_parameters(), |
+ logger, bookmark); |
if (pre_parse_timer_ != NULL) { |
pre_parse_timer_->Stop(); |
} |