| 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_PARSING_PREPARSER_H | 5 #ifndef V8_PARSING_PREPARSER_H |
| 6 #define V8_PARSING_PREPARSER_H | 6 #define V8_PARSING_PREPARSER_H |
| 7 | 7 |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
| 11 #include "src/messages.h" | 11 #include "src/messages.h" |
| 12 #include "src/parsing/expression-classifier.h" | 12 #include "src/parsing/expression-classifier.h" |
| 13 #include "src/parsing/func-name-inferrer.h" | 13 #include "src/parsing/func-name-inferrer.h" |
| 14 #include "src/parsing/parser-base.h" | 14 #include "src/parsing/parser-base.h" |
| 15 #include "src/parsing/scanner.h" | 15 #include "src/parsing/scanner.h" |
| 16 #include "src/parsing/token.h" | 16 #include "src/parsing/token.h" |
| 17 | 17 |
| 18 namespace v8 { | 18 namespace v8 { |
| 19 namespace internal { | 19 namespace internal { |
| 20 | 20 |
| 21 | |
| 22 class PreParserIdentifier { | 21 class PreParserIdentifier { |
| 23 public: | 22 public: |
| 24 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 23 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
| 25 static PreParserIdentifier Default() { | 24 static PreParserIdentifier Default() { |
| 26 return PreParserIdentifier(kUnknownIdentifier); | 25 return PreParserIdentifier(kUnknownIdentifier); |
| 27 } | 26 } |
| 28 static PreParserIdentifier Eval() { | 27 static PreParserIdentifier Eval() { |
| 29 return PreParserIdentifier(kEvalIdentifier); | 28 return PreParserIdentifier(kEvalIdentifier); |
| 30 } | 29 } |
| 31 static PreParserIdentifier Arguments() { | 30 static PreParserIdentifier Arguments() { |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 int Arity() const { return arity; } | 580 int Arity() const { return arity; } |
| 582 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy | 581 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy |
| 583 }; | 582 }; |
| 584 | 583 |
| 585 | 584 |
| 586 class PreParser; | 585 class PreParser; |
| 587 | 586 |
| 588 template <> | 587 template <> |
| 589 class ParserBaseTraits<PreParser> { | 588 class ParserBaseTraits<PreParser> { |
| 590 public: | 589 public: |
| 591 typedef ParserBaseTraits<PreParser> PreParserTraits; | 590 struct Type { |
| 591 typedef ParserBase<PreParser> Base; |
| 592 typedef PreParser Impl; |
| 592 | 593 |
| 593 struct Type { | |
| 594 // PreParser doesn't need to store generator variables. | 594 // PreParser doesn't need to store generator variables. |
| 595 typedef void GeneratorVariable; | 595 typedef void GeneratorVariable; |
| 596 | 596 |
| 597 typedef int AstProperties; | 597 typedef int AstProperties; |
| 598 | 598 |
| 599 typedef v8::internal::ExpressionClassifier<PreParserTraits> | 599 typedef v8::internal::ExpressionClassifier<ParserBaseTraits<PreParser>> |
| 600 ExpressionClassifier; | 600 ExpressionClassifier; |
| 601 | 601 |
| 602 // Return types for traversing functions. | 602 // Return types for traversing functions. |
| 603 typedef PreParserIdentifier Identifier; | 603 typedef PreParserIdentifier Identifier; |
| 604 typedef PreParserExpression Expression; | 604 typedef PreParserExpression Expression; |
| 605 typedef PreParserExpression YieldExpression; | 605 typedef PreParserExpression YieldExpression; |
| 606 typedef PreParserExpression FunctionLiteral; | 606 typedef PreParserExpression FunctionLiteral; |
| 607 typedef PreParserExpression ClassLiteral; | 607 typedef PreParserExpression ClassLiteral; |
| 608 typedef PreParserExpression Literal; | 608 typedef PreParserExpression Literal; |
| 609 typedef PreParserExpression ObjectLiteralProperty; | 609 typedef PreParserExpression ObjectLiteralProperty; |
| 610 typedef PreParserExpressionList ExpressionList; | 610 typedef PreParserExpressionList ExpressionList; |
| 611 typedef PreParserExpressionList PropertyList; | 611 typedef PreParserExpressionList PropertyList; |
| 612 typedef PreParserIdentifier FormalParameter; | 612 typedef PreParserIdentifier FormalParameter; |
| 613 typedef PreParserFormalParameters FormalParameters; | 613 typedef PreParserFormalParameters FormalParameters; |
| 614 typedef PreParserStatementList StatementList; | 614 typedef PreParserStatementList StatementList; |
| 615 | 615 |
| 616 // For constructing objects returned by the traversing functions. | 616 // For constructing objects returned by the traversing functions. |
| 617 typedef PreParserFactory Factory; | 617 typedef PreParserFactory Factory; |
| 618 }; | 618 }; |
| 619 | |
| 620 // TODO(nikolaos): The traits methods should not need to call methods | |
| 621 // of the implementation object. | |
| 622 PreParser* delegate() { return reinterpret_cast<PreParser*>(this); } | |
| 623 const PreParser* delegate() const { | |
| 624 return reinterpret_cast<const PreParser*>(this); | |
| 625 } | |
| 626 | |
| 627 // A dummy function, just useful as an argument to CHECK_OK_CUSTOM. | |
| 628 static void Void() {} | |
| 629 | |
| 630 void AddParameterInitializationBlock( | |
| 631 const PreParserFormalParameters& parameters, PreParserStatementList body, | |
| 632 bool is_async, bool* ok) {} | |
| 633 | |
| 634 void AddFormalParameter(PreParserFormalParameters* parameters, | |
| 635 PreParserExpression pattern, | |
| 636 PreParserExpression initializer, | |
| 637 int initializer_end_position, bool is_rest) { | |
| 638 ++parameters->arity; | |
| 639 } | |
| 640 | |
| 641 void DeclareFormalParameter(DeclarationScope* scope, | |
| 642 PreParserIdentifier parameter, | |
| 643 Type::ExpressionClassifier* classifier) { | |
| 644 if (!classifier->is_simple_parameter_list()) { | |
| 645 scope->SetHasNonSimpleParameters(); | |
| 646 } | |
| 647 } | |
| 648 | |
| 649 V8_INLINE void ParseArrowFunctionFormalParameterList( | |
| 650 PreParserFormalParameters* parameters, PreParserExpression params, | |
| 651 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, | |
| 652 const Scope::Snapshot& scope_snapshot, bool* ok); | |
| 653 | |
| 654 void ReindexLiterals(const PreParserFormalParameters& parameters) {} | |
| 655 | |
| 656 V8_INLINE PreParserExpression NoTemplateTag() { | |
| 657 return PreParserExpression::NoTemplateTag(); | |
| 658 } | |
| 659 V8_INLINE static bool IsTaggedTemplate(const PreParserExpression tag) { | |
| 660 return !tag.IsNoTemplateTag(); | |
| 661 } | |
| 662 | |
| 663 inline void MaterializeUnspreadArgumentsLiterals(int count); | |
| 664 | |
| 665 inline PreParserExpression ExpressionListToExpression( | |
| 666 PreParserExpressionList args) { | |
| 667 return PreParserExpression::Default(); | |
| 668 } | |
| 669 | |
| 670 void SetFunctionNameFromPropertyName(PreParserExpression property, | |
| 671 PreParserIdentifier name) {} | |
| 672 void SetFunctionNameFromIdentifierRef(PreParserExpression value, | |
| 673 PreParserExpression identifier) {} | |
| 674 | |
| 675 V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>* | |
| 676 GetReportedErrorList() const; | |
| 677 V8_INLINE Zone* zone() const; | |
| 678 V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const; | |
| 679 }; | 619 }; |
| 680 | 620 |
| 681 | 621 |
| 682 // Preparsing checks a JavaScript program and emits preparse-data that helps | 622 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 683 // a later parsing to be faster. | 623 // a later parsing to be faster. |
| 684 // See preparse-data-format.h for the data format. | 624 // See preparse-data-format.h for the data format. |
| 685 | 625 |
| 686 // The PreParser checks that the syntax follows the grammar for JavaScript, | 626 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| 687 // and collects some information about the program along the way. | 627 // and collects some information about the program along the way. |
| 688 // The grammar check is only performed in order to understand the program | 628 // The grammar check is only performed in order to understand the program |
| 689 // sufficiently to deduce some information about it, that can be used | 629 // sufficiently to deduce some information about it, that can be used |
| 690 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 630 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
| 691 // rather it is to speed up properly written and correct programs. | 631 // rather it is to speed up properly written and correct programs. |
| 692 // That means that contextual checks (like a label being declared where | 632 // That means that contextual checks (like a label being declared where |
| 693 // it is used) are generally omitted. | 633 // it is used) are generally omitted. |
| 694 class PreParser : public ParserBase<PreParser> { | 634 class PreParser : public ParserBase<PreParser> { |
| 695 friend class ParserBase<PreParser>; | 635 friend class ParserBase<PreParser>; |
| 696 // TODO(nikolaos): This should not be necessary. It will be removed | 636 friend class v8::internal::ExpressionClassifier<ParserBaseTraits<PreParser>>; |
| 697 // when the traits object stops delegating to the implementation object. | |
| 698 friend class ParserBaseTraits<PreParser>; | |
| 699 | 637 |
| 700 public: | 638 public: |
| 701 typedef PreParserIdentifier Identifier; | 639 typedef PreParserIdentifier Identifier; |
| 702 typedef PreParserExpression Expression; | 640 typedef PreParserExpression Expression; |
| 703 typedef PreParserStatement Statement; | 641 typedef PreParserStatement Statement; |
| 704 | 642 |
| 705 enum PreParseResult { | 643 enum PreParseResult { |
| 706 kPreParseStackOverflow, | 644 kPreParseStackOverflow, |
| 707 kPreParseSuccess | 645 kPreParseSuccess |
| 708 }; | 646 }; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 // keyword and parameters, and have consumed the initial '{'. | 694 // keyword and parameters, and have consumed the initial '{'. |
| 757 // At return, unless an error occurred, the scanner is positioned before the | 695 // At return, unless an error occurred, the scanner is positioned before the |
| 758 // the final '}'. | 696 // the final '}'. |
| 759 PreParseResult PreParseLazyFunction(LanguageMode language_mode, | 697 PreParseResult PreParseLazyFunction(LanguageMode language_mode, |
| 760 FunctionKind kind, | 698 FunctionKind kind, |
| 761 bool has_simple_parameters, | 699 bool has_simple_parameters, |
| 762 bool parsing_module, ParserRecorder* log, | 700 bool parsing_module, ParserRecorder* log, |
| 763 Scanner::BookmarkScope* bookmark, | 701 Scanner::BookmarkScope* bookmark, |
| 764 int* use_counts); | 702 int* use_counts); |
| 765 | 703 |
| 704 // A dummy function, just useful as an argument to CHECK_OK_CUSTOM. |
| 705 static void Void() {} |
| 706 |
| 766 private: | 707 private: |
| 767 static const int kLazyParseTrialLimit = 200; | 708 static const int kLazyParseTrialLimit = 200; |
| 768 | 709 |
| 769 // These types form an algebra over syntactic categories that is just | 710 // These types form an algebra over syntactic categories that is just |
| 770 // rich enough to let us recognize and propagate the constructs that | 711 // rich enough to let us recognize and propagate the constructs that |
| 771 // are either being counted in the preparser data, or is important | 712 // are either being counted in the preparser data, or is important |
| 772 // to throw the correct syntax error exceptions. | 713 // to throw the correct syntax error exceptions. |
| 773 | 714 |
| 774 // All ParseXXX functions take as the last argument an *ok parameter | 715 // All ParseXXX functions take as the last argument an *ok parameter |
| 775 // which is set to false if parsing failed; it is unchanged otherwise. | 716 // which is set to false if parsing failed; it is unchanged otherwise. |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 } | 1073 } |
| 1133 | 1074 |
| 1134 V8_INLINE PreParserExpressionList NewPropertyList(int size) const { | 1075 V8_INLINE PreParserExpressionList NewPropertyList(int size) const { |
| 1135 return PreParserExpressionList(); | 1076 return PreParserExpressionList(); |
| 1136 } | 1077 } |
| 1137 | 1078 |
| 1138 V8_INLINE PreParserStatementList NewStatementList(int size) const { | 1079 V8_INLINE PreParserStatementList NewStatementList(int size) const { |
| 1139 return PreParserStatementList(); | 1080 return PreParserStatementList(); |
| 1140 } | 1081 } |
| 1141 | 1082 |
| 1083 V8_INLINE void AddParameterInitializationBlock( |
| 1084 const PreParserFormalParameters& parameters, PreParserStatementList body, |
| 1085 bool is_async, bool* ok) {} |
| 1086 |
| 1087 V8_INLINE void AddFormalParameter(PreParserFormalParameters* parameters, |
| 1088 PreParserExpression pattern, |
| 1089 PreParserExpression initializer, |
| 1090 int initializer_end_position, |
| 1091 bool is_rest) { |
| 1092 ++parameters->arity; |
| 1093 } |
| 1094 |
| 1095 V8_INLINE void DeclareFormalParameter( |
| 1096 DeclarationScope* scope, PreParserIdentifier parameter, |
| 1097 Type::ExpressionClassifier* classifier) { |
| 1098 if (!classifier->is_simple_parameter_list()) { |
| 1099 scope->SetHasNonSimpleParameters(); |
| 1100 } |
| 1101 } |
| 1102 |
| 1103 V8_INLINE void ParseArrowFunctionFormalParameterList( |
| 1104 PreParserFormalParameters* parameters, PreParserExpression params, |
| 1105 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, |
| 1106 const Scope::Snapshot& scope_snapshot, bool* ok) { |
| 1107 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect |
| 1108 // parameter |
| 1109 // lists that are too long. |
| 1110 } |
| 1111 |
| 1112 V8_INLINE void ReindexLiterals(const PreParserFormalParameters& parameters) {} |
| 1113 |
| 1114 V8_INLINE PreParserExpression NoTemplateTag() { |
| 1115 return PreParserExpression::NoTemplateTag(); |
| 1116 } |
| 1117 |
| 1118 V8_INLINE static bool IsTaggedTemplate(const PreParserExpression tag) { |
| 1119 return !tag.IsNoTemplateTag(); |
| 1120 } |
| 1121 |
| 1122 V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) { |
| 1123 for (int i = 0; i < count; ++i) { |
| 1124 function_state_->NextMaterializedLiteralIndex(); |
| 1125 } |
| 1126 } |
| 1127 |
| 1128 V8_INLINE PreParserExpression |
| 1129 ExpressionListToExpression(PreParserExpressionList args) { |
| 1130 return PreParserExpression::Default(); |
| 1131 } |
| 1132 |
| 1133 V8_INLINE void SetFunctionNameFromPropertyName(PreParserExpression property, |
| 1134 PreParserIdentifier name) {} |
| 1135 V8_INLINE void SetFunctionNameFromIdentifierRef( |
| 1136 PreParserExpression value, PreParserExpression identifier) {} |
| 1137 |
| 1138 V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>* |
| 1139 GetReportedErrorList() const { |
| 1140 return function_state_->GetReportedErrorList(); |
| 1141 } |
| 1142 |
| 1143 V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const { |
| 1144 return function_state_->non_patterns_to_rewrite(); |
| 1145 } |
| 1146 |
| 1142 // Preparser's private field members. | 1147 // Preparser's private field members. |
| 1143 | 1148 |
| 1144 int* use_counts_; | 1149 int* use_counts_; |
| 1145 }; | 1150 }; |
| 1146 | 1151 |
| 1147 void ParserBaseTraits<PreParser>::MaterializeUnspreadArgumentsLiterals( | |
| 1148 int count) { | |
| 1149 for (int i = 0; i < count; ++i) { | |
| 1150 delegate()->function_state_->NextMaterializedLiteralIndex(); | |
| 1151 } | |
| 1152 } | |
| 1153 | |
| 1154 PreParserExpression PreParser::SpreadCall(PreParserExpression function, | 1152 PreParserExpression PreParser::SpreadCall(PreParserExpression function, |
| 1155 PreParserExpressionList args, | 1153 PreParserExpressionList args, |
| 1156 int pos) { | 1154 int pos) { |
| 1157 return factory()->NewCall(function, args, pos); | 1155 return factory()->NewCall(function, args, pos); |
| 1158 } | 1156 } |
| 1159 | 1157 |
| 1160 PreParserExpression PreParser::SpreadCallNew(PreParserExpression function, | 1158 PreParserExpression PreParser::SpreadCallNew(PreParserExpression function, |
| 1161 PreParserExpressionList args, | 1159 PreParserExpressionList args, |
| 1162 int pos) { | 1160 int pos) { |
| 1163 return factory()->NewCallNew(function, args, pos); | 1161 return factory()->NewCallNew(function, args, pos); |
| 1164 } | 1162 } |
| 1165 | 1163 |
| 1166 void ParserBaseTraits<PreParser>::ParseArrowFunctionFormalParameterList( | |
| 1167 PreParserFormalParameters* parameters, PreParserExpression params, | |
| 1168 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, | |
| 1169 const Scope::Snapshot& scope_snapshot, bool* ok) { | |
| 1170 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter | |
| 1171 // lists that are too long. | |
| 1172 } | |
| 1173 | |
| 1174 ZoneList<PreParserExpression>* ParserBaseTraits<PreParser>::GetNonPatternList() | |
| 1175 const { | |
| 1176 return delegate()->function_state_->non_patterns_to_rewrite(); | |
| 1177 } | |
| 1178 | |
| 1179 ZoneList< | |
| 1180 typename ParserBaseTraits<PreParser>::Type::ExpressionClassifier::Error>* | |
| 1181 ParserBaseTraits<PreParser>::GetReportedErrorList() const { | |
| 1182 return delegate()->function_state_->GetReportedErrorList(); | |
| 1183 } | |
| 1184 | |
| 1185 Zone* ParserBaseTraits<PreParser>::zone() const { | |
| 1186 return delegate()->function_state_->scope()->zone(); | |
| 1187 } | |
| 1188 | |
| 1189 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1164 PreParserStatementList PreParser::ParseEagerFunctionBody( |
| 1190 PreParserIdentifier function_name, int pos, | 1165 PreParserIdentifier function_name, int pos, |
| 1191 const PreParserFormalParameters& parameters, FunctionKind kind, | 1166 const PreParserFormalParameters& parameters, FunctionKind kind, |
| 1192 FunctionLiteral::FunctionType function_type, bool* ok) { | 1167 FunctionLiteral::FunctionType function_type, bool* ok) { |
| 1193 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1168 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1194 | 1169 |
| 1195 Scope* inner_scope = scope(); | 1170 Scope* inner_scope = scope(); |
| 1196 if (!parameters.is_simple) inner_scope = NewScope(BLOCK_SCOPE); | 1171 if (!parameters.is_simple) inner_scope = NewScope(BLOCK_SCOPE); |
| 1197 | 1172 |
| 1198 { | 1173 { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1214 function_state_->NextMaterializedLiteralIndex(); | 1189 function_state_->NextMaterializedLiteralIndex(); |
| 1215 function_state_->NextMaterializedLiteralIndex(); | 1190 function_state_->NextMaterializedLiteralIndex(); |
| 1216 } | 1191 } |
| 1217 return EmptyExpression(); | 1192 return EmptyExpression(); |
| 1218 } | 1193 } |
| 1219 | 1194 |
| 1220 } // namespace internal | 1195 } // namespace internal |
| 1221 } // namespace v8 | 1196 } // namespace v8 |
| 1222 | 1197 |
| 1223 #endif // V8_PARSING_PREPARSER_H | 1198 #endif // V8_PARSING_PREPARSER_H |
| OLD | NEW |