| 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 |