| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index 87d347d4c56491499b05c55bdf05fac38c3b8435..e379f778fc5c4faa23288fc2e5645f795625158e 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -1133,13 +1133,20 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
|
| scope->set_start_position(shared_info->start_position());
|
| FormalParameterErrorLocations error_locs;
|
| bool has_rest = false;
|
| + bool has_initializers = false;
|
| + ZoneList<Expression*>* initializers =
|
| + new (zone()) ZoneList<Expression*>(0, zone());
|
| if (Check(Token::LPAREN)) {
|
| // '(' StrictFormalParameters ')'
|
| - ParseFormalParameterList(scope, &error_locs, &has_rest, &ok);
|
| + Scope* parameter_scope = NewScope(scope, PARAMETER_SCOPE);
|
| + ParseFormalParameterList(scope, parameter_scope, &error_locs,
|
| + initializers, &has_initializers,
|
| + &has_rest, &ok);
|
| if (ok) ok = Check(Token::RPAREN);
|
| } else {
|
| // BindingIdentifier
|
| - ParseFormalParameter(scope, &error_locs, has_rest, &ok);
|
| + ParseFormalParameter(scope, nullptr, &error_locs,
|
| + nullptr, nullptr, has_rest, &ok);
|
| }
|
|
|
| if (ok) {
|
| @@ -3896,6 +3903,62 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
|
| }
|
|
|
|
|
| +ZoneList<Statement*>* Parser::DesugarInitializeParameters(
|
| + bool has_initializers, ZoneList<Expression*>* initializers) {
|
| + ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(0, zone());
|
| + if (has_initializers) {
|
| + for (int i = 0; i < initializers->length(); ++i) {
|
| + Expression* initializer = initializers->at(i);
|
| + // TODO(caitp): ensure proper TDZ behaviour --- need hole-check for
|
| + // all parameter bindings, including ones without initializers
|
| + if (initializer) {
|
| + // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i);
|
| + const AstRawString* fn_name = ast_value_factory()->empty_string();
|
| + const Runtime::Function* arguments =
|
| + Runtime::FunctionForId(Runtime::kInlineArguments);
|
| + ZoneList<Expression*>* arguments_i0 =
|
| + new (zone()) ZoneList<Expression*>(0, zone());
|
| + arguments_i0->Add(
|
| + factory()->NewSmiLiteral(i, RelocInfo::kNoPosition), zone());
|
| +
|
| + ZoneList<Expression*>* arguments_i1 =
|
| + new (zone()) ZoneList<Expression*>(0, zone());
|
| + arguments_i1->Add(
|
| + factory()->NewSmiLiteral(i, RelocInfo::kNoPosition), zone());
|
| +
|
| + Expression* arg_or_default = factory()->NewConditional(
|
| + // condition:
|
| + factory()->NewCompareOperation(
|
| + Token::EQ_STRICT,
|
| + factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
|
| + RelocInfo::kNoPosition),
|
| + factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition),
|
| + // if true:
|
| + initializer,
|
| + // if false:
|
| + factory()->NewCallRuntime(fn_name, arguments, arguments_i1,
|
| + RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition);
|
| +
|
| + Expression* assign = factory()->NewAssignment(
|
| + Token::ASSIGN,
|
| + factory()->NewVariableProxy(
|
| + scope_->parameter(i), RelocInfo::kNoPosition),
|
| + arg_or_default,
|
| + RelocInfo::kNoPosition);
|
| +
|
| + body->Add(
|
| + factory()->NewExpressionStatement(
|
| + assign, RelocInfo::kNoPosition),
|
| + zone());
|
| + }
|
| + }
|
| + }
|
| + return body;
|
| +}
|
| +
|
| +
|
| FunctionLiteral* Parser::ParseFunctionLiteral(
|
| const AstRawString* function_name, Scanner::Location function_name_location,
|
| bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
|
| @@ -3961,6 +4024,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| declaration_scope != original_declaration_scope)
|
| ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
|
| : NewScope(scope_, FUNCTION_SCOPE, kind);
|
| + Scope* parameter_scope = NewScope(scope, PARAMETER_SCOPE);
|
| ZoneList<Statement*>* body = NULL;
|
| int materialized_literal_count = -1;
|
| int expected_property_count = -1;
|
| @@ -3994,8 +4058,13 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| Expect(Token::LPAREN, CHECK_OK);
|
| int start_position = scanner()->location().beg_pos;
|
| scope_->set_start_position(start_position);
|
| - num_parameters =
|
| - ParseFormalParameterList(scope, &error_locs, &has_rest, CHECK_OK);
|
| + ZoneList<Expression*>* initializers =
|
| + new (zone()) ZoneList<Expression*>(0, zone());
|
| + bool has_initializers = false;
|
| + num_parameters = ParseFormalParameterList(scope, parameter_scope,
|
| + &error_locs, initializers,
|
| + &has_initializers, &has_rest,
|
| + CHECK_OK);
|
| Expect(Token::RPAREN, CHECK_OK);
|
| int formals_end_position = scanner()->location().end_pos;
|
|
|
| @@ -4074,8 +4143,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| SkipLazyFunctionBody(&materialized_literal_count,
|
| &expected_property_count, CHECK_OK);
|
| } else {
|
| - body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
|
| - kind, CHECK_OK);
|
| + body = DesugarInitializeParameters(has_initializers, initializers);
|
| + ZoneList<Statement*>* inner_body =
|
| + ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
|
| + kind, CHECK_OK);
|
| + body->AddAll(*inner_body, zone());
|
| materialized_literal_count = function_state.materialized_literal_count();
|
| expected_property_count = function_state.expected_property_count();
|
| handler_count = function_state.handler_count();
|
|
|