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

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: Rebase + rossberg nits Created 5 years, 6 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
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 set_allow_harmony_classes(FLAG_harmony_classes); 877 set_allow_harmony_classes(FLAG_harmony_classes);
878 set_allow_harmony_object_literals(FLAG_harmony_object_literals); 878 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
879 set_allow_harmony_sloppy(FLAG_harmony_sloppy); 879 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
880 set_allow_harmony_unicode(FLAG_harmony_unicode); 880 set_allow_harmony_unicode(FLAG_harmony_unicode);
881 set_allow_harmony_computed_property_names( 881 set_allow_harmony_computed_property_names(
882 FLAG_harmony_computed_property_names); 882 FLAG_harmony_computed_property_names);
883 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters); 883 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters);
884 set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls); 884 set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
885 set_allow_harmony_destructuring(FLAG_harmony_destructuring); 885 set_allow_harmony_destructuring(FLAG_harmony_destructuring);
886 set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays); 886 set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays);
887 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters);
887 set_allow_strong_mode(FLAG_strong_mode); 888 set_allow_strong_mode(FLAG_strong_mode);
888 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 889 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
889 ++feature) { 890 ++feature) {
890 use_counts_[feature] = 0; 891 use_counts_[feature] = 0;
891 } 892 }
892 if (info->ast_value_factory() == NULL) { 893 if (info->ast_value_factory() == NULL) {
893 // info takes ownership of AstValueFactory. 894 // info takes ownership of AstValueFactory.
894 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); 895 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
895 info->set_ast_value_factory_owned(); 896 info->set_ast_value_factory_owned();
896 ast_value_factory_ = info->ast_value_factory(); 897 ast_value_factory_ = info->ast_value_factory();
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 : FunctionLiteral::NAMED_EXPRESSION) 1142 : FunctionLiteral::NAMED_EXPRESSION)
1142 : FunctionLiteral::DECLARATION; 1143 : FunctionLiteral::DECLARATION;
1143 bool ok = true; 1144 bool ok = true;
1144 1145
1145 if (shared_info->is_arrow()) { 1146 if (shared_info->is_arrow()) {
1146 Scope* scope = 1147 Scope* scope =
1147 NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 1148 NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
1148 scope->set_start_position(shared_info->start_position()); 1149 scope->set_start_position(shared_info->start_position());
1149 ExpressionClassifier formals_classifier; 1150 ExpressionClassifier formals_classifier;
1150 bool has_rest = false; 1151 bool has_rest = false;
1152 bool has_parameter_expressions = false;
1153
1154 // TODO(caitp): make default parameters work in arrow functions
1155 ZoneList<Expression*>* initializers =
1156 new (zone()) ZoneList<Expression*>(0, zone());
1151 if (Check(Token::LPAREN)) { 1157 if (Check(Token::LPAREN)) {
1152 // '(' StrictFormalParameters ')' 1158 // '(' StrictFormalParameters ')'
1153 ParseFormalParameterList(scope, &has_rest, &formals_classifier, &ok); 1159 ParseFormalParameterList(scope, initializers,
1160 &has_parameter_expressions, &has_rest,
1161 &formals_classifier, &ok);
1154 if (ok) ok = Check(Token::RPAREN); 1162 if (ok) ok = Check(Token::RPAREN);
1155 } else { 1163 } else {
1156 // BindingIdentifier 1164 // BindingIdentifier
1157 ParseFormalParameter(scope, has_rest, &formals_classifier, &ok); 1165 ParseFormalParameter(scope, has_rest, &formals_classifier, &ok);
1158 } 1166 }
1159 1167
1160 if (ok) { 1168 if (ok) {
1161 Expression* expression = 1169 Expression* expression =
1162 ParseArrowFunctionLiteral(scope, has_rest, formals_classifier, &ok); 1170 ParseArrowFunctionLiteral(scope, has_rest, formals_classifier, &ok);
1163 if (ok) { 1171 if (ok) {
(...skipping 2233 matching lines...) Expand 10 before | Expand all | Expand 10 after
3397 3405
3398 inner_scope->set_end_position(scanner()->location().end_pos); 3406 inner_scope->set_end_position(scanner()->location().end_pos);
3399 inner_block->set_scope(inner_scope); 3407 inner_block->set_scope(inner_scope);
3400 scope_ = for_scope; 3408 scope_ = for_scope;
3401 3409
3402 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3410 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3403 return outer_block; 3411 return outer_block;
3404 } 3412 }
3405 3413
3406 3414
3415 ZoneList<Statement*>* Parser::DesugarInitializeParameters(
3416 Scope* scope, bool has_parameter_expressions,
3417 ZoneList<Expression*>* initializers) {
3418 DCHECK(scope->is_function_scope());
3419
3420 if (has_parameter_expressions) {
3421 // If has_parameter_expressions for the function is true, each parameter is
3422 // desugared as follows:
3423 //
3424 // SingleNameBinding :
3425 // let <name> = %_Arguments(<index>);
3426 // SingleNameBinding Initializer
3427 // let <name> = IS_UNDEFINED(%_Arguments(<index>)) ? <initializer>
3428 // : %_Arguments(<index>);
3429 //
3430 // TODO(caitp, dslomov): support BindingPatterns & rest parameters
3431 //
3432 scope->UndeclareParametersForExpressions();
3433 ZoneList<Statement*>* body =
3434 new (zone()) ZoneList<Statement*>(initializers->length(), zone());
3435 for (int i = 0; i < initializers->length(); ++i) {
3436 Expression* initializer = initializers->at(i);
3437
3438 // Position of parameter VariableProxy, for hole-checking
3439 int pos = scope->parameter_position(i);
3440
3441 static const int kCapacity = 1;
3442 static const bool kIsInitializerBlock = true;
3443 Block* param_block =
3444 factory()->NewBlock(nullptr, kCapacity, kIsInitializerBlock, pos);
3445
3446 VariableProxy* proxy =
3447 NewUnresolved(scope->parameter(i)->raw_name(), LET);
3448 VariableDeclaration* declaration = factory()->NewVariableDeclaration(
3449 proxy, LET, scope, RelocInfo::kNoPosition);
3450
3451 bool ok = true;
3452 // All formal parameters have been removed from the scope VariableMap,
3453 // and so Declare() should not be able to fail.
3454 proxy = factory()->NewVariableProxy(Declare(declaration, true, &ok), pos);
3455 DCHECK(ok);
3456
3457 const AstRawString* fn_name = ast_value_factory()->empty_string();
3458 const Runtime::Function* arguments =
3459 Runtime::FunctionForId(Runtime::kInlineArguments);
3460 ZoneList<Expression*>* arguments_i0 =
3461 new (zone()) ZoneList<Expression*>(1, zone());
3462 arguments_i0->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
3463 zone());
3464
3465 if (initializer == nullptr) {
3466 // let <name> = %_Arguments(i)
3467 Expression* assign = factory()->NewAssignment(
3468 Token::INIT_LET, proxy,
3469 factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
3470 RelocInfo::kNoPosition),
3471 RelocInfo::kNoPosition);
3472 param_block->AddStatement(
3473 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
3474 zone());
3475 proxy->var()->set_initializer_position(pos);
3476 } else {
3477 // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i);
3478 ZoneList<Expression*>* arguments_i1 =
3479 new (zone()) ZoneList<Expression*>(1, zone());
3480 arguments_i1->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
3481 zone());
3482
3483 Expression* arg_or_default = factory()->NewConditional(
3484 // condition:
3485 factory()->NewCompareOperation(
3486 Token::EQ_STRICT,
3487 factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
3488 RelocInfo::kNoPosition),
3489 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3490 RelocInfo::kNoPosition),
3491 // if true:
3492 initializer,
3493 // if false:
3494 factory()->NewCallRuntime(fn_name, arguments, arguments_i1,
3495 RelocInfo::kNoPosition),
3496 RelocInfo::kNoPosition);
3497
3498 Expression* assign = factory()->NewAssignment(
3499 Token::INIT_LET, proxy, arg_or_default, RelocInfo::kNoPosition);
3500
3501 param_block->AddStatement(
3502 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
3503 zone());
3504 proxy->var()->set_initializer_position(initializer->position());
3505 }
3506 body->Add(param_block, zone());
3507 }
3508 return body;
3509 } else {
3510 // If has_parameter_expressions is false, remove the unnecessary parameter
3511 // block scopes.
3512 ZoneList<Scope*>* scopes = scope->inner_scopes();
3513 for (int i = 0; i < scopes->length(); ++i) {
3514 Scope* scope = scopes->at(i);
3515 DCHECK(scope->is_block_scope());
3516 scope->FinalizeBlockScope();
3517 }
3518 return nullptr;
3519 }
3520 }
3521
3522
3407 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3523 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3408 bool* ok) { 3524 bool* ok) {
3409 // ForStatement :: 3525 // ForStatement ::
3410 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 3526 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3411 3527
3412 int stmt_pos = peek_position(); 3528 int stmt_pos = peek_position();
3413 bool is_const = false; 3529 bool is_const = false;
3414 Statement* init = NULL; 3530 Statement* init = NULL;
3415 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3531 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3416 3532
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
3767 const AstRawString* raw_name = expr->AsVariableProxy()->raw_name(); 3883 const AstRawString* raw_name = expr->AsVariableProxy()->raw_name();
3768 Scanner::Location param_location(expr->position(), 3884 Scanner::Location param_location(expr->position(),
3769 expr->position() + raw_name->length()); 3885 expr->position() + raw_name->length());
3770 3886
3771 // When the formal parameter was originally seen, it was parsed as a 3887 // When the formal parameter was originally seen, it was parsed as a
3772 // VariableProxy and recorded as unresolved in the scope. Here we undo that 3888 // VariableProxy and recorded as unresolved in the scope. Here we undo that
3773 // parse-time side-effect. 3889 // parse-time side-effect.
3774 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); 3890 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
3775 3891
3776 bool is_rest = false; 3892 bool is_rest = false;
3777 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest); 3893 int pos = expr->position();
3894 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest, pos);
3778 3895
3779 if (is_duplicate && !duplicate_loc->IsValid()) { 3896 if (is_duplicate && !duplicate_loc->IsValid()) {
3780 *duplicate_loc = param_location; 3897 *duplicate_loc = param_location;
3781 } 3898 }
3782 } 3899 }
3783 3900
3784 3901
3785 void ParserTraits::ParseArrowFunctionFormalParameters( 3902 void ParserTraits::ParseArrowFunctionFormalParameters(
3786 Scope* scope, Expression* params, const Scanner::Location& params_loc, 3903 Scope* scope, Expression* params, const Scanner::Location& params_loc,
3787 bool* is_rest, Scanner::Location* duplicate_loc, bool* ok) { 3904 bool* is_rest, Scanner::Location* duplicate_loc, bool* ok) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3878 3995
3879 // Calling a generator returns a generator object. That object is stored 3996 // Calling a generator returns a generator object. That object is stored
3880 // in a temporary variable, a definition that is used by "yield" 3997 // in a temporary variable, a definition that is used by "yield"
3881 // expressions. This also marks the FunctionState as a generator. 3998 // expressions. This also marks the FunctionState as a generator.
3882 Variable* temp = scope_->DeclarationScope()->NewTemporary( 3999 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3883 ast_value_factory()->dot_generator_object_string()); 4000 ast_value_factory()->dot_generator_object_string());
3884 function_state.set_generator_object_variable(temp); 4001 function_state.set_generator_object_variable(temp);
3885 } 4002 }
3886 4003
3887 bool has_rest = false; 4004 bool has_rest = false;
4005 bool has_parameter_expressions = false;
3888 Expect(Token::LPAREN, CHECK_OK); 4006 Expect(Token::LPAREN, CHECK_OK);
3889 int start_position = scanner()->location().beg_pos; 4007 int start_position = scanner()->location().beg_pos;
3890 scope_->set_start_position(start_position); 4008 scope_->set_start_position(start_position);
3891 num_parameters = ParseFormalParameterList(scope, &has_rest, 4009 ZoneList<Expression*>* initializers =
3892 &formals_classifier, CHECK_OK); 4010 new (zone()) ZoneList<Expression*>(0, zone());
4011 num_parameters = ParseFormalParameterList(
4012 scope, initializers, &has_parameter_expressions, &has_rest,
4013 &formals_classifier, CHECK_OK);
3893 Expect(Token::RPAREN, CHECK_OK); 4014 Expect(Token::RPAREN, CHECK_OK);
3894 int formals_end_position = scanner()->location().end_pos; 4015 int formals_end_position = scanner()->location().end_pos;
3895 4016
3896 CheckArityRestrictions(num_parameters, arity_restriction, has_rest, 4017 CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
3897 start_position, formals_end_position, CHECK_OK); 4018 start_position, formals_end_position, CHECK_OK);
3898 4019
3899 Expect(Token::LBRACE, CHECK_OK); 4020 Expect(Token::LBRACE, CHECK_OK);
3900 4021
3901 // If we have a named function expression, we add a local variable 4022 // If we have a named function expression, we add a local variable
3902 // declaration to the body of the function with the name of the 4023 // declaration to the body of the function with the name of the
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3983 is_lazily_parsed = false; 4104 is_lazily_parsed = false;
3984 4105
3985 // This is probably an initialization function. Inform the compiler it 4106 // This is probably an initialization function. Inform the compiler it
3986 // should also eager-compile this function, and that we expect it to be 4107 // should also eager-compile this function, and that we expect it to be
3987 // used once. 4108 // used once.
3988 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 4109 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
3989 should_be_used_once_hint = true; 4110 should_be_used_once_hint = true;
3990 } 4111 }
3991 } 4112 }
3992 if (!is_lazily_parsed) { 4113 if (!is_lazily_parsed) {
3993 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, 4114 body = DesugarInitializeParameters(scope, has_parameter_expressions,
3994 kind, CHECK_OK); 4115 initializers);
4116 if (has_parameter_expressions) {
4117 // TODO(caitp): Function body scope must be a declaration scope
4118 Scope* function_body_scope = NewScope(scope, BLOCK_SCOPE);
4119 function_body_scope->set_start_position(scope->start_position());
4120 function_body_scope->SetScopeName(function_name);
4121 BlockState function_body_state(&scope_, function_body_scope);
4122 ZoneList<Statement*>* inner_body = ParseEagerFunctionBody(
4123 function_name, pos, fvar, fvar_init_op, kind, CHECK_OK);
4124
4125 // Declare Block node
4126 Block* block =
4127 factory()->NewBlock(nullptr, inner_body->length(), false, pos);
4128 block->set_scope(function_body_scope);
4129 for (int i = 0; i < inner_body->length(); ++i) {
4130 block->AddStatement(inner_body->at(i), zone());
4131 }
4132
4133 scope->set_end_position(function_body_scope->end_position());
4134 body->Add(block, zone());
4135 } else {
4136 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
4137 kind, CHECK_OK);
4138 }
3995 materialized_literal_count = function_state.materialized_literal_count(); 4139 materialized_literal_count = function_state.materialized_literal_count();
3996 expected_property_count = function_state.expected_property_count(); 4140 expected_property_count = function_state.expected_property_count();
3997 handler_count = function_state.handler_count(); 4141 handler_count = function_state.handler_count();
3998 4142
3999 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { 4143 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
4000 if (!function_state.super_location().IsValid()) { 4144 if (!function_state.super_location().IsValid()) {
4001 ReportMessageAt(function_name_location, 4145 ReportMessageAt(function_name_location,
4002 MessageTemplate::kStrongSuperCallMissing, 4146 MessageTemplate::kStrongSuperCallMissing,
4003 kReferenceError); 4147 kReferenceError);
4004 *ok = false; 4148 *ok = false;
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
4268 reusable_preparser_->set_allow_harmony_computed_property_names( 4412 reusable_preparser_->set_allow_harmony_computed_property_names(
4269 allow_harmony_computed_property_names()); 4413 allow_harmony_computed_property_names());
4270 reusable_preparser_->set_allow_harmony_rest_params( 4414 reusable_preparser_->set_allow_harmony_rest_params(
4271 allow_harmony_rest_params()); 4415 allow_harmony_rest_params());
4272 reusable_preparser_->set_allow_harmony_spreadcalls( 4416 reusable_preparser_->set_allow_harmony_spreadcalls(
4273 allow_harmony_spreadcalls()); 4417 allow_harmony_spreadcalls());
4274 reusable_preparser_->set_allow_harmony_destructuring( 4418 reusable_preparser_->set_allow_harmony_destructuring(
4275 allow_harmony_destructuring()); 4419 allow_harmony_destructuring());
4276 reusable_preparser_->set_allow_harmony_spread_arrays( 4420 reusable_preparser_->set_allow_harmony_spread_arrays(
4277 allow_harmony_spread_arrays()); 4421 allow_harmony_spread_arrays());
4422 reusable_preparser_->set_allow_harmony_default_parameters(
4423 allow_harmony_default_parameters());
4278 reusable_preparser_->set_allow_strong_mode(allow_strong_mode()); 4424 reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
4279 } 4425 }
4280 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 4426 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4281 language_mode(), function_state_->kind(), logger, bookmark); 4427 language_mode(), function_state_->kind(), logger, bookmark);
4282 if (pre_parse_timer_ != NULL) { 4428 if (pre_parse_timer_ != NULL) {
4283 pre_parse_timer_->Stop(); 4429 pre_parse_timer_->Stop();
4284 } 4430 }
4285 return result; 4431 return result;
4286 } 4432 }
4287 4433
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after
5790 5936
5791 Expression* Parser::SpreadCallNew(Expression* function, 5937 Expression* Parser::SpreadCallNew(Expression* function,
5792 ZoneList<v8::internal::Expression*>* args, 5938 ZoneList<v8::internal::Expression*>* args,
5793 int pos) { 5939 int pos) {
5794 args->InsertAt(0, function, zone()); 5940 args->InsertAt(0, function, zone());
5795 5941
5796 return factory()->NewCallRuntime( 5942 return factory()->NewCallRuntime(
5797 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5943 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5798 } 5944 }
5799 } } // namespace v8::internal 5945 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698