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