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