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