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

Side by Side Diff: src/preparser.h

Issue 1272673003: [es6] Re-implement rest parameters via desugaring. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Tiny bit more cleanup Created 5 years, 3 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 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/bailout-reason.h" 8 #include "src/bailout-reason.h"
9 #include "src/expression-classifier.h" 9 #include "src/expression-classifier.h"
10 #include "src/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 13 matching lines...) Expand all
24 kFunctionNameValidityUnknown 24 kFunctionNameValidityUnknown
25 }; 25 };
26 26
27 27
28 struct FormalParametersBase { 28 struct FormalParametersBase {
29 explicit FormalParametersBase(Scope* scope) : scope(scope) {} 29 explicit FormalParametersBase(Scope* scope) : scope(scope) {}
30 Scope* scope; 30 Scope* scope;
31 bool has_rest = false; 31 bool has_rest = false;
32 bool is_simple = true; 32 bool is_simple = true;
33 int materialized_literals_count = 0; 33 int materialized_literals_count = 0;
34 mutable int rest_array_literal_index = -1;
34 }; 35 };
35 36
36 37
37 // Common base class shared between parser and pre-parser. Traits encapsulate 38 // Common base class shared between parser and pre-parser. Traits encapsulate
38 // the differences between Parser and PreParser: 39 // the differences between Parser and PreParser:
39 40
40 // - Return types: For example, Parser functions return Expression* and 41 // - Return types: For example, Parser functions return Expression* and
41 // PreParser functions return PreParserExpression. 42 // PreParser functions return PreParserExpression.
42 43
43 // - Creating parse tree nodes: Parser generates an AST during the recursive 44 // - Creating parse tree nodes: Parser generates an AST during the recursive
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 } 911 }
911 912
912 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 913 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
913 return PreParserExpression(TypeField::encode(kIdentifierExpression) | 914 return PreParserExpression(TypeField::encode(kIdentifierExpression) |
914 IdentifierTypeField::encode(id.type_)); 915 IdentifierTypeField::encode(id.type_));
915 } 916 }
916 917
917 static PreParserExpression BinaryOperation(PreParserExpression left, 918 static PreParserExpression BinaryOperation(PreParserExpression left,
918 Token::Value op, 919 Token::Value op,
919 PreParserExpression right) { 920 PreParserExpression right) {
920 return PreParserExpression(TypeField::encode(kBinaryOperationExpression)); 921 return PreParserExpression(
922 TypeField::encode(kBinaryOperationExpression) |
923 HasRestField::encode(op == Token::COMMA &&
924 right->IsSpreadExpression()));
921 } 925 }
922 926
923 static PreParserExpression StringLiteral() { 927 static PreParserExpression StringLiteral() {
924 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); 928 return PreParserExpression(TypeField::encode(kStringLiteralExpression));
925 } 929 }
926 930
927 static PreParserExpression UseStrictStringLiteral() { 931 static PreParserExpression UseStrictStringLiteral() {
928 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | 932 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
929 IsUseStrictField::encode(true)); 933 IsUseStrictField::encode(true));
930 } 934 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 1031
1028 bool IsNoTemplateTag() const { 1032 bool IsNoTemplateTag() const {
1029 return TypeField::decode(code_) == kExpression && 1033 return TypeField::decode(code_) == kExpression &&
1030 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; 1034 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
1031 } 1035 }
1032 1036
1033 bool IsSpreadExpression() const { 1037 bool IsSpreadExpression() const {
1034 return TypeField::decode(code_) == kSpreadExpression; 1038 return TypeField::decode(code_) == kSpreadExpression;
1035 } 1039 }
1036 1040
1041 bool HasRestParameter() const {
1042 // Preparser's way of determining if an arrow function has a rest parameter.
1043 return IsSpreadExpression() ||
1044 (IsBinaryOperation() && HasRestField::decode(code_));
wingo 2015/08/31 13:07:31 Need more comments about the preconditions, i.e. t
caitp (gmail) 2015/08/31 13:23:40 I'll inline it
caitp (gmail) 2015/08/31 13:28:17 Actually, it can't really be inlined since there's
1045 }
1046
1037 PreParserExpression AsFunctionLiteral() { return *this; } 1047 PreParserExpression AsFunctionLiteral() { return *this; }
1038 1048
1039 bool IsBinaryOperation() const { 1049 bool IsBinaryOperation() const {
1040 return TypeField::decode(code_) == kBinaryOperationExpression; 1050 return TypeField::decode(code_) == kBinaryOperationExpression;
1041 } 1051 }
1042 1052
1043 // Dummy implementation for making expression->somefunc() work in both Parser 1053 // Dummy implementation for making expression->somefunc() work in both Parser
1044 // and PreParser. 1054 // and PreParser.
1045 PreParserExpression* operator->() { return this; } 1055 PreParserExpression* operator->() { return this; }
1046 1056
(...skipping 28 matching lines...) Expand all
1075 // The first three bits are for the Type. 1085 // The first three bits are for the Type.
1076 typedef BitField<Type, 0, 3> TypeField; 1086 typedef BitField<Type, 0, 3> TypeField;
1077 1087
1078 // The rest of the bits are interpreted depending on the value 1088 // The rest of the bits are interpreted depending on the value
1079 // of the Type field, so they can share the storage. 1089 // of the Type field, so they can share the storage.
1080 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; 1090 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
1081 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; 1091 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
1082 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; 1092 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
1083 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> 1093 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
1084 IdentifierTypeField; 1094 IdentifierTypeField;
1095 typedef BitField<bool, TypeField::kNext, 1> HasRestField;
1085 1096
1086 uint32_t code_; 1097 uint32_t code_;
1087 }; 1098 };
1088 1099
1089 1100
1090 // The pre-parser doesn't need to build lists of expressions, identifiers, or 1101 // The pre-parser doesn't need to build lists of expressions, identifiers, or
1091 // the like. 1102 // the like.
1092 template <typename T> 1103 template <typename T>
1093 class PreParserList { 1104 class PreParserList {
1094 public: 1105 public:
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 return pre_parser_->factory()->NewCallNew(function, args, pos); 1858 return pre_parser_->factory()->NewCallNew(function, args, pos);
1848 } 1859 }
1849 1860
1850 1861
1851 void PreParserTraits::ParseArrowFunctionFormalParameterList( 1862 void PreParserTraits::ParseArrowFunctionFormalParameterList(
1852 PreParserFormalParameters* parameters, 1863 PreParserFormalParameters* parameters,
1853 PreParserExpression params, const Scanner::Location& params_loc, 1864 PreParserExpression params, const Scanner::Location& params_loc,
1854 Scanner::Location* duplicate_loc, bool* ok) { 1865 Scanner::Location* duplicate_loc, bool* ok) {
1855 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter 1866 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
1856 // lists that are too long. 1867 // lists that are too long.
1868
1869 // Accomodate array literal for rest parameter.
1870 if (params.HasRestParameter()) {
1871 ++parameters->materialized_literals_count;
1872 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1873 }
1857 } 1874 }
1858 1875
1859 1876
1860 PreParserStatementList PreParser::ParseEagerFunctionBody( 1877 PreParserStatementList PreParser::ParseEagerFunctionBody(
1861 PreParserIdentifier function_name, int pos, 1878 PreParserIdentifier function_name, int pos,
1862 const PreParserFormalParameters& parameters, FunctionKind kind, 1879 const PreParserFormalParameters& parameters, FunctionKind kind,
1863 FunctionLiteral::FunctionType function_type, bool* ok) { 1880 FunctionLiteral::FunctionType function_type, bool* ok) {
1864 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 1881 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1865 1882
1866 ParseStatementList(Token::RBRACE, ok); 1883 ParseStatementList(Token::RBRACE, ok);
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
2385 // AssignmentExpression 2402 // AssignmentExpression
2386 // Expression ',' AssignmentExpression 2403 // Expression ',' AssignmentExpression
2387 2404
2388 ExpressionClassifier binding_classifier; 2405 ExpressionClassifier binding_classifier;
2389 ExpressionT result = 2406 ExpressionT result =
2390 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); 2407 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
2391 classifier->Accumulate(binding_classifier, 2408 classifier->Accumulate(binding_classifier,
2392 ExpressionClassifier::AllProductions); 2409 ExpressionClassifier::AllProductions);
2393 bool is_simple_parameter_list = this->IsIdentifier(result); 2410 bool is_simple_parameter_list = this->IsIdentifier(result);
2394 bool seen_rest = false; 2411 bool seen_rest = false;
2412
2395 while (peek() == Token::COMMA) { 2413 while (peek() == Token::COMMA) {
2396 if (seen_rest) { 2414 if (seen_rest) {
2397 // At this point the production can't possibly be valid, but we don't know 2415 // At this point the production can't possibly be valid, but we don't know
2398 // which error to signal. 2416 // which error to signal.
2399 classifier->RecordArrowFormalParametersError( 2417 classifier->RecordArrowFormalParametersError(
2400 scanner()->peek_location(), MessageTemplate::kParamAfterRest); 2418 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
2401 } 2419 }
2402 Consume(Token::COMMA); 2420 Consume(Token::COMMA);
2421 Token::Value next = peek();
2422 Scanner::Location next_location = scanner()->peek_location();
2403 bool is_rest = false; 2423 bool is_rest = false;
2404 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { 2424 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) {
2405 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only 2425 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
2406 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a 2426 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
2407 // valid expression or binding pattern. 2427 // valid expression or binding pattern.
2408 ExpressionUnexpectedToken(classifier); 2428 ExpressionUnexpectedToken(classifier);
2409 BindingPatternUnexpectedToken(classifier); 2429 BindingPatternUnexpectedToken(classifier);
2410 Consume(Token::ELLIPSIS); 2430 Consume(Token::ELLIPSIS);
2411 seen_rest = is_rest = true; 2431 seen_rest = is_rest = true;
2412 } 2432 }
2413 int pos = position(); 2433 int pos = position();
2414 ExpressionT right = this->ParseAssignmentExpression( 2434 ExpressionT right = this->ParseAssignmentExpression(
2415 accept_IN, &binding_classifier, CHECK_OK); 2435 accept_IN, &binding_classifier, CHECK_OK);
2416 if (is_rest) right = factory()->NewSpread(right, pos); 2436 if (is_rest) {
2437 if (!this->IsIdentifier(right)) {
2438 ReportUnexpectedTokenAt(next_location, next);
2439 *ok = false;
2440 return this->EmptyExpression();
2441 }
2442 right = factory()->NewSpread(right, pos);
2443 }
2444
2417 is_simple_parameter_list = 2445 is_simple_parameter_list =
2418 is_simple_parameter_list && this->IsIdentifier(right); 2446 is_simple_parameter_list && this->IsIdentifier(right);
2419 classifier->Accumulate(binding_classifier, 2447 classifier->Accumulate(binding_classifier,
2420 ExpressionClassifier::AllProductions); 2448 ExpressionClassifier::AllProductions);
2421 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 2449 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2422 } 2450 }
2423 if (!is_simple_parameter_list || seen_rest) { 2451 if (!is_simple_parameter_list || seen_rest) {
2424 classifier->RecordNonSimpleParameter(); 2452 classifier->RecordNonSimpleParameter();
2425 } 2453 }
2426 return result; 2454 return result;
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
2855 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, 2883 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2856 parenthesized_formals, CHECK_OK); 2884 parenthesized_formals, CHECK_OK);
2857 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); 2885 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2858 Scope* scope = 2886 Scope* scope =
2859 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2887 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2860 FormalParametersT parameters(scope); 2888 FormalParametersT parameters(scope);
2861 if (!arrow_formals_classifier.is_simple_parameter_list()) { 2889 if (!arrow_formals_classifier.is_simple_parameter_list()) {
2862 scope->SetHasNonSimpleParameters(); 2890 scope->SetHasNonSimpleParameters();
2863 parameters.is_simple = false; 2891 parameters.is_simple = false;
2864 } 2892 }
2893
2894 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2895 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2896 &duplicate_loc, CHECK_OK);
2897
2865 checkpoint.Restore(&parameters.materialized_literals_count); 2898 checkpoint.Restore(&parameters.materialized_literals_count);
2866 2899
2867 scope->set_start_position(lhs_beg_pos); 2900 scope->set_start_position(lhs_beg_pos);
2868 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2869 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2870 &duplicate_loc, CHECK_OK);
2871 if (duplicate_loc.IsValid()) { 2901 if (duplicate_loc.IsValid()) {
2872 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2902 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2873 duplicate_loc); 2903 duplicate_loc);
2874 } 2904 }
2905
2875 expression = this->ParseArrowFunctionLiteral( 2906 expression = this->ParseArrowFunctionLiteral(
2876 parameters, arrow_formals_classifier, CHECK_OK); 2907 parameters, arrow_formals_classifier, CHECK_OK);
2877 return expression; 2908 return expression;
2878 } 2909 }
2879 2910
2880 // "expression" was not itself an arrow function parameter list, but it might 2911 // "expression" was not itself an arrow function parameter list, but it might
2881 // form part of one. Propagate speculative formal parameter error locations. 2912 // form part of one. Propagate speculative formal parameter error locations.
2882 classifier->Accumulate(arrow_formals_classifier, 2913 classifier->Accumulate(arrow_formals_classifier,
2883 ExpressionClassifier::StandardProductions | 2914 ExpressionClassifier::StandardProductions |
2884 ExpressionClassifier::FormalParametersProductions); 2915 ExpressionClassifier::FormalParametersProductions);
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
3649 default: 3680 default:
3650 return expression; 3681 return expression;
3651 } 3682 }
3652 } 3683 }
3653 DCHECK(false); 3684 DCHECK(false);
3654 return this->EmptyExpression(); 3685 return this->EmptyExpression();
3655 } 3686 }
3656 3687
3657 3688
3658 template <class Traits> 3689 template <class Traits>
3659 void ParserBase<Traits>::ParseFormalParameter( 3690 void ParserBase<Traits>::ParseFormalParameter(FormalParametersT* parameters,
3660 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { 3691 ExpressionClassifier* classifier,
3692 bool* ok) {
3661 // FormalParameter[Yield,GeneratorParameter] : 3693 // FormalParameter[Yield,GeneratorParameter] :
3662 // BindingElement[?Yield, ?GeneratorParameter] 3694 // BindingElement[?Yield, ?GeneratorParameter]
3663 bool is_rest = parameters->has_rest; 3695 bool is_rest = parameters->has_rest;
3664 3696
3665 Token::Value next = peek(); 3697 Token::Value next = peek();
3666 ExpressionT pattern = ParsePrimaryExpression(classifier, ok); 3698 ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
3667 if (!*ok) return; 3699 if (!*ok) return;
3668 3700
3669 ValidateBindingPattern(classifier, ok); 3701 ValidateBindingPattern(classifier, ok);
3670 if (!*ok) return; 3702 if (!*ok) return;
3671 3703
3672 if (!Traits::IsIdentifier(pattern)) { 3704 if (!Traits::IsIdentifier(pattern)) {
3673 if (is_rest || !allow_harmony_destructuring()) { 3705 if (is_rest || !allow_harmony_destructuring()) {
3674 ReportUnexpectedToken(next); 3706 ReportUnexpectedToken(next);
3675 *ok = false; 3707 *ok = false;
3676 return; 3708 return;
3677 } 3709 }
3678 parameters->is_simple = false; 3710 parameters->is_simple = false;
3679 classifier->RecordNonSimpleParameter(); 3711 classifier->RecordNonSimpleParameter();
3680 } 3712 }
3681 3713
3714 if (is_rest) {
3715 parameters->rest_array_literal_index =
3716 function_state_->NextMaterializedLiteralIndex();
3717 ++parameters->materialized_literals_count;
3718 }
3719
3682 ExpressionT initializer = Traits::EmptyExpression(); 3720 ExpressionT initializer = Traits::EmptyExpression();
3683 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { 3721 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
3684 ExpressionClassifier init_classifier; 3722 ExpressionClassifier init_classifier;
3685 initializer = ParseAssignmentExpression(true, &init_classifier, ok); 3723 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3686 if (!*ok) return; 3724 if (!*ok) return;
3687 ValidateExpression(&init_classifier, ok); 3725 ValidateExpression(&init_classifier, ok);
3688 if (!*ok) return; 3726 if (!*ok) return;
3689 parameters->is_simple = false; 3727 parameters->is_simple = false;
3690 classifier->RecordNonSimpleParameter(); 3728 classifier->RecordNonSimpleParameter();
3691 } 3729 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3810 3848
3811 if (peek() == Token::LBRACE) { 3849 if (peek() == Token::LBRACE) {
3812 // Multiple statement body 3850 // Multiple statement body
3813 Consume(Token::LBRACE); 3851 Consume(Token::LBRACE);
3814 bool is_lazily_parsed = 3852 bool is_lazily_parsed =
3815 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); 3853 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
3816 if (is_lazily_parsed) { 3854 if (is_lazily_parsed) {
3817 body = this->NewStatementList(0, zone()); 3855 body = this->NewStatementList(0, zone());
3818 this->SkipLazyFunctionBody(&materialized_literal_count, 3856 this->SkipLazyFunctionBody(&materialized_literal_count,
3819 &expected_property_count, CHECK_OK); 3857 &expected_property_count, CHECK_OK);
3858
3859 if (formal_parameters.materialized_literals_count > 0) {
3860 materialized_literal_count +=
3861 formal_parameters.materialized_literals_count;
3862 }
3820 } else { 3863 } else {
3821 body = this->ParseEagerFunctionBody( 3864 body = this->ParseEagerFunctionBody(
3822 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, 3865 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
3823 kArrowFunction, FunctionLiteral::ANONYMOUS_EXPRESSION, CHECK_OK); 3866 kArrowFunction, FunctionLiteral::ANONYMOUS_EXPRESSION, CHECK_OK);
3824 materialized_literal_count = 3867 materialized_literal_count =
3825 function_state.materialized_literal_count(); 3868 function_state.materialized_literal_count();
3826 expected_property_count = function_state.expected_property_count(); 3869 expected_property_count = function_state.expected_property_count();
3827 } 3870 }
3828 } else { 3871 } else {
3829 // Single-expression body 3872 // Single-expression body
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
4076 *ok = false; 4119 *ok = false;
4077 return; 4120 return;
4078 } 4121 }
4079 has_seen_constructor_ = true; 4122 has_seen_constructor_ = true;
4080 return; 4123 return;
4081 } 4124 }
4082 } 4125 }
4083 } } // v8::internal 4126 } } // v8::internal
4084 4127
4085 #endif // V8_PREPARSER_H 4128 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698