| 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();
|
| }
|
|
|