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

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: Add more context-allocation tests 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
« src/parser.h ('K') | « 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 861 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 set_allow_harmony_classes(FLAG_harmony_classes); 872 set_allow_harmony_classes(FLAG_harmony_classes);
873 set_allow_harmony_object_literals(FLAG_harmony_object_literals); 873 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
874 set_allow_harmony_sloppy(FLAG_harmony_sloppy); 874 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
875 set_allow_harmony_unicode(FLAG_harmony_unicode); 875 set_allow_harmony_unicode(FLAG_harmony_unicode);
876 set_allow_harmony_computed_property_names( 876 set_allow_harmony_computed_property_names(
877 FLAG_harmony_computed_property_names); 877 FLAG_harmony_computed_property_names);
878 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters); 878 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters);
879 set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls); 879 set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
880 set_allow_harmony_destructuring(FLAG_harmony_destructuring); 880 set_allow_harmony_destructuring(FLAG_harmony_destructuring);
881 set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays); 881 set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays);
882 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters);
882 set_allow_strong_mode(FLAG_strong_mode); 883 set_allow_strong_mode(FLAG_strong_mode);
883 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 884 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
884 ++feature) { 885 ++feature) {
885 use_counts_[feature] = 0; 886 use_counts_[feature] = 0;
886 } 887 }
887 if (info->ast_value_factory() == NULL) { 888 if (info->ast_value_factory() == NULL) {
888 // info takes ownership of AstValueFactory. 889 // info takes ownership of AstValueFactory.
889 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); 890 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
890 info->set_ast_value_factory_owned(); 891 info->set_ast_value_factory_owned();
891 ast_value_factory_ = info->ast_value_factory(); 892 ast_value_factory_ = info->ast_value_factory();
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 ? FunctionLiteral::ANONYMOUS_EXPRESSION 1136 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1136 : FunctionLiteral::NAMED_EXPRESSION) 1137 : FunctionLiteral::NAMED_EXPRESSION)
1137 : FunctionLiteral::DECLARATION; 1138 : FunctionLiteral::DECLARATION;
1138 bool ok = true; 1139 bool ok = true;
1139 1140
1140 if (shared_info->is_arrow()) { 1141 if (shared_info->is_arrow()) {
1141 Scope* scope = NewScope(scope_, ARROW_SCOPE); 1142 Scope* scope = NewScope(scope_, ARROW_SCOPE);
1142 scope->set_start_position(shared_info->start_position()); 1143 scope->set_start_position(shared_info->start_position());
1143 ExpressionClassifier formals_classifier; 1144 ExpressionClassifier formals_classifier;
1144 bool has_rest = false; 1145 bool has_rest = false;
1146 bool hasParameterExpressions = false;
adamk 2015/05/26 19:58:10 Same style nit, use_underscores. I think this show
caitp (gmail) 2015/05/26 20:24:44 Done.
1147 ZoneList<Expression*>* initializers =
adamk 2015/05/26 19:58:10 Please add a TODO here, since you're just dropping
caitp (gmail) 2015/05/26 20:24:44 Done.
1148 new (zone()) ZoneList<Expression*>(0, zone());
1145 if (Check(Token::LPAREN)) { 1149 if (Check(Token::LPAREN)) {
1146 // '(' StrictFormalParameters ')' 1150 // '(' StrictFormalParameters ')'
1147 ParseFormalParameterList(scope, &has_rest, &formals_classifier, &ok); 1151 ParseFormalParameterList(scope, initializers, &hasParameterExpressions,
1152 &has_rest, &formals_classifier, &ok);
1148 if (ok) ok = Check(Token::RPAREN); 1153 if (ok) ok = Check(Token::RPAREN);
1149 } else { 1154 } else {
1150 // BindingIdentifier 1155 // BindingIdentifier
1151 ParseFormalParameter(scope, has_rest, &formals_classifier, &ok); 1156 ParseFormalParameter(scope, has_rest, &formals_classifier, &ok);
1152 } 1157 }
1153 1158
1154 if (ok) { 1159 if (ok) {
1155 Expression* expression = 1160 Expression* expression =
1156 ParseArrowFunctionLiteral(scope, has_rest, formals_classifier, &ok); 1161 ParseArrowFunctionLiteral(scope, has_rest, formals_classifier, &ok);
1157 if (ok) { 1162 if (ok) {
(...skipping 2233 matching lines...) Expand 10 before | Expand all | Expand 10 after
3391 3396
3392 inner_scope->set_end_position(scanner()->location().end_pos); 3397 inner_scope->set_end_position(scanner()->location().end_pos);
3393 inner_block->set_scope(inner_scope); 3398 inner_block->set_scope(inner_scope);
3394 scope_ = for_scope; 3399 scope_ = for_scope;
3395 3400
3396 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3401 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3397 return outer_block; 3402 return outer_block;
3398 } 3403 }
3399 3404
3400 3405
3406 ZoneList<Statement*>* Parser::DesugarInitializeParameters(
3407 Scope* scope, bool hasParameterExpressions,
3408 ZoneList<Expression*>* initializers) {
3409 DCHECK(scope->is_function_scope());
3410
3411 if (hasParameterExpressions) {
3412 // If hasParameterExpressions for the function is true, each parameter is
3413 // desugared as follows:
3414 //
3415 // SingleNameBinding :
3416 // let <name> = %_Arguments(<index>);
3417 // SingleNameBinding Initializer
3418 // let <name> = IS_UNDEFINED(%_Arguments(<index>)) ? <initializer>
3419 // : %_Arguments(<index>);
3420 //
3421 // TODO(caitp, dslomov): support BindingPatterns & rest parameters
3422 //
3423 scope->UndeclareParametersForExpressions();
3424 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(0, zone());
adamk 2015/05/26 19:58:10 Don't you know how big a list you need here (initi
caitp (gmail) 2015/05/26 20:24:44 Done.
3425 for (int i = 0; i < initializers->length(); ++i) {
3426 Expression* initializer = initializers->at(i);
3427
3428 // Position of parameter VariableProxy, for hole-checking
3429 int pos = scope->parameter_position(i);
3430
3431 static const int capacity = 1;
adamk 2015/05/26 19:58:10 More style nits: kCapacity
caitp (gmail) 2015/05/26 20:24:44 Done.
3432 static const bool is_initializer_block = true; // ?
adamk 2015/05/26 19:58:10 kIsInitializerBlock. Also the "// ?" should eithe
caitp (gmail) 2015/05/26 20:24:44 Done. The "?" comment is a reminder to ask what th
3433 Block* param_block =
3434 factory()->NewBlock(nullptr, capacity, is_initializer_block, pos);
3435
3436 static const VariableMode mode = LET;
adamk 2015/05/26 19:58:10 kMode (though I'm not sure this adds much)
caitp (gmail) 2015/05/26 20:24:44 Done.
3437 VariableProxy* proxy =
3438 NewUnresolved(scope->parameter(i)->raw_name(), mode);
3439 VariableDeclaration* declaration = factory()->NewVariableDeclaration(
3440 proxy, mode, scope, RelocInfo::kNoPosition);
3441
3442 bool ok = true;
3443 // All formal parameters have been removed from the scope VariableMap,
3444 // and so Declare() should not be able to fail.
3445 proxy = factory()->NewVariableProxy(Declare(declaration, true, &ok), pos);
3446 DCHECK(ok);
3447
3448 const AstRawString* fn_name = ast_value_factory()->empty_string();
3449 const Runtime::Function* arguments =
3450 Runtime::FunctionForId(Runtime::kInlineArguments);
3451 ZoneList<Expression*>* arguments_i0 =
3452 new (zone()) ZoneList<Expression*>(0, zone());
adamk 2015/05/26 19:58:10 s/0/1/ for the capacity arg here.
caitp (gmail) 2015/05/26 20:24:44 Done.
3453 arguments_i0->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
3454 zone());
3455
3456 if (initializer) {
adamk 2015/05/26 19:58:10 if (initializer != nullptr)
caitp (gmail) 2015/05/26 20:24:44 Done.
3457 // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i);
3458 ZoneList<Expression*>* arguments_i1 =
3459 new (zone()) ZoneList<Expression*>(0, zone());
adamk 2015/05/26 19:58:10 s/0/1/ again.
caitp (gmail) 2015/05/26 20:24:44 Done.
3460 arguments_i1->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
3461 zone());
3462
3463 Expression* arg_or_default = factory()->NewConditional(
3464 // condition:
3465 factory()->NewCompareOperation(
3466 Token::EQ_STRICT,
3467 factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
3468 RelocInfo::kNoPosition),
3469 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3470 RelocInfo::kNoPosition),
3471 // if true:
3472 initializer,
3473 // if false:
3474 factory()->NewCallRuntime(fn_name, arguments, arguments_i1,
3475 RelocInfo::kNoPosition),
3476 RelocInfo::kNoPosition);
3477
3478 Expression* assign = factory()->NewAssignment(
3479 Token::INIT_LET, proxy, arg_or_default, RelocInfo::kNoPosition);
3480
3481 param_block->AddStatement(
3482 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
3483 zone());
3484 proxy->var()->set_initializer_position(initializer->position());
3485 } else {
3486 // let <name> = %_Arguments(i)
3487 Expression* assign = factory()->NewAssignment(
3488 Token::INIT_LET, proxy,
3489 factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
3490 RelocInfo::kNoPosition),
3491 RelocInfo::kNoPosition);
3492 param_block->AddStatement(
3493 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
3494 zone());
3495 proxy->var()->set_initializer_position(pos);
3496 }
3497 body->Add(param_block, zone());
3498 }
3499 return body;
3500 } else {
3501 // If hasParameterExpressions is false, remove the unnecessary parameter
3502 // block scopes.
3503 ZoneList<Scope*>* scopes = scope->inner_scopes();
3504 for (int i = 0; i < scopes->length(); ++i) {
3505 Scope* scope = scopes->at(i);
3506 DCHECK(scope->is_block_scope());
3507 scope->FinalizeBlockScope();
3508 }
3509 return nullptr;
3510 }
3511 }
3512
3513
3401 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3514 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3402 bool* ok) { 3515 bool* ok) {
3403 // ForStatement :: 3516 // ForStatement ::
3404 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 3517 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3405 3518
3406 int stmt_pos = peek_position(); 3519 int stmt_pos = peek_position();
3407 bool is_const = false; 3520 bool is_const = false;
3408 Statement* init = NULL; 3521 Statement* init = NULL;
3409 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3522 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3410 3523
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
3761 const AstRawString* raw_name = expr->AsVariableProxy()->raw_name(); 3874 const AstRawString* raw_name = expr->AsVariableProxy()->raw_name();
3762 Scanner::Location param_location(expr->position(), 3875 Scanner::Location param_location(expr->position(),
3763 expr->position() + raw_name->length()); 3876 expr->position() + raw_name->length());
3764 3877
3765 // When the formal parameter was originally seen, it was parsed as a 3878 // When the formal parameter was originally seen, it was parsed as a
3766 // VariableProxy and recorded as unresolved in the scope. Here we undo that 3879 // VariableProxy and recorded as unresolved in the scope. Here we undo that
3767 // parse-time side-effect. 3880 // parse-time side-effect.
3768 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); 3881 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
3769 3882
3770 bool is_rest = false; 3883 bool is_rest = false;
3771 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest); 3884 int pos = expr->position();
3885 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest, pos);
3772 3886
3773 if (is_duplicate && !duplicate_loc->IsValid()) { 3887 if (is_duplicate && !duplicate_loc->IsValid()) {
3774 *duplicate_loc = param_location; 3888 *duplicate_loc = param_location;
3775 } 3889 }
3776 } 3890 }
3777 3891
3778 3892
3779 void ParserTraits::ParseArrowFunctionFormalParameters( 3893 void ParserTraits::ParseArrowFunctionFormalParameters(
3780 Scope* scope, Expression* params, const Scanner::Location& params_loc, 3894 Scope* scope, Expression* params, const Scanner::Location& params_loc,
3781 bool* is_rest, Scanner::Location* duplicate_loc, bool* ok) { 3895 bool* is_rest, Scanner::Location* duplicate_loc, bool* ok) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3875 // expressions. This also marks the FunctionState as a generator. 3989 // expressions. This also marks the FunctionState as a generator.
3876 Variable* temp = scope_->DeclarationScope()->NewTemporary( 3990 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3877 ast_value_factory()->dot_generator_object_string()); 3991 ast_value_factory()->dot_generator_object_string());
3878 function_state.set_generator_object_variable(temp); 3992 function_state.set_generator_object_variable(temp);
3879 } 3993 }
3880 3994
3881 bool has_rest = false; 3995 bool has_rest = false;
3882 Expect(Token::LPAREN, CHECK_OK); 3996 Expect(Token::LPAREN, CHECK_OK);
3883 int start_position = scanner()->location().beg_pos; 3997 int start_position = scanner()->location().beg_pos;
3884 scope_->set_start_position(start_position); 3998 scope_->set_start_position(start_position);
3885 num_parameters = ParseFormalParameterList(scope, &has_rest, 3999 ZoneList<Expression*>* initializers =
3886 &formals_classifier, CHECK_OK); 4000 new (zone()) ZoneList<Expression*>(0, zone());
4001 bool hasParameterExpressions = false;
4002 num_parameters =
4003 ParseFormalParameterList(scope, initializers, &hasParameterExpressions,
4004 &has_rest, &formals_classifier, CHECK_OK);
3887 Expect(Token::RPAREN, CHECK_OK); 4005 Expect(Token::RPAREN, CHECK_OK);
3888 int formals_end_position = scanner()->location().end_pos; 4006 int formals_end_position = scanner()->location().end_pos;
3889 4007
3890 CheckArityRestrictions(num_parameters, arity_restriction, has_rest, 4008 CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
3891 start_position, formals_end_position, CHECK_OK); 4009 start_position, formals_end_position, CHECK_OK);
3892 4010
3893 Expect(Token::LBRACE, CHECK_OK); 4011 Expect(Token::LBRACE, CHECK_OK);
3894 4012
3895 // If we have a named function expression, we add a local variable 4013 // If we have a named function expression, we add a local variable
3896 // declaration to the body of the function with the name of the 4014 // declaration to the body of the function with the name of the
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3977 is_lazily_parsed = false; 4095 is_lazily_parsed = false;
3978 4096
3979 // This is probably an initialization function. Inform the compiler it 4097 // This is probably an initialization function. Inform the compiler it
3980 // should also eager-compile this function, and that we expect it to be 4098 // should also eager-compile this function, and that we expect it to be
3981 // used once. 4099 // used once.
3982 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 4100 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
3983 should_be_used_once_hint = true; 4101 should_be_used_once_hint = true;
3984 } 4102 }
3985 } 4103 }
3986 if (!is_lazily_parsed) { 4104 if (!is_lazily_parsed) {
3987 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, 4105 body = DesugarInitializeParameters(scope, hasParameterExpressions,
3988 kind, CHECK_OK); 4106 initializers);
4107 if (hasParameterExpressions) {
4108 // TODO(caitp): Function body scope must be a declaration scope
4109 Scope* function_body_scope = NewScope(scope, BLOCK_SCOPE);
4110 function_body_scope->set_start_position(scope->start_position());
4111 function_body_scope->SetScopeName(function_name);
4112 BlockState function_body_state(&scope_, function_body_scope);
4113 ZoneList<Statement*>* inner_body = ParseEagerFunctionBody(
4114 function_name, pos, fvar, fvar_init_op, kind, CHECK_OK);
4115
4116 // Declare Block node
4117 Block* block =
4118 factory()->NewBlock(nullptr, inner_body->length(), false, pos);
4119 block->set_scope(function_body_scope);
4120 for (int i = 0; i < inner_body->length(); ++i) {
4121 block->AddStatement(inner_body->at(i), zone());
4122 }
4123
4124 scope->set_end_position(function_body_scope->end_position());
4125 body->Add(block, zone());
4126 } else {
4127 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
4128 kind, CHECK_OK);
4129 }
3989 materialized_literal_count = function_state.materialized_literal_count(); 4130 materialized_literal_count = function_state.materialized_literal_count();
3990 expected_property_count = function_state.expected_property_count(); 4131 expected_property_count = function_state.expected_property_count();
3991 handler_count = function_state.handler_count(); 4132 handler_count = function_state.handler_count();
3992 4133
3993 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { 4134 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
3994 if (!function_state.super_location().IsValid()) { 4135 if (!function_state.super_location().IsValid()) {
3995 ReportMessageAt(function_name_location, 4136 ReportMessageAt(function_name_location,
3996 MessageTemplate::kStrongSuperCallMissing, 4137 MessageTemplate::kStrongSuperCallMissing,
3997 kReferenceError); 4138 kReferenceError);
3998 *ok = false; 4139 *ok = false;
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
4262 reusable_preparser_->set_allow_harmony_computed_property_names( 4403 reusable_preparser_->set_allow_harmony_computed_property_names(
4263 allow_harmony_computed_property_names()); 4404 allow_harmony_computed_property_names());
4264 reusable_preparser_->set_allow_harmony_rest_params( 4405 reusable_preparser_->set_allow_harmony_rest_params(
4265 allow_harmony_rest_params()); 4406 allow_harmony_rest_params());
4266 reusable_preparser_->set_allow_harmony_spreadcalls( 4407 reusable_preparser_->set_allow_harmony_spreadcalls(
4267 allow_harmony_spreadcalls()); 4408 allow_harmony_spreadcalls());
4268 reusable_preparser_->set_allow_harmony_destructuring( 4409 reusable_preparser_->set_allow_harmony_destructuring(
4269 allow_harmony_destructuring()); 4410 allow_harmony_destructuring());
4270 reusable_preparser_->set_allow_harmony_spread_arrays( 4411 reusable_preparser_->set_allow_harmony_spread_arrays(
4271 allow_harmony_spread_arrays()); 4412 allow_harmony_spread_arrays());
4413 reusable_preparser_->set_allow_harmony_default_parameters(
4414 allow_harmony_default_parameters());
4272 reusable_preparser_->set_allow_strong_mode(allow_strong_mode()); 4415 reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
4273 } 4416 }
4274 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 4417 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4275 language_mode(), function_state_->kind(), logger, bookmark); 4418 language_mode(), function_state_->kind(), logger, bookmark);
4276 if (pre_parse_timer_ != NULL) { 4419 if (pre_parse_timer_ != NULL) {
4277 pre_parse_timer_->Stop(); 4420 pre_parse_timer_->Stop();
4278 } 4421 }
4279 return result; 4422 return result;
4280 } 4423 }
4281 4424
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after
5784 5927
5785 Expression* Parser::SpreadCallNew(Expression* function, 5928 Expression* Parser::SpreadCallNew(Expression* function,
5786 ZoneList<v8::internal::Expression*>* args, 5929 ZoneList<v8::internal::Expression*>* args,
5787 int pos) { 5930 int pos) {
5788 args->InsertAt(0, function, zone()); 5931 args->InsertAt(0, function, zone());
5789 5932
5790 return factory()->NewCallRuntime( 5933 return factory()->NewCallRuntime(
5791 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5934 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5792 } 5935 }
5793 } } // namespace v8::internal 5936 } } // namespace v8::internal
OLDNEW
« src/parser.h ('K') | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698