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" |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 : FormalParametersBase(scope) {} | 578 : FormalParametersBase(scope) {} |
579 int arity = 0; | 579 int arity = 0; |
580 | 580 |
581 int Arity() const { return arity; } | 581 int Arity() const { return arity; } |
582 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy | 582 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy |
583 }; | 583 }; |
584 | 584 |
585 | 585 |
586 class PreParser; | 586 class PreParser; |
587 | 587 |
588 class PreParserTraits { | 588 template <> |
| 589 class ParserBaseTraits<PreParser> { |
589 public: | 590 public: |
| 591 typedef ParserBaseTraits<PreParser> PreParserTraits; |
| 592 |
590 struct Type { | 593 struct Type { |
591 // TODO(marja): To be removed. The Traits object should contain all the data | |
592 // it needs. | |
593 typedef PreParser* Parser; | |
594 | |
595 // PreParser doesn't need to store generator variables. | 594 // PreParser doesn't need to store generator variables. |
596 typedef void GeneratorVariable; | 595 typedef void GeneratorVariable; |
597 | 596 |
598 typedef int AstProperties; | 597 typedef int AstProperties; |
599 | 598 |
600 typedef v8::internal::ExpressionClassifier<PreParserTraits> | 599 typedef v8::internal::ExpressionClassifier<PreParserTraits> |
601 ExpressionClassifier; | 600 ExpressionClassifier; |
602 | 601 |
603 // Return types for traversing functions. | 602 // Return types for traversing functions. |
604 typedef PreParserIdentifier Identifier; | 603 typedef PreParserIdentifier Identifier; |
605 typedef PreParserExpression Expression; | 604 typedef PreParserExpression Expression; |
606 typedef PreParserExpression YieldExpression; | 605 typedef PreParserExpression YieldExpression; |
607 typedef PreParserExpression FunctionLiteral; | 606 typedef PreParserExpression FunctionLiteral; |
608 typedef PreParserExpression ClassLiteral; | 607 typedef PreParserExpression ClassLiteral; |
609 typedef PreParserExpression Literal; | 608 typedef PreParserExpression Literal; |
610 typedef PreParserExpression ObjectLiteralProperty; | 609 typedef PreParserExpression ObjectLiteralProperty; |
611 typedef PreParserExpressionList ExpressionList; | 610 typedef PreParserExpressionList ExpressionList; |
612 typedef PreParserExpressionList PropertyList; | 611 typedef PreParserExpressionList PropertyList; |
613 typedef PreParserIdentifier FormalParameter; | 612 typedef PreParserIdentifier FormalParameter; |
614 typedef PreParserFormalParameters FormalParameters; | 613 typedef PreParserFormalParameters FormalParameters; |
615 typedef PreParserStatementList StatementList; | 614 typedef PreParserStatementList StatementList; |
616 | 615 |
617 // For constructing objects returned by the traversing functions. | 616 // For constructing objects returned by the traversing functions. |
618 typedef PreParserFactory Factory; | 617 typedef PreParserFactory Factory; |
619 }; | 618 }; |
620 | 619 |
621 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} | 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 } |
622 | 626 |
623 // Helper functions for recursive descent. | 627 // Helper functions for recursive descent. |
624 bool IsEval(PreParserIdentifier identifier) const { | 628 bool IsEval(PreParserIdentifier identifier) const { |
625 return identifier.IsEval(); | 629 return identifier.IsEval(); |
626 } | 630 } |
627 | 631 |
628 bool IsArguments(PreParserIdentifier identifier) const { | 632 bool IsArguments(PreParserIdentifier identifier) const { |
629 return identifier.IsArguments(); | 633 return identifier.IsArguments(); |
630 } | 634 } |
631 | 635 |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 bool* ok); | 985 bool* ok); |
982 | 986 |
983 V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>* | 987 V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>* |
984 GetReportedErrorList() const; | 988 GetReportedErrorList() const; |
985 V8_INLINE Zone* zone() const; | 989 V8_INLINE Zone* zone() const; |
986 V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const; | 990 V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const; |
987 | 991 |
988 inline PreParserExpression RewriteYieldStar(PreParserExpression generator, | 992 inline PreParserExpression RewriteYieldStar(PreParserExpression generator, |
989 PreParserExpression expression, | 993 PreParserExpression expression, |
990 int pos); | 994 int pos); |
991 | |
992 private: | |
993 PreParser* pre_parser_; | |
994 }; | 995 }; |
995 | 996 |
996 | 997 |
997 // Preparsing checks a JavaScript program and emits preparse-data that helps | 998 // Preparsing checks a JavaScript program and emits preparse-data that helps |
998 // a later parsing to be faster. | 999 // a later parsing to be faster. |
999 // See preparse-data-format.h for the data format. | 1000 // See preparse-data-format.h for the data format. |
1000 | 1001 |
1001 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1002 // The PreParser checks that the syntax follows the grammar for JavaScript, |
1002 // and collects some information about the program along the way. | 1003 // and collects some information about the program along the way. |
1003 // The grammar check is only performed in order to understand the program | 1004 // The grammar check is only performed in order to understand the program |
1004 // sufficiently to deduce some information about it, that can be used | 1005 // sufficiently to deduce some information about it, that can be used |
1005 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 1006 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
1006 // rather it is to speed up properly written and correct programs. | 1007 // rather it is to speed up properly written and correct programs. |
1007 // That means that contextual checks (like a label being declared where | 1008 // That means that contextual checks (like a label being declared where |
1008 // it is used) are generally omitted. | 1009 // it is used) are generally omitted. |
1009 class PreParser : public ParserBase<PreParserTraits> { | 1010 class PreParser : public ParserBase<PreParser> { |
| 1011 // TODO(nikolaos): This should not be necessary. It will be removed |
| 1012 // when the traits object stops delegating to the implementation object. |
| 1013 friend class ParserBaseTraits<PreParser>; |
| 1014 |
1010 public: | 1015 public: |
1011 typedef PreParserIdentifier Identifier; | 1016 typedef PreParserIdentifier Identifier; |
1012 typedef PreParserExpression Expression; | 1017 typedef PreParserExpression Expression; |
1013 typedef PreParserStatement Statement; | 1018 typedef PreParserStatement Statement; |
1014 | 1019 |
1015 enum PreParseResult { | 1020 enum PreParseResult { |
1016 kPreParseStackOverflow, | 1021 kPreParseStackOverflow, |
1017 kPreParseSuccess | 1022 kPreParseSuccess |
1018 }; | 1023 }; |
1019 | 1024 |
1020 PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory, | 1025 PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory, |
1021 ParserRecorder* log, uintptr_t stack_limit) | 1026 ParserRecorder* log, uintptr_t stack_limit) |
1022 : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL, | 1027 : ParserBase<PreParser>(zone, scanner, stack_limit, NULL, |
1023 ast_value_factory, log, this), | 1028 ast_value_factory, log), |
1024 use_counts_(nullptr) {} | 1029 use_counts_(nullptr) {} |
1025 | 1030 |
1026 // Pre-parse the program from the character stream; returns true on | 1031 // Pre-parse the program from the character stream; returns true on |
1027 // success (even if parsing failed, the pre-parse data successfully | 1032 // success (even if parsing failed, the pre-parse data successfully |
1028 // captured the syntax error), and false if a stack-overflow happened | 1033 // captured the syntax error), and false if a stack-overflow happened |
1029 // during parsing. | 1034 // during parsing. |
1030 PreParseResult PreParseProgram(int* materialized_literals = 0, | 1035 PreParseResult PreParseProgram(int* materialized_literals = 0, |
1031 bool is_module = false) { | 1036 bool is_module = false) { |
1032 DCHECK_NULL(scope_state_); | 1037 DCHECK_NULL(scope_state_); |
1033 DeclarationScope* scope = NewScriptScope(); | 1038 DeclarationScope* scope = NewScriptScope(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 // At return, unless an error occurred, the scanner is positioned before the | 1072 // At return, unless an error occurred, the scanner is positioned before the |
1068 // the final '}'. | 1073 // the final '}'. |
1069 PreParseResult PreParseLazyFunction(LanguageMode language_mode, | 1074 PreParseResult PreParseLazyFunction(LanguageMode language_mode, |
1070 FunctionKind kind, | 1075 FunctionKind kind, |
1071 bool has_simple_parameters, | 1076 bool has_simple_parameters, |
1072 bool parsing_module, ParserRecorder* log, | 1077 bool parsing_module, ParserRecorder* log, |
1073 Scanner::BookmarkScope* bookmark, | 1078 Scanner::BookmarkScope* bookmark, |
1074 int* use_counts); | 1079 int* use_counts); |
1075 | 1080 |
1076 private: | 1081 private: |
1077 friend class PreParserTraits; | |
1078 | |
1079 static const int kLazyParseTrialLimit = 200; | 1082 static const int kLazyParseTrialLimit = 200; |
1080 | 1083 |
1081 // These types form an algebra over syntactic categories that is just | 1084 // These types form an algebra over syntactic categories that is just |
1082 // rich enough to let us recognize and propagate the constructs that | 1085 // rich enough to let us recognize and propagate the constructs that |
1083 // are either being counted in the preparser data, or is important | 1086 // are either being counted in the preparser data, or is important |
1084 // to throw the correct syntax error exceptions. | 1087 // to throw the correct syntax error exceptions. |
1085 | 1088 |
1086 // All ParseXXX functions take as the last argument an *ok parameter | 1089 // All ParseXXX functions take as the last argument an *ok parameter |
1087 // which is set to false if parsing failed; it is unchanged otherwise. | 1090 // which is set to false if parsing failed; it is unchanged otherwise. |
1088 // By making the 'exception handling' explicit, we are forced to check | 1091 // By making the 'exception handling' explicit, we are forced to check |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1145 | 1148 |
1146 PreParserExpression ParseClassLiteral(ExpressionClassifier* classifier, | 1149 PreParserExpression ParseClassLiteral(ExpressionClassifier* classifier, |
1147 PreParserIdentifier name, | 1150 PreParserIdentifier name, |
1148 Scanner::Location class_name_location, | 1151 Scanner::Location class_name_location, |
1149 bool name_is_strict_reserved, int pos, | 1152 bool name_is_strict_reserved, int pos, |
1150 bool* ok); | 1153 bool* ok); |
1151 | 1154 |
1152 int* use_counts_; | 1155 int* use_counts_; |
1153 }; | 1156 }; |
1154 | 1157 |
1155 | 1158 void ParserBaseTraits<PreParser>::MaterializeUnspreadArgumentsLiterals( |
1156 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) { | 1159 int count) { |
1157 for (int i = 0; i < count; ++i) { | 1160 for (int i = 0; i < count; ++i) { |
1158 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1161 delegate()->function_state_->NextMaterializedLiteralIndex(); |
1159 } | 1162 } |
1160 } | 1163 } |
1161 | 1164 |
1162 | 1165 PreParserExpression ParserBaseTraits<PreParser>::SpreadCall( |
1163 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function, | 1166 PreParserExpression function, PreParserExpressionList args, int pos) { |
1164 PreParserExpressionList args, | 1167 return delegate()->factory()->NewCall(function, args, pos); |
1165 int pos) { | |
1166 return pre_parser_->factory()->NewCall(function, args, pos); | |
1167 } | 1168 } |
1168 | 1169 |
1169 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, | 1170 PreParserExpression ParserBaseTraits<PreParser>::SpreadCallNew( |
1170 PreParserExpressionList args, | 1171 PreParserExpression function, PreParserExpressionList args, int pos) { |
1171 int pos) { | 1172 return delegate()->factory()->NewCallNew(function, args, pos); |
1172 return pre_parser_->factory()->NewCallNew(function, args, pos); | |
1173 } | 1173 } |
1174 | 1174 |
1175 void PreParserTraits::ParseArrowFunctionFormalParameterList( | 1175 void ParserBaseTraits<PreParser>::ParseArrowFunctionFormalParameterList( |
1176 PreParserFormalParameters* parameters, PreParserExpression params, | 1176 PreParserFormalParameters* parameters, PreParserExpression params, |
1177 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, | 1177 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, |
1178 const Scope::Snapshot& scope_snapshot, bool* ok) { | 1178 const Scope::Snapshot& scope_snapshot, bool* ok) { |
1179 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter | 1179 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter |
1180 // lists that are too long. | 1180 // lists that are too long. |
1181 } | 1181 } |
1182 | 1182 |
1183 PreParserExpression PreParserTraits::ParseAsyncFunctionExpression(bool* ok) { | 1183 PreParserExpression ParserBaseTraits<PreParser>::ParseAsyncFunctionExpression( |
1184 return pre_parser_->ParseAsyncFunctionExpression(ok); | 1184 bool* ok) { |
| 1185 return delegate()->ParseAsyncFunctionExpression(ok); |
1185 } | 1186 } |
1186 | 1187 |
1187 PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) { | 1188 PreParserExpression ParserBaseTraits<PreParser>::ParseDoExpression(bool* ok) { |
1188 return pre_parser_->ParseDoExpression(ok); | 1189 return delegate()->ParseDoExpression(ok); |
1189 } | 1190 } |
1190 | 1191 |
1191 | 1192 void ParserBaseTraits<PreParser>::RewriteNonPattern( |
1192 void PreParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, | 1193 Type::ExpressionClassifier* classifier, bool* ok) { |
1193 bool* ok) { | 1194 delegate()->ValidateExpression(classifier, ok); |
1194 pre_parser_->ValidateExpression(classifier, ok); | |
1195 } | 1195 } |
1196 | 1196 |
1197 PreParserExpression PreParserTraits::RewriteAwaitExpression( | 1197 PreParserExpression ParserBaseTraits<PreParser>::RewriteAwaitExpression( |
1198 PreParserExpression value, int pos) { | 1198 PreParserExpression value, int pos) { |
1199 return value; | 1199 return value; |
1200 } | 1200 } |
1201 | 1201 |
1202 ZoneList<PreParserExpression>* PreParserTraits::GetNonPatternList() const { | 1202 ZoneList<PreParserExpression>* ParserBaseTraits<PreParser>::GetNonPatternList() |
1203 return pre_parser_->function_state_->non_patterns_to_rewrite(); | 1203 const { |
| 1204 return delegate()->function_state_->non_patterns_to_rewrite(); |
1204 } | 1205 } |
1205 | 1206 |
1206 | 1207 ZoneList< |
1207 ZoneList<typename PreParserTraits::Type::ExpressionClassifier::Error>* | 1208 typename ParserBaseTraits<PreParser>::Type::ExpressionClassifier::Error>* |
1208 PreParserTraits::GetReportedErrorList() const { | 1209 ParserBaseTraits<PreParser>::GetReportedErrorList() const { |
1209 return pre_parser_->function_state_->GetReportedErrorList(); | 1210 return delegate()->function_state_->GetReportedErrorList(); |
1210 } | 1211 } |
1211 | 1212 |
1212 | 1213 Zone* ParserBaseTraits<PreParser>::zone() const { |
1213 Zone* PreParserTraits::zone() const { | 1214 return delegate()->function_state_->scope()->zone(); |
1214 return pre_parser_->function_state_->scope()->zone(); | |
1215 } | 1215 } |
1216 | 1216 |
1217 | 1217 PreParserExpression ParserBaseTraits<PreParser>::RewriteYieldStar( |
1218 PreParserExpression PreParserTraits::RewriteYieldStar( | |
1219 PreParserExpression generator, PreParserExpression expression, int pos) { | 1218 PreParserExpression generator, PreParserExpression expression, int pos) { |
1220 return PreParserExpression::Default(); | 1219 return PreParserExpression::Default(); |
1221 } | 1220 } |
1222 | 1221 |
1223 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1222 PreParserStatementList PreParser::ParseEagerFunctionBody( |
1224 PreParserIdentifier function_name, int pos, | 1223 PreParserIdentifier function_name, int pos, |
1225 const PreParserFormalParameters& parameters, FunctionKind kind, | 1224 const PreParserFormalParameters& parameters, FunctionKind kind, |
1226 FunctionLiteral::FunctionType function_type, bool* ok) { | 1225 FunctionLiteral::FunctionType function_type, bool* ok) { |
1227 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1226 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1228 | 1227 |
1229 Scope* inner_scope = scope(); | 1228 Scope* inner_scope = scope(); |
1230 if (!parameters.is_simple) inner_scope = NewScope(BLOCK_SCOPE); | 1229 if (!parameters.is_simple) inner_scope = NewScope(BLOCK_SCOPE); |
1231 | 1230 |
1232 { | 1231 { |
1233 BlockState block_state(&scope_state_, inner_scope); | 1232 BlockState block_state(&scope_state_, inner_scope); |
1234 ParseStatementList(Token::RBRACE, ok); | 1233 ParseStatementList(Token::RBRACE, ok); |
1235 if (!*ok) return PreParserStatementList(); | 1234 if (!*ok) return PreParserStatementList(); |
1236 } | 1235 } |
1237 | 1236 |
1238 Expect(Token::RBRACE, ok); | 1237 Expect(Token::RBRACE, ok); |
1239 return PreParserStatementList(); | 1238 return PreParserStatementList(); |
1240 } | 1239 } |
1241 | 1240 |
1242 | 1241 PreParserStatementList ParserBaseTraits<PreParser>::ParseEagerFunctionBody( |
1243 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( | |
1244 PreParserIdentifier function_name, int pos, | 1242 PreParserIdentifier function_name, int pos, |
1245 const PreParserFormalParameters& parameters, FunctionKind kind, | 1243 const PreParserFormalParameters& parameters, FunctionKind kind, |
1246 FunctionLiteral::FunctionType function_type, bool* ok) { | 1244 FunctionLiteral::FunctionType function_type, bool* ok) { |
1247 return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters, | 1245 return delegate()->ParseEagerFunctionBody(function_name, pos, parameters, |
1248 kind, function_type, ok); | 1246 kind, function_type, ok); |
1249 } | 1247 } |
1250 | 1248 |
1251 PreParserExpression PreParserTraits::CloseTemplateLiteral( | 1249 PreParserExpression ParserBaseTraits<PreParser>::CloseTemplateLiteral( |
1252 TemplateLiteralState* state, int start, PreParserExpression tag) { | 1250 TemplateLiteralState* state, int start, PreParserExpression tag) { |
1253 if (IsTaggedTemplate(tag)) { | 1251 if (IsTaggedTemplate(tag)) { |
1254 // Emulate generation of array literals for tag callsite | 1252 // Emulate generation of array literals for tag callsite |
1255 // 1st is array of cooked strings, second is array of raw strings | 1253 // 1st is array of cooked strings, second is array of raw strings |
1256 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1254 delegate()->function_state_->NextMaterializedLiteralIndex(); |
1257 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1255 delegate()->function_state_->NextMaterializedLiteralIndex(); |
1258 } | 1256 } |
1259 return EmptyExpression(); | 1257 return EmptyExpression(); |
1260 } | 1258 } |
1261 | 1259 |
1262 } // namespace internal | 1260 } // namespace internal |
1263 } // namespace v8 | 1261 } // namespace v8 |
1264 | 1262 |
1265 #endif // V8_PARSING_PREPARSER_H | 1263 #endif // V8_PARSING_PREPARSER_H |
OLD | NEW |