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

Side by Side Diff: src/parser.cc

Issue 1127063003: [es6] implement default parameters via desugaring (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 ? FunctionLiteral::ANONYMOUS_EXPRESSION 1127 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1128 : FunctionLiteral::NAMED_EXPRESSION) 1128 : FunctionLiteral::NAMED_EXPRESSION)
1129 : FunctionLiteral::DECLARATION; 1129 : FunctionLiteral::DECLARATION;
1130 bool ok = true; 1130 bool ok = true;
1131 1131
1132 if (shared_info->is_arrow()) { 1132 if (shared_info->is_arrow()) {
1133 Scope* scope = NewScope(scope_, ARROW_SCOPE); 1133 Scope* scope = NewScope(scope_, ARROW_SCOPE);
1134 scope->set_start_position(shared_info->start_position()); 1134 scope->set_start_position(shared_info->start_position());
1135 FormalParameterErrorLocations error_locs; 1135 FormalParameterErrorLocations error_locs;
1136 bool has_rest = false; 1136 bool has_rest = false;
1137 bool has_initializers = false;
1138 ZoneList<Expression*>* initializers =
1139 new (zone()) ZoneList<Expression*>(0, zone());
1137 if (Check(Token::LPAREN)) { 1140 if (Check(Token::LPAREN)) {
1138 // '(' StrictFormalParameters ')' 1141 // '(' StrictFormalParameters ')'
1139 ParseFormalParameterList(scope, &error_locs, &has_rest, &ok); 1142 ParseFormalParameterList(scope, &error_locs, initializers,
1143 &has_initializers, &has_rest, &ok);
1140 if (ok) ok = Check(Token::RPAREN); 1144 if (ok) ok = Check(Token::RPAREN);
1141 } else { 1145 } else {
1142 // BindingIdentifier 1146 // BindingIdentifier
1143 ParseFormalParameter(scope, &error_locs, has_rest, &ok); 1147 ParseFormalParameter(scope, &error_locs, nullptr, nullptr, has_rest,
1148 &ok);
1144 } 1149 }
1145 1150
1146 if (ok) { 1151 if (ok) {
1147 ExpressionClassifier classifier; 1152 ExpressionClassifier classifier;
1148 Expression* expression = ParseArrowFunctionLiteral( 1153 Expression* expression = ParseArrowFunctionLiteral(
1149 scope, error_locs, has_rest, &classifier, &ok); 1154 scope, error_locs, has_rest, &classifier, &ok);
1150 ValidateExpression(&classifier, &ok); 1155 ValidateExpression(&classifier, &ok);
1151 if (ok) { 1156 if (ok) {
1152 // Scanning must end at the same position that was recorded 1157 // Scanning must end at the same position that was recorded
1153 // previously. If not, parsing has been interrupted due to a stack 1158 // previously. If not, parsing has been interrupted due to a stack
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
2057 // initialization code. Thus, inside the 'with' statement, we need 2062 // initialization code. Thus, inside the 'with' statement, we need
2058 // both access to the static and the dynamic context chain; the 2063 // both access to the static and the dynamic context chain; the
2059 // runtime needs to provide both. 2064 // runtime needs to provide both.
2060 if (resolve && var != NULL) { 2065 if (resolve && var != NULL) {
2061 proxy->BindTo(var); 2066 proxy->BindTo(var);
2062 } 2067 }
2063 return var; 2068 return var;
2064 } 2069 }
2065 2070
2066 2071
2072 void Parser::ShadowParametersForExpressions(Scope* scope) {
2073 scope->ShadowParametersForExpressions();
2074 }
2075
2076
2067 // Language extension which is only enabled for source files loaded 2077 // Language extension which is only enabled for source files loaded
2068 // through the API's extension mechanism. A native function 2078 // through the API's extension mechanism. A native function
2069 // declaration is resolved by looking up the function through a 2079 // declaration is resolved by looking up the function through a
2070 // callback provided by the extension. 2080 // callback provided by the extension.
2071 Statement* Parser::ParseNativeDeclaration(bool* ok) { 2081 Statement* Parser::ParseNativeDeclaration(bool* ok) {
2072 int pos = peek_position(); 2082 int pos = peek_position();
2073 Expect(Token::FUNCTION, CHECK_OK); 2083 Expect(Token::FUNCTION, CHECK_OK);
2074 // Allow "eval" or "arguments" for backward compatibility. 2084 // Allow "eval" or "arguments" for backward compatibility.
2075 const AstRawString* name = 2085 const AstRawString* name =
2076 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 2086 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
(...skipping 1438 matching lines...) Expand 10 before | Expand all | Expand 10 after
3515 3525
3516 inner_scope->set_end_position(scanner()->location().end_pos); 3526 inner_scope->set_end_position(scanner()->location().end_pos);
3517 inner_block->set_scope(inner_scope); 3527 inner_block->set_scope(inner_scope);
3518 scope_ = for_scope; 3528 scope_ = for_scope;
3519 3529
3520 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3530 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3521 return outer_block; 3531 return outer_block;
3522 } 3532 }
3523 3533
3524 3534
3535 ZoneList<Statement*>* Parser::DesugarInitializeParameters(
3536 Scope* scope, bool has_initializers, ZoneList<Expression*>* initializers) {
3537 DCHECK(scope->is_function_scope());
3538
arv (Not doing code reviews) 2015/05/06 20:32:38 How about adding a comment block explaining how th
3539 if (has_initializers) {
3540 ShadowParametersForExpressions(scope);
3541 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(0, zone());
3542 for (int i = 0; i < initializers->length(); ++i) {
3543 Expression* initializer = initializers->at(i);
3544
3545 // Position of parameter VariableProxy, for hole-checking
3546 int pos = scope->parameter_position(i);
3547
3548 // Lexically declare the initialized variable
3549 static const VariableMode mode = LET;
3550 VariableProxy* proxy =
3551 NewUnresolved(scope->parameter(i)->raw_name(), mode);
3552 VariableDeclaration* declaration = factory()->NewVariableDeclaration(
3553 proxy, mode, scope, RelocInfo::kNoPosition);
3554 bool ok = true;
3555 proxy = factory()->NewVariableProxy(Declare(declaration, true, &ok), pos);
3556 DCHECK(ok);
3557 proxy->var()->set_maybe_assigned();
3558
3559 const AstRawString* fn_name = ast_value_factory()->empty_string();
3560 const Runtime::Function* arguments =
3561 Runtime::FunctionForId(Runtime::kInlineArguments);
arv (Not doing code reviews) 2015/05/06 20:32:38 I think Andreas wanted: function f(x = expr) {}
caitp (gmail) 2015/05/06 20:42:55 I don't think bounds-checking is needed --- at lea
3562 ZoneList<Expression*>* arguments_i0 =
3563 new (zone()) ZoneList<Expression*>(0, zone());
3564 arguments_i0->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
3565 zone());
3566
3567 // TODO(caitp): ensure proper TDZ behaviour --- need hole-check for
3568 // all parameter bindings, including ones without initializers
3569 if (initializer) {
3570 // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i);
3571 ZoneList<Expression*>* arguments_i1 =
3572 new (zone()) ZoneList<Expression*>(0, zone());
3573 arguments_i1->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
3574 zone());
3575
3576 Expression* arg_or_default = factory()->NewConditional(
3577 // condition:
3578 factory()->NewCompareOperation(
3579 Token::EQ_STRICT,
3580 factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
3581 RelocInfo::kNoPosition),
3582 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3583 RelocInfo::kNoPosition),
3584 // if true:
3585 initializer,
3586 // if false:
3587 factory()->NewCallRuntime(fn_name, arguments, arguments_i1,
3588 RelocInfo::kNoPosition),
3589 RelocInfo::kNoPosition);
3590
3591 Expression* assign = factory()->NewAssignment(
3592 Token::INIT_LET, proxy, arg_or_default, RelocInfo::kNoPosition);
3593
3594 body->Add(
3595 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
3596 zone());
3597 proxy->var()->set_initializer_position(initializer->position());
3598 } else {
3599 // let <name> = %_Arguments(i)
3600 Expression* assign = factory()->NewAssignment(
3601 Token::INIT_LET, proxy,
3602 factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
3603 RelocInfo::kNoPosition),
3604 RelocInfo::kNoPosition);
3605 body->Add(
3606 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
3607 zone());
3608 proxy->var()->set_initializer_position(pos);
3609 }
3610 }
3611 return body;
3612 } else {
arv (Not doing code reviews) 2015/05/06 20:32:38 no else after return
3613 // If hasParameterExpressions is false, remove the unnecessary parameter
3614 // block scopes.
3615 ZoneList<Scope*>* scopes = scope->inner_scopes();
3616 for (int i = 0; i < scopes->length(); ++i) {
3617 Scope* scope = scopes->at(i);
3618 DCHECK(scope->is_block_scope());
3619 scope->FinalizeBlockScope();
3620 }
3621 return nullptr;
3622 }
3623 }
3624
3625
3525 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3626 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3526 bool* ok) { 3627 bool* ok) {
3527 // ForStatement :: 3628 // ForStatement ::
3528 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 3629 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3529 3630
3530 int stmt_pos = peek_position(); 3631 int stmt_pos = peek_position();
3531 bool is_const = false; 3632 bool is_const = false;
3532 Statement* init = NULL; 3633 Statement* init = NULL;
3533 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3634 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3534 3635
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
3925 error_locs->reserved = param_location; 4026 error_locs->reserved = param_location;
3926 if (!error_locs->undefined.IsValid() && IsUndefined(raw_name)) 4027 if (!error_locs->undefined.IsValid() && IsUndefined(raw_name))
3927 error_locs->undefined = param_location; 4028 error_locs->undefined = param_location;
3928 4029
3929 // When the formal parameter was originally seen, it was parsed as a 4030 // When the formal parameter was originally seen, it was parsed as a
3930 // VariableProxy and recorded as unresolved in the scope. Here we undo that 4031 // VariableProxy and recorded as unresolved in the scope. Here we undo that
3931 // parse-time side-effect. 4032 // parse-time side-effect.
3932 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); 4033 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
3933 4034
3934 bool is_rest = false; 4035 bool is_rest = false;
3935 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest); 4036 int pos = expr->position();
4037 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest, pos);
3936 4038
3937 if (is_duplicate) { 4039 if (is_duplicate) {
3938 // Arrow function parameter lists are parsed as StrictFormalParameters, 4040 // Arrow function parameter lists are parsed as StrictFormalParameters,
3939 // which means that they cannot have duplicates. Note that this is a subset 4041 // which means that they cannot have duplicates. Note that this is a subset
3940 // of the restrictions placed on parameters to functions whose body is 4042 // of the restrictions placed on parameters to functions whose body is
3941 // strict. 4043 // strict.
3942 ReportMessageAt(param_location, 4044 ReportMessageAt(param_location,
3943 "duplicate_arrow_function_formal_parameter"); 4045 "duplicate_arrow_function_formal_parameter");
3944 *ok = false; 4046 *ok = false;
3945 return; 4047 return;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
4054 // expressions. This also marks the FunctionState as a generator. 4156 // expressions. This also marks the FunctionState as a generator.
4055 Variable* temp = scope_->DeclarationScope()->NewTemporary( 4157 Variable* temp = scope_->DeclarationScope()->NewTemporary(
4056 ast_value_factory()->dot_generator_object_string()); 4158 ast_value_factory()->dot_generator_object_string());
4057 function_state.set_generator_object_variable(temp); 4159 function_state.set_generator_object_variable(temp);
4058 } 4160 }
4059 4161
4060 bool has_rest = false; 4162 bool has_rest = false;
4061 Expect(Token::LPAREN, CHECK_OK); 4163 Expect(Token::LPAREN, CHECK_OK);
4062 int start_position = scanner()->location().beg_pos; 4164 int start_position = scanner()->location().beg_pos;
4063 scope_->set_start_position(start_position); 4165 scope_->set_start_position(start_position);
4166 ZoneList<Expression*>* initializers =
4167 new (zone()) ZoneList<Expression*>(0, zone());
4168 bool has_initializers = false;
4064 num_parameters = 4169 num_parameters =
4065 ParseFormalParameterList(scope, &error_locs, &has_rest, CHECK_OK); 4170 ParseFormalParameterList(scope, &error_locs, initializers,
4171 &has_initializers, &has_rest, CHECK_OK);
4066 Expect(Token::RPAREN, CHECK_OK); 4172 Expect(Token::RPAREN, CHECK_OK);
4067 int formals_end_position = scanner()->location().end_pos; 4173 int formals_end_position = scanner()->location().end_pos;
4068 4174
4069 CheckArityRestrictions(num_parameters, arity_restriction, start_position, 4175 CheckArityRestrictions(num_parameters, arity_restriction, start_position,
4070 formals_end_position, CHECK_OK); 4176 formals_end_position, CHECK_OK);
4071 4177
4072 Expect(Token::LBRACE, CHECK_OK); 4178 Expect(Token::LBRACE, CHECK_OK);
4073 4179
4074 // If we have a named function expression, we add a local variable 4180 // If we have a named function expression, we add a local variable
4075 // declaration to the body of the function with the name of the 4181 // declaration to the body of the function with the name of the
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4134 parenthesized_function_ = false; // The bit was set for this function only. 4240 parenthesized_function_ = false; // The bit was set for this function only.
4135 4241
4136 if (is_lazily_parsed) { 4242 if (is_lazily_parsed) {
4137 for (Scope* s = scope_->outer_scope(); 4243 for (Scope* s = scope_->outer_scope();
4138 s != nullptr && (s != s->DeclarationScope()); s = s->outer_scope()) { 4244 s != nullptr && (s != s->DeclarationScope()); s = s->outer_scope()) {
4139 s->ForceContextAllocation(); 4245 s->ForceContextAllocation();
4140 } 4246 }
4141 SkipLazyFunctionBody(&materialized_literal_count, 4247 SkipLazyFunctionBody(&materialized_literal_count,
4142 &expected_property_count, CHECK_OK); 4248 &expected_property_count, CHECK_OK);
4143 } else { 4249 } else {
4144 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, 4250 body = DesugarInitializeParameters(scope, has_initializers, initializers);
4145 kind, CHECK_OK); 4251 if (has_initializers) {
4252 // TODO(caitp): Function body scope must be a declaration scope
4253 Scope* function_body_scope = NewScope(scope, BLOCK_SCOPE);
4254 function_body_scope->set_start_position(scope->start_position());
4255 function_body_scope->SetScopeName(function_name);
4256 BlockState function_body_state(&scope_, function_body_scope);
4257 ZoneList<Statement*>* inner_body = ParseEagerFunctionBody(
4258 function_name, pos, fvar, fvar_init_op, kind, CHECK_OK);
4259 scope->set_end_position(function_body_scope->end_position());
4260 body->AddAll(*inner_body, zone());
4261 } else {
4262 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
4263 kind, CHECK_OK);
4264 }
4146 materialized_literal_count = function_state.materialized_literal_count(); 4265 materialized_literal_count = function_state.materialized_literal_count();
4147 expected_property_count = function_state.expected_property_count(); 4266 expected_property_count = function_state.expected_property_count();
4148 handler_count = function_state.handler_count(); 4267 handler_count = function_state.handler_count();
4149 4268
4150 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { 4269 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
4151 if (!function_state.super_location().IsValid()) { 4270 if (!function_state.super_location().IsValid()) {
4152 ReportMessageAt(function_name_location, 4271 ReportMessageAt(function_name_location,
4153 "strong_super_call_missing", kReferenceError); 4272 "strong_super_call_missing", kReferenceError);
4154 *ok = false; 4273 *ok = false;
4155 return nullptr; 4274 return nullptr;
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after
5891 6010
5892 Expression* Parser::SpreadCallNew(Expression* function, 6011 Expression* Parser::SpreadCallNew(Expression* function,
5893 ZoneList<v8::internal::Expression*>* args, 6012 ZoneList<v8::internal::Expression*>* args,
5894 int pos) { 6013 int pos) {
5895 args->InsertAt(0, function, zone()); 6014 args->InsertAt(0, function, zone());
5896 6015
5897 return factory()->NewCallRuntime( 6016 return factory()->NewCallRuntime(
5898 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 6017 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5899 } 6018 }
5900 } } // namespace v8::internal 6019 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698