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

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 + add lazy parsing test + WIP review comments 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
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/scopes.cc » ('J')
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 860 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions); 871 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions);
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_default_parameters(FLAG_harmony_default_parameters);
881 set_allow_strong_mode(FLAG_strong_mode); 882 set_allow_strong_mode(FLAG_strong_mode);
882 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 883 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
883 ++feature) { 884 ++feature) {
884 use_counts_[feature] = 0; 885 use_counts_[feature] = 0;
885 } 886 }
886 if (info->ast_value_factory() == NULL) { 887 if (info->ast_value_factory() == NULL) {
887 // info takes ownership of AstValueFactory. 888 // info takes ownership of AstValueFactory.
888 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); 889 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
889 info->set_ast_value_factory_owned(); 890 info->set_ast_value_factory_owned();
890 ast_value_factory_ = info->ast_value_factory(); 891 ast_value_factory_ = info->ast_value_factory();
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 ? FunctionLiteral::ANONYMOUS_EXPRESSION 1135 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1135 : FunctionLiteral::NAMED_EXPRESSION) 1136 : FunctionLiteral::NAMED_EXPRESSION)
1136 : FunctionLiteral::DECLARATION; 1137 : FunctionLiteral::DECLARATION;
1137 bool ok = true; 1138 bool ok = true;
1138 1139
1139 if (shared_info->is_arrow()) { 1140 if (shared_info->is_arrow()) {
1140 Scope* scope = NewScope(scope_, ARROW_SCOPE); 1141 Scope* scope = NewScope(scope_, ARROW_SCOPE);
1141 scope->set_start_position(shared_info->start_position()); 1142 scope->set_start_position(shared_info->start_position());
1142 ExpressionClassifier formals_classifier; 1143 ExpressionClassifier formals_classifier;
1143 bool has_rest = false; 1144 bool has_rest = false;
1145 bool hasParameterExpressions = false;
1146 ZoneList<Expression*>* initializers =
1147 new (zone()) ZoneList<Expression*>(0, zone());
1144 if (Check(Token::LPAREN)) { 1148 if (Check(Token::LPAREN)) {
1145 // '(' StrictFormalParameters ')' 1149 // '(' StrictFormalParameters ')'
1146 ParseFormalParameterList(scope, &has_rest, &formals_classifier, &ok); 1150 ParseFormalParameterList(scope, initializers, &hasParameterExpressions,
1151 &has_rest, &formals_classifier, &ok);
1147 if (ok) ok = Check(Token::RPAREN); 1152 if (ok) ok = Check(Token::RPAREN);
1148 } else { 1153 } else {
1149 // BindingIdentifier 1154 // BindingIdentifier
1150 ParseFormalParameter(scope, has_rest, &formals_classifier, &ok); 1155 ParseFormalParameter(scope, has_rest, &formals_classifier, &ok);
1151 } 1156 }
1152 1157
1153 if (ok) { 1158 if (ok) {
1154 Expression* expression = 1159 Expression* expression =
1155 ParseArrowFunctionLiteral(scope, has_rest, formals_classifier, &ok); 1160 ParseArrowFunctionLiteral(scope, has_rest, formals_classifier, &ok);
1156 if (ok) { 1161 if (ok) {
(...skipping 2232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3389 3394
3390 inner_scope->set_end_position(scanner()->location().end_pos); 3395 inner_scope->set_end_position(scanner()->location().end_pos);
3391 inner_block->set_scope(inner_scope); 3396 inner_block->set_scope(inner_scope);
3392 scope_ = for_scope; 3397 scope_ = for_scope;
3393 3398
3394 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3399 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3395 return outer_block; 3400 return outer_block;
3396 } 3401 }
3397 3402
3398 3403
3404 ZoneList<Statement*>* Parser::DesugarInitializeParameters(
3405 Scope* scope, bool hasParameterExpressions,
3406 ZoneList<Expression*>* initializers) {
3407 DCHECK(scope->is_function_scope());
3408
3409 if (hasParameterExpressions) {
3410 // If hasParameterExpressions for the function is true, each parameter is
3411 // desugared as follows:
3412 //
3413 // SingleNameBinding :
3414 // let <name> = %_Arguments(<index>);
3415 // SingleNameBinding Initializer
3416 // let <name> = IS_UNDEFINED(%_Arguments(<index>)) ? <initializer>
3417 // : %_Arguments(<index>);
3418 //
3419 // TODO(caitp, dslomov): support BindingPatterns & rest parameters
3420 //
3421
3422 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(0, zone());
3423 for (int i = 0; i < initializers->length(); ++i) {
3424 Expression* initializer = initializers->at(i);
3425
3426 // Position of parameter VariableProxy, for hole-checking
3427 int pos = scope->parameter_position(i);
3428
3429 static const int capacity = 1;
3430 static const bool is_initializer_block = true; // ?
3431 Block* param_block =
3432 factory()->NewBlock(nullptr, capacity, is_initializer_block, pos);
3433
3434 Variable* param_var = scope->parameter(i);
3435 param_var->set_mode(LET);
3436
3437 // Lexically declare the initialized variable
3438 static const VariableMode mode = LET;
3439 VariableProxy* proxy = NewUnresolved(param_var->raw_name(), mode);
3440 VariableDeclaration* declaration =
3441 factory()->NewVariableDeclaration(proxy, mode, scope, pos);
3442 scope->AddDeclaration(declaration);
3443 proxy = factory()->NewVariableProxy(param_var);
3444
3445 const AstRawString* fn_name = ast_value_factory()->empty_string();
3446 const Runtime::Function* arguments =
3447 Runtime::FunctionForId(Runtime::kInlineArguments);
3448 ZoneList<Expression*>* arguments_i0 =
3449 new (zone()) ZoneList<Expression*>(0, zone());
3450 arguments_i0->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
3451 zone());
3452
3453 if (initializer) {
3454 // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i);
3455 ZoneList<Expression*>* arguments_i1 =
3456 new (zone()) ZoneList<Expression*>(0, zone());
3457 arguments_i1->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
3458 zone());
3459
3460 Expression* arg_or_default = factory()->NewConditional(
3461 // condition:
3462 factory()->NewCompareOperation(
3463 Token::EQ_STRICT,
3464 factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
3465 RelocInfo::kNoPosition),
3466 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3467 RelocInfo::kNoPosition),
3468 // if true:
3469 initializer,
3470 // if false:
3471 factory()->NewCallRuntime(fn_name, arguments, arguments_i1,
3472 RelocInfo::kNoPosition),
3473 RelocInfo::kNoPosition);
3474
3475 Expression* assign = factory()->NewAssignment(
3476 Token::INIT_LET, proxy, arg_or_default, RelocInfo::kNoPosition);
3477
3478 param_block->AddStatement(
3479 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
3480 zone());
3481 proxy->var()->set_initializer_position(initializer->position());
3482 } else {
3483 // let <name> = %_Arguments(i)
3484 Expression* assign = factory()->NewAssignment(
3485 Token::INIT_LET, proxy,
3486 factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
3487 RelocInfo::kNoPosition),
3488 RelocInfo::kNoPosition);
3489 param_block->AddStatement(
3490 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
3491 zone());
3492 proxy->var()->set_initializer_position(pos);
3493 }
3494 body->Add(param_block, zone());
3495 }
3496 return body;
3497 } else {
3498 // If hasParameterExpressions is false, remove the unnecessary parameter
3499 // block scopes.
3500 ZoneList<Scope*>* scopes = scope->inner_scopes();
3501 for (int i = 0; i < scopes->length(); ++i) {
3502 Scope* scope = scopes->at(i);
3503 DCHECK(scope->is_block_scope());
3504 scope->FinalizeBlockScope();
3505 }
3506 return nullptr;
3507 }
3508 }
3509
3510
3399 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3511 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3400 bool* ok) { 3512 bool* ok) {
3401 // ForStatement :: 3513 // ForStatement ::
3402 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 3514 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3403 3515
3404 int stmt_pos = peek_position(); 3516 int stmt_pos = peek_position();
3405 bool is_const = false; 3517 bool is_const = false;
3406 Statement* init = NULL; 3518 Statement* init = NULL;
3407 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3519 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3408 3520
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
3782 const AstRawString* raw_name = expr->AsVariableProxy()->raw_name(); 3894 const AstRawString* raw_name = expr->AsVariableProxy()->raw_name();
3783 Scanner::Location param_location(expr->position(), 3895 Scanner::Location param_location(expr->position(),
3784 expr->position() + raw_name->length()); 3896 expr->position() + raw_name->length());
3785 3897
3786 // When the formal parameter was originally seen, it was parsed as a 3898 // When the formal parameter was originally seen, it was parsed as a
3787 // VariableProxy and recorded as unresolved in the scope. Here we undo that 3899 // VariableProxy and recorded as unresolved in the scope. Here we undo that
3788 // parse-time side-effect. 3900 // parse-time side-effect.
3789 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); 3901 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
3790 3902
3791 bool is_rest = false; 3903 bool is_rest = false;
3792 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest); 3904 int pos = expr->position();
3905 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest, pos);
3793 3906
3794 if (is_duplicate && !duplicate_loc->IsValid()) { 3907 if (is_duplicate && !duplicate_loc->IsValid()) {
3795 *duplicate_loc = param_location; 3908 *duplicate_loc = param_location;
3796 } 3909 }
3797 } 3910 }
3798 3911
3799 3912
3800 void ParserTraits::ParseArrowFunctionFormalParameters( 3913 void ParserTraits::ParseArrowFunctionFormalParameters(
3801 Scope* scope, Expression* params, const Scanner::Location& params_loc, 3914 Scope* scope, Expression* params, const Scanner::Location& params_loc,
3802 bool* is_rest, Scanner::Location* duplicate_loc, bool* ok) { 3915 bool* is_rest, Scanner::Location* duplicate_loc, bool* ok) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3896 // expressions. This also marks the FunctionState as a generator. 4009 // expressions. This also marks the FunctionState as a generator.
3897 Variable* temp = scope_->DeclarationScope()->NewTemporary( 4010 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3898 ast_value_factory()->dot_generator_object_string()); 4011 ast_value_factory()->dot_generator_object_string());
3899 function_state.set_generator_object_variable(temp); 4012 function_state.set_generator_object_variable(temp);
3900 } 4013 }
3901 4014
3902 bool has_rest = false; 4015 bool has_rest = false;
3903 Expect(Token::LPAREN, CHECK_OK); 4016 Expect(Token::LPAREN, CHECK_OK);
3904 int start_position = scanner()->location().beg_pos; 4017 int start_position = scanner()->location().beg_pos;
3905 scope_->set_start_position(start_position); 4018 scope_->set_start_position(start_position);
3906 num_parameters = ParseFormalParameterList(scope, &has_rest, 4019 ZoneList<Expression*>* initializers =
3907 &formals_classifier, CHECK_OK); 4020 new (zone()) ZoneList<Expression*>(0, zone());
4021 bool hasParameterExpressions = false;
4022 num_parameters =
4023 ParseFormalParameterList(scope, initializers, &hasParameterExpressions,
4024 &has_rest, &formals_classifier, CHECK_OK);
3908 Expect(Token::RPAREN, CHECK_OK); 4025 Expect(Token::RPAREN, CHECK_OK);
3909 int formals_end_position = scanner()->location().end_pos; 4026 int formals_end_position = scanner()->location().end_pos;
3910 4027
3911 CheckArityRestrictions(num_parameters, arity_restriction, has_rest, 4028 CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
3912 start_position, formals_end_position, CHECK_OK); 4029 start_position, formals_end_position, CHECK_OK);
3913 4030
3914 Expect(Token::LBRACE, CHECK_OK); 4031 Expect(Token::LBRACE, CHECK_OK);
3915 4032
3916 // If we have a named function expression, we add a local variable 4033 // If we have a named function expression, we add a local variable
3917 // declaration to the body of the function with the name of the 4034 // declaration to the body of the function with the name of the
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3998 is_lazily_parsed = false; 4115 is_lazily_parsed = false;
3999 4116
4000 // This is probably an initialization function. Inform the compiler it 4117 // This is probably an initialization function. Inform the compiler it
4001 // should also eager-compile this function, and that we expect it to be 4118 // should also eager-compile this function, and that we expect it to be
4002 // used once. 4119 // used once.
4003 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 4120 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4004 should_be_used_once_hint = true; 4121 should_be_used_once_hint = true;
4005 } 4122 }
4006 } 4123 }
4007 if (!is_lazily_parsed) { 4124 if (!is_lazily_parsed) {
4008 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, 4125 body = DesugarInitializeParameters(scope, hasParameterExpressions,
4009 kind, CHECK_OK); 4126 initializers);
4127 if (hasParameterExpressions) {
4128 // TODO(caitp): Function body scope must be a declaration scope
4129 Scope* function_body_scope = NewScope(scope, BLOCK_SCOPE);
4130 function_body_scope->set_start_position(scope->start_position());
4131 function_body_scope->SetScopeName(function_name);
4132 BlockState function_body_state(&scope_, function_body_scope);
4133 ZoneList<Statement*>* inner_body = ParseEagerFunctionBody(
4134 function_name, pos, fvar, fvar_init_op, kind, CHECK_OK);
4135
4136 // Declare Block node
4137 Block* block =
4138 factory()->NewBlock(nullptr, inner_body->length(), false, pos);
4139 block->set_scope(function_body_scope);
4140 for (int i = 0; i < inner_body->length(); ++i) {
4141 block->AddStatement(inner_body->at(i), zone());
4142 }
4143
4144 scope->set_end_position(function_body_scope->end_position());
4145 body->Add(block, zone());
4146 } else {
4147 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
4148 kind, CHECK_OK);
4149 }
4010 materialized_literal_count = function_state.materialized_literal_count(); 4150 materialized_literal_count = function_state.materialized_literal_count();
4011 expected_property_count = function_state.expected_property_count(); 4151 expected_property_count = function_state.expected_property_count();
4012 handler_count = function_state.handler_count(); 4152 handler_count = function_state.handler_count();
4013 4153
4014 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { 4154 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
4015 if (!function_state.super_location().IsValid()) { 4155 if (!function_state.super_location().IsValid()) {
4016 ReportMessageAt(function_name_location, 4156 ReportMessageAt(function_name_location,
4017 MessageTemplate::kStrongSuperCallMissing, 4157 MessageTemplate::kStrongSuperCallMissing,
4018 kReferenceError); 4158 kReferenceError);
4019 *ok = false; 4159 *ok = false;
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
4281 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy()); 4421 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy());
4282 reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode()); 4422 reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode());
4283 reusable_preparser_->set_allow_harmony_computed_property_names( 4423 reusable_preparser_->set_allow_harmony_computed_property_names(
4284 allow_harmony_computed_property_names()); 4424 allow_harmony_computed_property_names());
4285 reusable_preparser_->set_allow_harmony_rest_params( 4425 reusable_preparser_->set_allow_harmony_rest_params(
4286 allow_harmony_rest_params()); 4426 allow_harmony_rest_params());
4287 reusable_preparser_->set_allow_harmony_spreadcalls( 4427 reusable_preparser_->set_allow_harmony_spreadcalls(
4288 allow_harmony_spreadcalls()); 4428 allow_harmony_spreadcalls());
4289 reusable_preparser_->set_allow_harmony_destructuring( 4429 reusable_preparser_->set_allow_harmony_destructuring(
4290 allow_harmony_destructuring()); 4430 allow_harmony_destructuring());
4431 reusable_preparser_->set_allow_harmony_default_parameters(
4432 allow_harmony_default_parameters());
4291 reusable_preparser_->set_allow_strong_mode(allow_strong_mode()); 4433 reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
4292 } 4434 }
4293 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 4435 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4294 language_mode(), function_state_->kind(), logger, bookmark); 4436 language_mode(), function_state_->kind(), logger, bookmark);
4295 if (pre_parse_timer_ != NULL) { 4437 if (pre_parse_timer_ != NULL) {
4296 pre_parse_timer_->Stop(); 4438 pre_parse_timer_->Stop();
4297 } 4439 }
4298 return result; 4440 return result;
4299 } 4441 }
4300 4442
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after
5803 5945
5804 Expression* Parser::SpreadCallNew(Expression* function, 5946 Expression* Parser::SpreadCallNew(Expression* function,
5805 ZoneList<v8::internal::Expression*>* args, 5947 ZoneList<v8::internal::Expression*>* args,
5806 int pos) { 5948 int pos) {
5807 args->InsertAt(0, function, zone()); 5949 args->InsertAt(0, function, zone());
5808 5950
5809 return factory()->NewCallRuntime( 5951 return factory()->NewCallRuntime(
5810 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5952 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5811 } 5953 }
5812 } } // namespace v8::internal 5954 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/scopes.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698