| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index d4607d1007ad845d15815f68b3ce5646b7a849d9..758dd98963e2c61569883c9b7e796db04cae01d4 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -878,6 +878,7 @@ Parser::Parser(ParseInfo* info)
|
| set_allow_harmony_rest_params(FLAG_harmony_rest_parameters);
|
| set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
|
| set_allow_harmony_destructuring(FLAG_harmony_destructuring);
|
| + set_allow_harmony_default_parameters(FLAG_harmony_default_parameters);
|
| set_allow_strong_mode(FLAG_strong_mode);
|
| for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
|
| ++feature) {
|
| @@ -1141,9 +1142,13 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
|
| scope->set_start_position(shared_info->start_position());
|
| ExpressionClassifier formals_classifier;
|
| bool has_rest = false;
|
| + bool hasParameterExpressions = false;
|
| + ZoneList<Expression*>* initializers =
|
| + new (zone()) ZoneList<Expression*>(0, zone());
|
| if (Check(Token::LPAREN)) {
|
| // '(' StrictFormalParameters ')'
|
| - ParseFormalParameterList(scope, &has_rest, &formals_classifier, &ok);
|
| + ParseFormalParameterList(scope, initializers, &hasParameterExpressions,
|
| + &has_rest, &formals_classifier, &ok);
|
| if (ok) ok = Check(Token::RPAREN);
|
| } else {
|
| // BindingIdentifier
|
| @@ -3396,6 +3401,113 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| }
|
|
|
|
|
| +ZoneList<Statement*>* Parser::DesugarInitializeParameters(
|
| + Scope* scope, bool hasParameterExpressions,
|
| + ZoneList<Expression*>* initializers) {
|
| + DCHECK(scope->is_function_scope());
|
| +
|
| + if (hasParameterExpressions) {
|
| + // If hasParameterExpressions for the function is true, each parameter is
|
| + // desugared as follows:
|
| + //
|
| + // SingleNameBinding :
|
| + // let <name> = %_Arguments(<index>);
|
| + // SingleNameBinding Initializer
|
| + // let <name> = IS_UNDEFINED(%_Arguments(<index>)) ? <initializer>
|
| + // : %_Arguments(<index>);
|
| + //
|
| + // TODO(caitp, dslomov): support BindingPatterns & rest parameters
|
| + //
|
| +
|
| + ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(0, zone());
|
| + for (int i = 0; i < initializers->length(); ++i) {
|
| + Expression* initializer = initializers->at(i);
|
| +
|
| + // Position of parameter VariableProxy, for hole-checking
|
| + int pos = scope->parameter_position(i);
|
| +
|
| + static const int capacity = 1;
|
| + static const bool is_initializer_block = true; // ?
|
| + Block* param_block =
|
| + factory()->NewBlock(nullptr, capacity, is_initializer_block, pos);
|
| +
|
| + Variable* param_var = scope->parameter(i);
|
| + param_var->set_mode(LET);
|
| +
|
| + // Lexically declare the initialized variable
|
| + static const VariableMode mode = LET;
|
| + VariableProxy* proxy = NewUnresolved(param_var->raw_name(), mode);
|
| + VariableDeclaration* declaration =
|
| + factory()->NewVariableDeclaration(proxy, mode, scope, pos);
|
| + scope->AddDeclaration(declaration);
|
| + proxy = factory()->NewVariableProxy(param_var);
|
| +
|
| + 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());
|
| +
|
| + if (initializer) {
|
| + // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i);
|
| + 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::INIT_LET, proxy, arg_or_default, RelocInfo::kNoPosition);
|
| +
|
| + param_block->AddStatement(
|
| + factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
|
| + zone());
|
| + proxy->var()->set_initializer_position(initializer->position());
|
| + } else {
|
| + // let <name> = %_Arguments(i)
|
| + Expression* assign = factory()->NewAssignment(
|
| + Token::INIT_LET, proxy,
|
| + factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
|
| + RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition);
|
| + param_block->AddStatement(
|
| + factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
|
| + zone());
|
| + proxy->var()->set_initializer_position(pos);
|
| + }
|
| + body->Add(param_block, zone());
|
| + }
|
| + return body;
|
| + } else {
|
| + // If hasParameterExpressions is false, remove the unnecessary parameter
|
| + // block scopes.
|
| + ZoneList<Scope*>* scopes = scope->inner_scopes();
|
| + for (int i = 0; i < scopes->length(); ++i) {
|
| + Scope* scope = scopes->at(i);
|
| + DCHECK(scope->is_block_scope());
|
| + scope->FinalizeBlockScope();
|
| + }
|
| + return nullptr;
|
| + }
|
| +}
|
| +
|
| +
|
| Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
| bool* ok) {
|
| // ForStatement ::
|
| @@ -3789,7 +3901,8 @@ void ParserTraits::DeclareArrowFunctionParameters(
|
| parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
|
|
|
| bool is_rest = false;
|
| - bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest);
|
| + int pos = expr->position();
|
| + bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest, pos);
|
|
|
| if (is_duplicate && !duplicate_loc->IsValid()) {
|
| *duplicate_loc = param_location;
|
| @@ -3903,8 +4016,12 @@ 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, &has_rest,
|
| - &formals_classifier, CHECK_OK);
|
| + ZoneList<Expression*>* initializers =
|
| + new (zone()) ZoneList<Expression*>(0, zone());
|
| + bool hasParameterExpressions = false;
|
| + num_parameters =
|
| + ParseFormalParameterList(scope, initializers, &hasParameterExpressions,
|
| + &has_rest, &formals_classifier, CHECK_OK);
|
| Expect(Token::RPAREN, CHECK_OK);
|
| int formals_end_position = scanner()->location().end_pos;
|
|
|
| @@ -4005,8 +4122,31 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| }
|
| }
|
| if (!is_lazily_parsed) {
|
| - body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
|
| - kind, CHECK_OK);
|
| + body = DesugarInitializeParameters(scope, hasParameterExpressions,
|
| + initializers);
|
| + if (hasParameterExpressions) {
|
| + // TODO(caitp): Function body scope must be a declaration scope
|
| + Scope* function_body_scope = NewScope(scope, BLOCK_SCOPE);
|
| + function_body_scope->set_start_position(scope->start_position());
|
| + function_body_scope->SetScopeName(function_name);
|
| + BlockState function_body_state(&scope_, function_body_scope);
|
| + ZoneList<Statement*>* inner_body = ParseEagerFunctionBody(
|
| + function_name, pos, fvar, fvar_init_op, kind, CHECK_OK);
|
| +
|
| + // Declare Block node
|
| + Block* block =
|
| + factory()->NewBlock(nullptr, inner_body->length(), false, pos);
|
| + block->set_scope(function_body_scope);
|
| + for (int i = 0; i < inner_body->length(); ++i) {
|
| + block->AddStatement(inner_body->at(i), zone());
|
| + }
|
| +
|
| + scope->set_end_position(function_body_scope->end_position());
|
| + body->Add(block, zone());
|
| + } else {
|
| + body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
|
| + kind, CHECK_OK);
|
| + }
|
| materialized_literal_count = function_state.materialized_literal_count();
|
| expected_property_count = function_state.expected_property_count();
|
| handler_count = function_state.handler_count();
|
| @@ -4288,6 +4428,8 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
|
| allow_harmony_spreadcalls());
|
| reusable_preparser_->set_allow_harmony_destructuring(
|
| allow_harmony_destructuring());
|
| + reusable_preparser_->set_allow_harmony_default_parameters(
|
| + allow_harmony_default_parameters());
|
| reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
|
| }
|
| PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
|
|
|