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

Side by Side Diff: src/parsing/parser.cc

Issue 1537683002: Partial revert of rest parameter desugaring. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix test failures. Created 4 years, 12 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/parsing/parser.h ('k') | src/parsing/parser-base.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/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-visitor.h" 9 #include "src/ast/ast-expression-visitor.h"
10 #include "src/ast/ast-literal-reindexer.h" 10 #include "src/ast/ast-literal-reindexer.h"
(...skipping 4098 matching lines...) Expand 10 before | Expand all | Expand 10 after
4109 expr = right; 4109 expr = right;
4110 } 4110 }
4111 4111
4112 // Only the right-most expression may be a rest parameter. 4112 // Only the right-most expression may be a rest parameter.
4113 DCHECK(!parameters->has_rest); 4113 DCHECK(!parameters->has_rest);
4114 4114
4115 bool is_rest = expr->IsSpread(); 4115 bool is_rest = expr->IsSpread();
4116 if (is_rest) { 4116 if (is_rest) {
4117 expr = expr->AsSpread()->expression(); 4117 expr = expr->AsSpread()->expression();
4118 parameters->has_rest = true; 4118 parameters->has_rest = true;
4119 parameters->rest_array_literal_index =
4120 parser_->function_state_->NextMaterializedLiteralIndex();
4121 ++parameters->materialized_literals_count;
4122 } 4119 }
4123 if (parameters->is_simple) { 4120 if (parameters->is_simple) {
4124 parameters->is_simple = !is_rest && expr->IsVariableProxy(); 4121 parameters->is_simple = !is_rest && expr->IsVariableProxy();
4125 } 4122 }
4126 4123
4127 Expression* initializer = nullptr; 4124 Expression* initializer = nullptr;
4128 if (expr->IsVariableProxy()) { 4125 if (expr->IsVariableProxy()) {
4129 // When the formal parameter was originally seen, it was parsed as a 4126 // When the formal parameter was originally seen, it was parsed as a
4130 // VariableProxy and recorded as unresolved in the scope. Here we undo that 4127 // VariableProxy and recorded as unresolved in the scope. Here we undo that
4131 // parse-time side-effect for parameters that are single-names (not 4128 // parse-time side-effect for parameters that are single-names (not
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
4196 4193
4197 void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) { 4194 void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) {
4198 if (parser_->function_state_->materialized_literal_count() > 0) { 4195 if (parser_->function_state_->materialized_literal_count() > 0) {
4199 AstLiteralReindexer reindexer; 4196 AstLiteralReindexer reindexer;
4200 4197
4201 for (const auto p : parameters.params) { 4198 for (const auto p : parameters.params) {
4202 if (p.pattern != nullptr) reindexer.Reindex(p.pattern); 4199 if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
4203 if (p.initializer != nullptr) reindexer.Reindex(p.initializer); 4200 if (p.initializer != nullptr) reindexer.Reindex(p.initializer);
4204 } 4201 }
4205 4202
4206 if (parameters.has_rest) {
4207 parameters.rest_array_literal_index = reindexer.NextIndex();
4208 }
4209
4210 DCHECK(reindexer.count() <= 4203 DCHECK(reindexer.count() <=
4211 parser_->function_state_->materialized_literal_count()); 4204 parser_->function_state_->materialized_literal_count());
4212 } 4205 }
4213 } 4206 }
4214 4207
4215 4208
4216 FunctionLiteral* Parser::ParseFunctionLiteral( 4209 FunctionLiteral* Parser::ParseFunctionLiteral(
4217 const AstRawString* function_name, Scanner::Location function_name_location, 4210 const AstRawString* function_name, Scanner::Location function_name_location,
4218 FunctionNameValidity function_name_validity, FunctionKind kind, 4211 FunctionNameValidity function_name_validity, FunctionKind kind,
4219 int function_token_pos, FunctionLiteral::FunctionType function_type, 4212 int function_token_pos, FunctionLiteral::FunctionType function_type,
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
4479 4472
4480 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 4473 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4481 function_name, ast_value_factory(), scope, body, 4474 function_name, ast_value_factory(), scope, body,
4482 materialized_literal_count, expected_property_count, arity, 4475 materialized_literal_count, expected_property_count, arity,
4483 duplicate_parameters, function_type, FunctionLiteral::kIsFunction, 4476 duplicate_parameters, function_type, FunctionLiteral::kIsFunction,
4484 eager_compile_hint, kind, pos); 4477 eager_compile_hint, kind, pos);
4485 function_literal->set_function_token_position(function_token_pos); 4478 function_literal->set_function_token_position(function_token_pos);
4486 if (should_be_used_once_hint) 4479 if (should_be_used_once_hint)
4487 function_literal->set_should_be_used_once_hint(); 4480 function_literal->set_should_be_used_once_hint();
4488 4481
4482 if (scope->has_rest_parameter()) {
4483 function_literal->set_dont_optimize_reason(kRestParameter);
4484 }
4485
4489 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 4486 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4490 return function_literal; 4487 return function_literal;
4491 } 4488 }
4492 4489
4493 4490
4494 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, 4491 void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
4495 int* expected_property_count, bool* ok, 4492 int* expected_property_count, bool* ok,
4496 Scanner::BookmarkScope* bookmark) { 4493 Scanner::BookmarkScope* bookmark) {
4497 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); 4494 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
4498 if (produce_cached_parse_data()) CHECK(log_); 4495 if (produce_cached_parse_data()) CHECK(log_);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4628 4625
4629 4626
4630 Block* Parser::BuildParameterInitializationBlock( 4627 Block* Parser::BuildParameterInitializationBlock(
4631 const ParserFormalParameters& parameters, bool* ok) { 4628 const ParserFormalParameters& parameters, bool* ok) {
4632 DCHECK(!parameters.is_simple); 4629 DCHECK(!parameters.is_simple);
4633 DCHECK(scope_->is_function_scope()); 4630 DCHECK(scope_->is_function_scope());
4634 Block* init_block = 4631 Block* init_block =
4635 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); 4632 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
4636 for (int i = 0; i < parameters.params.length(); ++i) { 4633 for (int i = 0; i < parameters.params.length(); ++i) {
4637 auto parameter = parameters.params[i]; 4634 auto parameter = parameters.params[i];
4635 if (parameter.is_rest) break;
4638 DeclarationDescriptor descriptor; 4636 DeclarationDescriptor descriptor;
4639 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; 4637 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
4640 descriptor.parser = this; 4638 descriptor.parser = this;
4641 descriptor.scope = scope_; 4639 descriptor.scope = scope_;
4642 descriptor.hoist_scope = nullptr; 4640 descriptor.hoist_scope = nullptr;
4643 descriptor.mode = LET; 4641 descriptor.mode = LET;
4644 descriptor.needs_init = true; 4642 descriptor.needs_init = true;
4645 descriptor.declaration_pos = parameter.pattern->position(); 4643 descriptor.declaration_pos = parameter.pattern->position();
4646 // The position that will be used by the AssignmentExpression 4644 // The position that will be used by the AssignmentExpression
4647 // which copies from the temp parameter to the pattern. 4645 // which copies from the temp parameter to the pattern.
4648 // 4646 //
4649 // TODO(adamk): Should this be RelocInfo::kNoPosition, since 4647 // TODO(adamk): Should this be RelocInfo::kNoPosition, since
4650 // it's just copying from a temp var to the real param var? 4648 // it's just copying from a temp var to the real param var?
4651 descriptor.initialization_pos = parameter.pattern->position(); 4649 descriptor.initialization_pos = parameter.pattern->position();
4652 // The initializer position which will end up in, 4650 // The initializer position which will end up in,
4653 // Variable::initializer_position(), used for hole check elimination. 4651 // Variable::initializer_position(), used for hole check elimination.
4654 int initializer_position = parameter.pattern->position(); 4652 int initializer_position = parameter.pattern->position();
4655 Expression* initial_value = 4653 Expression* initial_value =
4656 factory()->NewVariableProxy(parameters.scope->parameter(i)); 4654 factory()->NewVariableProxy(parameters.scope->parameter(i));
4657 if (parameter.initializer != nullptr) { 4655 if (parameter.initializer != nullptr) {
4658 // IS_UNDEFINED($param) ? initializer : $param 4656 // IS_UNDEFINED($param) ? initializer : $param
4659 DCHECK(!parameter.is_rest);
4660 4657
4661 // Ensure initializer is rewritten 4658 // Ensure initializer is rewritten
4662 RewriteParameterInitializer(parameter.initializer, scope_); 4659 RewriteParameterInitializer(parameter.initializer, scope_);
4663 4660
4664 auto condition = factory()->NewCompareOperation( 4661 auto condition = factory()->NewCompareOperation(
4665 Token::EQ_STRICT, 4662 Token::EQ_STRICT,
4666 factory()->NewVariableProxy(parameters.scope->parameter(i)), 4663 factory()->NewVariableProxy(parameters.scope->parameter(i)),
4667 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), 4664 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4668 RelocInfo::kNoPosition); 4665 RelocInfo::kNoPosition);
4669 initial_value = factory()->NewConditional( 4666 initial_value = factory()->NewConditional(
4670 condition, parameter.initializer, initial_value, 4667 condition, parameter.initializer, initial_value,
4671 RelocInfo::kNoPosition); 4668 RelocInfo::kNoPosition);
4672 descriptor.initialization_pos = parameter.initializer->position(); 4669 descriptor.initialization_pos = parameter.initializer->position();
4673 initializer_position = parameter.initializer_end_position; 4670 initializer_position = parameter.initializer_end_position;
4674 } else if (parameter.is_rest) {
4675 // $rest = [];
4676 // for (var $argument_index = $rest_index;
4677 // $argument_index < %_ArgumentsLength();
4678 // ++$argument_index) {
4679 // %AppendElement($rest, %_Arguments($argument_index));
4680 // }
4681 // let <param> = $rest;
4682 DCHECK(parameter.pattern->IsVariableProxy());
4683 DCHECK_EQ(i, parameters.params.length() - 1);
4684
4685 Variable* temp_var = parameters.scope->parameter(i);
4686 auto empty_values = new (zone()) ZoneList<Expression*>(0, zone());
4687 auto empty_array = factory()->NewArrayLiteral(
4688 empty_values, parameters.rest_array_literal_index,
4689 is_strong(language_mode()), RelocInfo::kNoPosition);
4690
4691 auto init_array = factory()->NewAssignment(
4692 Token::INIT, factory()->NewVariableProxy(temp_var), empty_array,
4693 RelocInfo::kNoPosition);
4694
4695 auto loop = factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
4696
4697 auto argument_index =
4698 parameters.scope->NewTemporary(ast_value_factory()->empty_string());
4699 auto init = factory()->NewExpressionStatement(
4700 factory()->NewAssignment(
4701 Token::INIT, factory()->NewVariableProxy(argument_index),
4702 factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
4703 RelocInfo::kNoPosition),
4704 RelocInfo::kNoPosition);
4705
4706 auto empty_arguments = new (zone()) ZoneList<Expression*>(0, zone());
4707
4708 // $arguments_index < arguments.length
4709 auto cond = factory()->NewCompareOperation(
4710 Token::LT, factory()->NewVariableProxy(argument_index),
4711 factory()->NewCallRuntime(Runtime::kInlineArgumentsLength,
4712 empty_arguments, RelocInfo::kNoPosition),
4713 RelocInfo::kNoPosition);
4714
4715 // ++argument_index
4716 auto next = factory()->NewExpressionStatement(
4717 factory()->NewCountOperation(
4718 Token::INC, true, factory()->NewVariableProxy(argument_index),
4719 RelocInfo::kNoPosition),
4720 RelocInfo::kNoPosition);
4721
4722 // %_Arguments($arguments_index)
4723 auto arguments_args = new (zone()) ZoneList<Expression*>(1, zone());
4724 arguments_args->Add(factory()->NewVariableProxy(argument_index), zone());
4725
4726 // %AppendElement($rest, %_Arguments($arguments_index))
4727 auto append_element_args = new (zone()) ZoneList<Expression*>(2, zone());
4728
4729 append_element_args->Add(factory()->NewVariableProxy(temp_var), zone());
4730 append_element_args->Add(
4731 factory()->NewCallRuntime(Runtime::kInlineArguments, arguments_args,
4732 RelocInfo::kNoPosition),
4733 zone());
4734
4735 auto body = factory()->NewExpressionStatement(
4736 factory()->NewCallRuntime(Runtime::kAppendElement,
4737 append_element_args,
4738 RelocInfo::kNoPosition),
4739 RelocInfo::kNoPosition);
4740
4741 loop->Initialize(init, cond, next, body);
4742
4743 init_block->statements()->Add(
4744 factory()->NewExpressionStatement(init_array, RelocInfo::kNoPosition),
4745 zone());
4746
4747 init_block->statements()->Add(loop, zone());
4748 } 4671 }
4749 4672
4750 Scope* param_scope = scope_; 4673 Scope* param_scope = scope_;
4751 Block* param_block = init_block; 4674 Block* param_block = init_block;
4752 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) { 4675 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4753 param_scope = NewScope(scope_, BLOCK_SCOPE); 4676 param_scope = NewScope(scope_, BLOCK_SCOPE);
4754 param_scope->set_is_declaration_scope(); 4677 param_scope->set_is_declaration_scope();
4755 param_scope->set_start_position(parameter.pattern->position()); 4678 param_scope->set_start_position(parameter.pattern->position());
4756 param_scope->set_end_position(RelocInfo::kNoPosition); 4679 param_scope->set_end_position(RelocInfo::kNoPosition);
4757 param_scope->RecordEvalCall(); 4680 param_scope->RecordEvalCall();
(...skipping 1836 matching lines...) Expand 10 before | Expand all | Expand 10 after
6594 6517
6595 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { 6518 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
6596 DCHECK(expr->IsRewritableAssignmentExpression()); 6519 DCHECK(expr->IsRewritableAssignmentExpression());
6597 parser_->function_state_->AddDestructuringAssignment( 6520 parser_->function_state_->AddDestructuringAssignment(
6598 Parser::DestructuringAssignment(expr, parser_->scope_)); 6521 Parser::DestructuringAssignment(expr, parser_->scope_));
6599 } 6522 }
6600 6523
6601 6524
6602 } // namespace internal 6525 } // namespace internal
6603 } // namespace v8 6526 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698