OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(¶meters, expression, loc, |
| 2911 &duplicate_loc, CHECK_OK); |
| 2912 |
2889 checkpoint.Restore(¶meters.materialized_literals_count); | 2913 checkpoint.Restore(¶meters.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(¶meters, 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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |