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/preparser.h

Issue 1272673003: [es6] Re-implement rest parameters via desugaring. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Oops. 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 890 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 } 935 }
935 936
936 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 937 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
937 return PreParserExpression(TypeField::encode(kIdentifierExpression) | 938 return PreParserExpression(TypeField::encode(kIdentifierExpression) |
938 IdentifierTypeField::encode(id.type_)); 939 IdentifierTypeField::encode(id.type_));
939 } 940 }
940 941
941 static PreParserExpression BinaryOperation(PreParserExpression left, 942 static PreParserExpression BinaryOperation(PreParserExpression left,
942 Token::Value op, 943 Token::Value op,
943 PreParserExpression right) { 944 PreParserExpression right) {
944 return PreParserExpression(TypeField::encode(kBinaryOperationExpression)); 945 return PreParserExpression(
946 TypeField::encode(kBinaryOperationExpression) |
947 HasRestField::encode(op == Token::COMMA &&
948 right->IsSpreadExpression()));
945 } 949 }
946 950
947 static PreParserExpression StringLiteral() { 951 static PreParserExpression StringLiteral() {
948 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); 952 return PreParserExpression(TypeField::encode(kStringLiteralExpression));
949 } 953 }
950 954
951 static PreParserExpression UseStrictStringLiteral() { 955 static PreParserExpression UseStrictStringLiteral() {
952 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | 956 return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
953 IsUseStrictField::encode(true)); 957 IsUseStrictField::encode(true));
954 } 958 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 1055
1052 bool IsNoTemplateTag() const { 1056 bool IsNoTemplateTag() const {
1053 return TypeField::decode(code_) == kExpression && 1057 return TypeField::decode(code_) == kExpression &&
1054 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; 1058 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
1055 } 1059 }
1056 1060
1057 bool IsSpreadExpression() const { 1061 bool IsSpreadExpression() const {
1058 return TypeField::decode(code_) == kSpreadExpression; 1062 return TypeField::decode(code_) == kSpreadExpression;
1059 } 1063 }
1060 1064
1065 bool IsArrowFunctionFormalParametersWithRestParameter() const {
1066 // Iff the expression classifier has determined that this expression is a
1067 // valid arrow fformal parameter list, return true if the formal parameter
1068 // list ends with a rest parameter.
1069 return IsSpreadExpression() ||
1070 (IsBinaryOperation() && HasRestField::decode(code_));
1071 }
1072
1061 PreParserExpression AsFunctionLiteral() { return *this; } 1073 PreParserExpression AsFunctionLiteral() { return *this; }
1062 1074
1063 bool IsBinaryOperation() const { 1075 bool IsBinaryOperation() const {
1064 return TypeField::decode(code_) == kBinaryOperationExpression; 1076 return TypeField::decode(code_) == kBinaryOperationExpression;
1065 } 1077 }
1066 1078
1067 // Dummy implementation for making expression->somefunc() work in both Parser 1079 // Dummy implementation for making expression->somefunc() work in both Parser
1068 // and PreParser. 1080 // and PreParser.
1069 PreParserExpression* operator->() { return this; } 1081 PreParserExpression* operator->() { return this; }
1070 1082
(...skipping 28 matching lines...) Expand all
1099 // The first three bits are for the Type. 1111 // The first three bits are for the Type.
1100 typedef BitField<Type, 0, 3> TypeField; 1112 typedef BitField<Type, 0, 3> TypeField;
1101 1113
1102 // The rest of the bits are interpreted depending on the value 1114 // The rest of the bits are interpreted depending on the value
1103 // of the Type field, so they can share the storage. 1115 // of the Type field, so they can share the storage.
1104 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; 1116 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
1105 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; 1117 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
1106 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; 1118 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
1107 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> 1119 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
1108 IdentifierTypeField; 1120 IdentifierTypeField;
1121 typedef BitField<bool, TypeField::kNext, 1> HasRestField;
1109 1122
1110 uint32_t code_; 1123 uint32_t code_;
1111 }; 1124 };
1112 1125
1113 1126
1114 // The pre-parser doesn't need to build lists of expressions, identifiers, or 1127 // The pre-parser doesn't need to build lists of expressions, identifiers, or
1115 // the like. 1128 // the like.
1116 template <typename T> 1129 template <typename T>
1117 class PreParserList { 1130 class PreParserList {
1118 public: 1131 public:
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 return pre_parser_->factory()->NewCallNew(function, args, pos); 1884 return pre_parser_->factory()->NewCallNew(function, args, pos);
1872 } 1885 }
1873 1886
1874 1887
1875 void PreParserTraits::ParseArrowFunctionFormalParameterList( 1888 void PreParserTraits::ParseArrowFunctionFormalParameterList(
1876 PreParserFormalParameters* parameters, 1889 PreParserFormalParameters* parameters,
1877 PreParserExpression params, const Scanner::Location& params_loc, 1890 PreParserExpression params, const Scanner::Location& params_loc,
1878 Scanner::Location* duplicate_loc, bool* ok) { 1891 Scanner::Location* duplicate_loc, bool* ok) {
1879 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter 1892 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
1880 // lists that are too long. 1893 // lists that are too long.
1894
1895 // Accomodate array literal for rest parameter.
1896 if (params.IsArrowFunctionFormalParametersWithRestParameter()) {
1897 ++parameters->materialized_literals_count;
1898 pre_parser_->function_state_->NextMaterializedLiteralIndex();
1899 }
1881 } 1900 }
1882 1901
1883 1902
1884 PreParserStatementList PreParser::ParseEagerFunctionBody( 1903 PreParserStatementList PreParser::ParseEagerFunctionBody(
1885 PreParserIdentifier function_name, int pos, 1904 PreParserIdentifier function_name, int pos,
1886 const PreParserFormalParameters& parameters, FunctionKind kind, 1905 const PreParserFormalParameters& parameters, FunctionKind kind,
1887 FunctionLiteral::FunctionType function_type, bool* ok) { 1906 FunctionLiteral::FunctionType function_type, bool* ok) {
1888 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 1907 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1889 1908
1890 ParseStatementList(Token::RBRACE, ok); 1909 ParseStatementList(Token::RBRACE, ok);
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after
2879 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, 2898 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2880 parenthesized_formals, CHECK_OK); 2899 parenthesized_formals, CHECK_OK);
2881 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); 2900 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2882 Scope* scope = 2901 Scope* scope =
2883 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2902 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2884 FormalParametersT parameters(scope); 2903 FormalParametersT parameters(scope);
2885 if (!arrow_formals_classifier.is_simple_parameter_list()) { 2904 if (!arrow_formals_classifier.is_simple_parameter_list()) {
2886 scope->SetHasNonSimpleParameters(); 2905 scope->SetHasNonSimpleParameters();
2887 parameters.is_simple = false; 2906 parameters.is_simple = false;
2888 } 2907 }
2908
2909 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2910 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2911 &duplicate_loc, CHECK_OK);
2912
2889 checkpoint.Restore(&parameters.materialized_literals_count); 2913 checkpoint.Restore(&parameters.materialized_literals_count);
2890 2914
2891 scope->set_start_position(lhs_beg_pos); 2915 scope->set_start_position(lhs_beg_pos);
2892 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2893 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2894 &duplicate_loc, CHECK_OK);
2895 if (duplicate_loc.IsValid()) { 2916 if (duplicate_loc.IsValid()) {
2896 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2917 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2897 duplicate_loc); 2918 duplicate_loc);
2898 } 2919 }
2899 expression = this->ParseArrowFunctionLiteral( 2920 expression = this->ParseArrowFunctionLiteral(
2900 parameters, arrow_formals_classifier, CHECK_OK); 2921 parameters, arrow_formals_classifier, CHECK_OK);
2901 return expression; 2922 return expression;
2902 } 2923 }
2903 2924
2904 // "expression" was not itself an arrow function parameter list, but it might 2925 // "expression" was not itself an arrow function parameter list, but it might
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
3699 ReportUnexpectedToken(next); 3720 ReportUnexpectedToken(next);
3700 *ok = false; 3721 *ok = false;
3701 return; 3722 return;
3702 } 3723 }
3703 parameters->is_simple = false; 3724 parameters->is_simple = false;
3704 ValidateFormalParameterInitializer(classifier, ok); 3725 ValidateFormalParameterInitializer(classifier, ok);
3705 if (!*ok) return; 3726 if (!*ok) return;
3706 classifier->RecordNonSimpleParameter(); 3727 classifier->RecordNonSimpleParameter();
3707 } 3728 }
3708 3729
3730 if (is_rest) {
3731 parameters->rest_array_literal_index =
3732 function_state_->NextMaterializedLiteralIndex();
3733 ++parameters->materialized_literals_count;
3734 }
3735
3709 ExpressionT initializer = Traits::EmptyExpression(); 3736 ExpressionT initializer = Traits::EmptyExpression();
3710 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { 3737 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
3711 ExpressionClassifier init_classifier; 3738 ExpressionClassifier init_classifier;
3712 initializer = ParseAssignmentExpression(true, &init_classifier, ok); 3739 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3713 if (!*ok) return; 3740 if (!*ok) return;
3714 ValidateExpression(&init_classifier, ok); 3741 ValidateExpression(&init_classifier, ok);
3715 ValidateFormalParameterInitializer(&init_classifier, ok); 3742 ValidateFormalParameterInitializer(&init_classifier, ok);
3716 if (!*ok) return; 3743 if (!*ok) return;
3717 parameters->is_simple = false; 3744 parameters->is_simple = false;
3718 classifier->RecordNonSimpleParameter(); 3745 classifier->RecordNonSimpleParameter();
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3859 3886
3860 if (peek() == Token::LBRACE) { 3887 if (peek() == Token::LBRACE) {
3861 // Multiple statement body 3888 // Multiple statement body
3862 Consume(Token::LBRACE); 3889 Consume(Token::LBRACE);
3863 bool is_lazily_parsed = 3890 bool is_lazily_parsed =
3864 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); 3891 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
3865 if (is_lazily_parsed) { 3892 if (is_lazily_parsed) {
3866 body = this->NewStatementList(0, zone()); 3893 body = this->NewStatementList(0, zone());
3867 this->SkipLazyFunctionBody(&materialized_literal_count, 3894 this->SkipLazyFunctionBody(&materialized_literal_count,
3868 &expected_property_count, CHECK_OK); 3895 &expected_property_count, CHECK_OK);
3896
3897 if (formal_parameters.materialized_literals_count > 0) {
3898 materialized_literal_count +=
3899 formal_parameters.materialized_literals_count;
3900 }
3869 } else { 3901 } else {
3870 body = this->ParseEagerFunctionBody( 3902 body = this->ParseEagerFunctionBody(
3871 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, 3903 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
3872 kArrowFunction, FunctionLiteral::ANONYMOUS_EXPRESSION, CHECK_OK); 3904 kArrowFunction, FunctionLiteral::ANONYMOUS_EXPRESSION, CHECK_OK);
3873 materialized_literal_count = 3905 materialized_literal_count =
3874 function_state.materialized_literal_count(); 3906 function_state.materialized_literal_count();
3875 expected_property_count = function_state.expected_property_count(); 3907 expected_property_count = function_state.expected_property_count();
3876 } 3908 }
3877 } else { 3909 } else {
3878 // Single-expression body 3910 // Single-expression body
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
4125 *ok = false; 4157 *ok = false;
4126 return; 4158 return;
4127 } 4159 }
4128 has_seen_constructor_ = true; 4160 has_seen_constructor_ = true;
4129 return; 4161 return;
4130 } 4162 }
4131 } 4163 }
4132 } } // v8::internal 4164 } } // v8::internal
4133 4165
4134 #endif // V8_PREPARSER_H 4166 #endif // V8_PREPARSER_H
OLDNEW
« src/parser.h ('K') | « src/parser.cc ('k') | src/runtime/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698