| 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_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 #undef DUMMY | 133 #undef DUMMY |
| 134 | 134 |
| 135 // Used in functions where the return type is ExpressionT. | 135 // Used in functions where the return type is ExpressionT. |
| 136 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression) | 136 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression) |
| 137 | 137 |
| 138 // Common base class template shared between parser and pre-parser. | 138 // Common base class template shared between parser and pre-parser. |
| 139 // The Impl parameter is the actual class of the parser/pre-parser, | 139 // The Impl parameter is the actual class of the parser/pre-parser, |
| 140 // following the Curiously Recurring Template Pattern (CRTP). | 140 // following the Curiously Recurring Template Pattern (CRTP). |
| 141 // The structure of the parser objects is roughly the following: | 141 // The structure of the parser objects is roughly the following: |
| 142 // | 142 // |
| 143 // // Common denominator, needed to avoid cyclic dependency. | 143 // // A structure template containing type definitions, needed to |
| 144 // // Instances of this template will end up with very minimal | 144 // // avoid a cyclic dependency. |
| 145 // // definitions, ideally containing just typedefs. | |
| 146 // template <typename Impl> | 145 // template <typename Impl> |
| 147 // class ParserBaseTraits; | 146 // struct ParserTypes; |
| 148 | 147 // |
| 149 // // The parser base object, which should just implement pure | 148 // // The parser base object, which should just implement pure |
| 150 // // parser behavior. The Impl parameter is the actual derived | 149 // // parser behavior. The Impl parameter is the actual derived |
| 151 // // class (according to CRTP), which implements impure parser | 150 // // class (according to CRTP), which implements impure parser |
| 152 // // behavior. | 151 // // behavior. |
| 153 // template <typename Impl> | 152 // template <typename Impl> |
| 154 // class ParserBase : public ParserBaseTraits<Impl> { ... }; | 153 // class ParserBase { ... }; |
| 155 // | 154 // |
| 156 // // And then, for each parser variant (e.g., parser, preparser, etc): | 155 // // And then, for each parser variant (e.g., parser, preparser, etc): |
| 157 // class Parser; | 156 // class Parser; |
| 158 // | 157 // |
| 159 // template <> | 158 // template <> |
| 160 // class ParserBaseTraits<Parser> { ... }; | 159 // class ParserTypes<Parser> { ... }; |
| 161 // | 160 // |
| 162 // class Parser : public ParserBase<Parser> { ... }; | 161 // class Parser : public ParserBase<Parser> { ... }; |
| 163 // | 162 // |
| 164 // The traits class template encapsulates the differences between | 163 // The parser base object implements pure parsing, according to the |
| 165 // parser/pre-parser implementations. In particular: | 164 // language grammar. Different parser implementations may exhibit |
| 165 // different parser-driven behavior that is not considered as pure |
| 166 // parsing, e.g., early error detection and reporting, AST generation, etc. |
| 166 | 167 |
| 167 // - Return types: For example, Parser functions return Expression* and | 168 // The ParserTypes structure encapsulates the differences in the |
| 168 // PreParser functions return PreParserExpression. | 169 // types used in parsing methods. E.g., Parser methods use Expression* |
| 169 | 170 // and PreParser methods use PreParserExpression. For any given parser |
| 170 // - Creating parse tree nodes: Parser generates an AST during the recursive | 171 // implementation class Impl, it is expected to contain the following typedefs: |
| 171 // descent. PreParser doesn't create a tree. Instead, it passes around minimal | 172 // |
| 172 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain | |
| 173 // just enough data for the upper layer functions. PreParserFactory is | |
| 174 // responsible for creating these dummy objects. It provides a similar kind of | |
| 175 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is | |
| 176 // used. | |
| 177 | |
| 178 // The traits are expected to contain the following typedefs: | |
| 179 // template <> | 173 // template <> |
| 180 // class ParserBaseTraits<Impl> { | 174 // struct ParserTypes<Impl> { |
| 181 // // In particular... | 175 // // Synonyms for ParserBase<Impl> and Impl, respectively. |
| 182 // struct Type { | 176 // typedef Base; |
| 183 // // Synonyms for ParserBase<Impl> and Impl, respectively. | 177 // typedef Impl; |
| 184 // typedef Base; | 178 // // TODO(nikolaos): these three will probably go away, as they are |
| 185 // typedef Impl; | 179 // // not related to pure parsing. |
| 186 // typedef GeneratorVariable; | 180 // typedef GeneratorVariable; |
| 187 // typedef AstProperties; | 181 // typedef AstProperties; |
| 188 // typedef ExpressionClassifier; | 182 // typedef ExpressionClassifier; |
| 189 // // Return types for traversing functions. | 183 // // Return types for traversing functions. |
| 190 // typedef Identifier; | 184 // typedef Identifier; |
| 191 // typedef Expression; | 185 // typedef Expression; |
| 192 // typedef YieldExpression; | 186 // typedef YieldExpression; |
| 193 // typedef FunctionLiteral; | 187 // typedef FunctionLiteral; |
| 194 // typedef ClassLiteral; | 188 // typedef ClassLiteral; |
| 195 // typedef Literal; | 189 // typedef Literal; |
| 196 // typedef ObjectLiteralProperty; | 190 // typedef ObjectLiteralProperty; |
| 197 // typedef ExpressionList; | 191 // typedef ExpressionList; |
| 198 // typedef PropertyList; | 192 // typedef PropertyList; |
| 199 // typedef FormalParameter; | 193 // typedef FormalParameter; |
| 200 // typedef FormalParameters; | 194 // typedef FormalParameters; |
| 201 // typedef StatementList; | 195 // typedef StatementList; |
| 202 // // For constructing objects returned by the traversing functions. | 196 // // For constructing objects returned by the traversing functions. |
| 203 // typedef Factory; | 197 // typedef Factory; |
| 204 // }; | |
| 205 // // ... | |
| 206 // }; | 198 // }; |
| 207 | 199 |
| 208 template <typename Impl> | 200 template <typename Impl> |
| 209 class ParserBaseTraits; | 201 struct ParserTypes; |
| 210 | 202 |
| 211 template <typename Impl> | 203 template <typename Impl> |
| 212 class ParserBase : public ParserBaseTraits<Impl> { | 204 class ParserBase { |
| 213 public: | 205 public: |
| 214 // Shorten type names defined by Traits. | 206 // Shorten type names defined by ParserTypes<Impl>. |
| 215 typedef ParserBaseTraits<Impl> Traits; | 207 typedef ParserTypes<Impl> Types; |
| 216 typedef typename Traits::Type::Expression ExpressionT; | 208 typedef typename Types::Expression ExpressionT; |
| 217 typedef typename Traits::Type::Identifier IdentifierT; | 209 typedef typename Types::Identifier IdentifierT; |
| 218 typedef typename Traits::Type::FormalParameter FormalParameterT; | 210 typedef typename Types::FormalParameter FormalParameterT; |
| 219 typedef typename Traits::Type::FormalParameters FormalParametersT; | 211 typedef typename Types::FormalParameters FormalParametersT; |
| 220 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | 212 typedef typename Types::FunctionLiteral FunctionLiteralT; |
| 221 typedef typename Traits::Type::Literal LiteralT; | 213 typedef typename Types::Literal LiteralT; |
| 222 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; | 214 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; |
| 223 typedef typename Traits::Type::StatementList StatementListT; | 215 typedef typename Types::StatementList StatementListT; |
| 224 typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier; | 216 typedef typename Types::ExpressionClassifier ExpressionClassifier; |
| 225 | 217 |
| 226 // All implementation-specific methods must be called through this. | 218 // All implementation-specific methods must be called through this. |
| 227 Impl* impl() { return static_cast<Impl*>(this); } | 219 Impl* impl() { return static_cast<Impl*>(this); } |
| 228 const Impl* impl() const { return static_cast<const Impl*>(this); } | 220 const Impl* impl() const { return static_cast<const Impl*>(this); } |
| 229 | 221 |
| 230 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, | 222 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
| 231 v8::Extension* extension, AstValueFactory* ast_value_factory, | 223 v8::Extension* extension, AstValueFactory* ast_value_factory, |
| 232 ParserRecorder* log) | 224 ParserRecorder* log) |
| 233 : scope_state_(nullptr), | 225 : scope_state_(nullptr), |
| 234 function_state_(nullptr), | 226 function_state_(nullptr), |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 int expected_property_count() { return expected_property_count_; } | 432 int expected_property_count() { return expected_property_count_; } |
| 441 | 433 |
| 442 bool is_generator() const { return IsGeneratorFunction(kind_); } | 434 bool is_generator() const { return IsGeneratorFunction(kind_); } |
| 443 bool is_async_function() const { return IsAsyncFunction(kind_); } | 435 bool is_async_function() const { return IsAsyncFunction(kind_); } |
| 444 bool is_resumable() const { return is_generator() || is_async_function(); } | 436 bool is_resumable() const { return is_generator() || is_async_function(); } |
| 445 | 437 |
| 446 FunctionKind kind() const { return kind_; } | 438 FunctionKind kind() const { return kind_; } |
| 447 FunctionState* outer() const { return outer_function_state_; } | 439 FunctionState* outer() const { return outer_function_state_; } |
| 448 | 440 |
| 449 void set_generator_object_variable( | 441 void set_generator_object_variable( |
| 450 typename Traits::Type::GeneratorVariable* variable) { | 442 typename Types::GeneratorVariable* variable) { |
| 451 DCHECK(variable != NULL); | 443 DCHECK(variable != NULL); |
| 452 DCHECK(is_resumable()); | 444 DCHECK(is_resumable()); |
| 453 generator_object_variable_ = variable; | 445 generator_object_variable_ = variable; |
| 454 } | 446 } |
| 455 typename Traits::Type::GeneratorVariable* generator_object_variable() | 447 typename Types::GeneratorVariable* generator_object_variable() const { |
| 456 const { | |
| 457 return generator_object_variable_; | 448 return generator_object_variable_; |
| 458 } | 449 } |
| 459 | 450 |
| 460 const ZoneList<DestructuringAssignment>& | 451 const ZoneList<DestructuringAssignment>& |
| 461 destructuring_assignments_to_rewrite() const { | 452 destructuring_assignments_to_rewrite() const { |
| 462 return destructuring_assignments_to_rewrite_; | 453 return destructuring_assignments_to_rewrite_; |
| 463 } | 454 } |
| 464 | 455 |
| 465 TailCallExpressionList& tail_call_expressions() { | 456 TailCallExpressionList& tail_call_expressions() { |
| 466 return tail_call_expressions_; | 457 return tail_call_expressions_; |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 } | 860 } |
| 870 } | 861 } |
| 871 | 862 |
| 872 // Determine precedence of given token. | 863 // Determine precedence of given token. |
| 873 static int Precedence(Token::Value token, bool accept_IN) { | 864 static int Precedence(Token::Value token, bool accept_IN) { |
| 874 if (token == Token::IN && !accept_IN) | 865 if (token == Token::IN && !accept_IN) |
| 875 return 0; // 0 precedence will terminate binary expression parsing | 866 return 0; // 0 precedence will terminate binary expression parsing |
| 876 return Token::Precedence(token); | 867 return Token::Precedence(token); |
| 877 } | 868 } |
| 878 | 869 |
| 879 typename Traits::Type::Factory* factory() { return &ast_node_factory_; } | 870 typename Types::Factory* factory() { return &ast_node_factory_; } |
| 880 | 871 |
| 881 DeclarationScope* GetReceiverScope() const { | 872 DeclarationScope* GetReceiverScope() const { |
| 882 return scope()->GetReceiverScope(); | 873 return scope()->GetReceiverScope(); |
| 883 } | 874 } |
| 884 LanguageMode language_mode() { return scope()->language_mode(); } | 875 LanguageMode language_mode() { return scope()->language_mode(); } |
| 885 bool is_generator() const { return function_state_->is_generator(); } | 876 bool is_generator() const { return function_state_->is_generator(); } |
| 886 bool is_async_function() const { | 877 bool is_async_function() const { |
| 887 return function_state_->is_async_function(); | 878 return function_state_->is_async_function(); |
| 888 } | 879 } |
| 889 bool is_resumable() const { return function_state_->is_resumable(); } | 880 bool is_resumable() const { return function_state_->is_resumable(); } |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 bool* ok); | 1083 bool* ok); |
| 1093 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 1084 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
| 1094 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 1085 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| 1095 bool* is_computed_name, | 1086 bool* is_computed_name, |
| 1096 ExpressionClassifier* classifier, bool* ok); | 1087 ExpressionClassifier* classifier, bool* ok); |
| 1097 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 1088 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
| 1098 ObjectLiteralPropertyT ParsePropertyDefinition( | 1089 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 1099 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1090 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 1100 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor, | 1091 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor, |
| 1101 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 1092 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
| 1102 typename Traits::Type::ExpressionList ParseArguments( | 1093 typename Types::ExpressionList ParseArguments( |
| 1103 Scanner::Location* first_spread_pos, bool maybe_arrow, | 1094 Scanner::Location* first_spread_pos, bool maybe_arrow, |
| 1104 ExpressionClassifier* classifier, bool* ok); | 1095 ExpressionClassifier* classifier, bool* ok); |
| 1105 typename Traits::Type::ExpressionList ParseArguments( | 1096 typename Types::ExpressionList ParseArguments( |
| 1106 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 1097 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
| 1107 bool* ok) { | 1098 bool* ok) { |
| 1108 return ParseArguments(first_spread_pos, false, classifier, ok); | 1099 return ParseArguments(first_spread_pos, false, classifier, ok); |
| 1109 } | 1100 } |
| 1110 | 1101 |
| 1111 ExpressionT ParseAssignmentExpression(bool accept_IN, | 1102 ExpressionT ParseAssignmentExpression(bool accept_IN, |
| 1112 ExpressionClassifier* classifier, | 1103 ExpressionClassifier* classifier, |
| 1113 bool* ok); | 1104 bool* ok); |
| 1114 ExpressionT ParseYieldExpression(bool accept_IN, | 1105 ExpressionT ParseYieldExpression(bool accept_IN, |
| 1115 ExpressionClassifier* classifier, bool* ok); | 1106 ExpressionClassifier* classifier, bool* ok); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 ModuleDescriptor* module() const { | 1252 ModuleDescriptor* module() const { |
| 1262 return scope()->AsModuleScope()->module(); | 1253 return scope()->AsModuleScope()->module(); |
| 1263 } | 1254 } |
| 1264 Scope* scope() const { return scope_state_->scope(); } | 1255 Scope* scope() const { return scope_state_->scope(); } |
| 1265 | 1256 |
| 1266 ScopeState* scope_state_; // Scope stack. | 1257 ScopeState* scope_state_; // Scope stack. |
| 1267 FunctionState* function_state_; // Function state stack. | 1258 FunctionState* function_state_; // Function state stack. |
| 1268 v8::Extension* extension_; | 1259 v8::Extension* extension_; |
| 1269 FuncNameInferrer* fni_; | 1260 FuncNameInferrer* fni_; |
| 1270 AstValueFactory* ast_value_factory_; // Not owned. | 1261 AstValueFactory* ast_value_factory_; // Not owned. |
| 1271 typename Traits::Type::Factory ast_node_factory_; | 1262 typename Types::Factory ast_node_factory_; |
| 1272 ParserRecorder* log_; | 1263 ParserRecorder* log_; |
| 1273 Mode mode_; | 1264 Mode mode_; |
| 1274 bool parsing_module_; | 1265 bool parsing_module_; |
| 1275 uintptr_t stack_limit_; | 1266 uintptr_t stack_limit_; |
| 1276 | 1267 |
| 1277 private: | 1268 private: |
| 1278 Zone* zone_; | 1269 Zone* zone_; |
| 1279 | 1270 |
| 1280 Scanner* scanner_; | 1271 Scanner* scanner_; |
| 1281 bool stack_overflow_; | 1272 bool stack_overflow_; |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1790 return result; | 1781 return result; |
| 1791 } | 1782 } |
| 1792 | 1783 |
| 1793 template <typename Impl> | 1784 template <typename Impl> |
| 1794 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( | 1785 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( |
| 1795 ExpressionClassifier* classifier, bool* ok) { | 1786 ExpressionClassifier* classifier, bool* ok) { |
| 1796 // ArrayLiteral :: | 1787 // ArrayLiteral :: |
| 1797 // '[' Expression? (',' Expression?)* ']' | 1788 // '[' Expression? (',' Expression?)* ']' |
| 1798 | 1789 |
| 1799 int pos = peek_position(); | 1790 int pos = peek_position(); |
| 1800 typename Traits::Type::ExpressionList values = impl()->NewExpressionList(4); | 1791 typename Types::ExpressionList values = impl()->NewExpressionList(4); |
| 1801 int first_spread_index = -1; | 1792 int first_spread_index = -1; |
| 1802 Expect(Token::LBRACK, CHECK_OK); | 1793 Expect(Token::LBRACK, CHECK_OK); |
| 1803 while (peek() != Token::RBRACK) { | 1794 while (peek() != Token::RBRACK) { |
| 1804 ExpressionT elem; | 1795 ExpressionT elem; |
| 1805 if (peek() == Token::COMMA) { | 1796 if (peek() == Token::COMMA) { |
| 1806 elem = impl()->GetLiteralTheHole(peek_position()); | 1797 elem = impl()->GetLiteralTheHole(peek_position()); |
| 1807 } else if (peek() == Token::ELLIPSIS) { | 1798 } else if (peek() == Token::ELLIPSIS) { |
| 1808 int start_pos = peek_position(); | 1799 int start_pos = peek_position(); |
| 1809 Consume(Token::ELLIPSIS); | 1800 Consume(Token::ELLIPSIS); |
| 1810 int expr_pos = peek_position(); | 1801 int expr_pos = peek_position(); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2107 name_expression = ParsePropertyName( | 2098 name_expression = ParsePropertyName( |
| 2108 name, &dont_care, &dont_care, is_computed_name, classifier, | 2099 name, &dont_care, &dont_care, is_computed_name, classifier, |
| 2109 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2100 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2110 | 2101 |
| 2111 if (!*is_computed_name) { | 2102 if (!*is_computed_name) { |
| 2112 checker->CheckProperty(name_token, kAccessorProperty, method_kind, | 2103 checker->CheckProperty(name_token, kAccessorProperty, method_kind, |
| 2113 classifier, | 2104 classifier, |
| 2114 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2105 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2115 } | 2106 } |
| 2116 | 2107 |
| 2117 typename Traits::Type::FunctionLiteral value = impl()->ParseFunctionLiteral( | 2108 FunctionLiteralT value = impl()->ParseFunctionLiteral( |
| 2118 *name, scanner()->location(), kSkipFunctionNameCheck, | 2109 *name, scanner()->location(), kSkipFunctionNameCheck, |
| 2119 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, | 2110 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, |
| 2120 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), | 2111 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), |
| 2121 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2112 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2122 | 2113 |
| 2123 // Make sure the name expression is a string since we need a Name for | 2114 // Make sure the name expression is a string since we need a Name for |
| 2124 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this | 2115 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this |
| 2125 // statically we can skip the extra runtime check. | 2116 // statically we can skip the extra runtime check. |
| 2126 if (!*is_computed_name) { | 2117 if (!*is_computed_name) { |
| 2127 name_expression = | 2118 name_expression = |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2140 return impl()->EmptyObjectLiteralProperty(); | 2131 return impl()->EmptyObjectLiteralProperty(); |
| 2141 } | 2132 } |
| 2142 | 2133 |
| 2143 template <typename Impl> | 2134 template <typename Impl> |
| 2144 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 2135 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( |
| 2145 ExpressionClassifier* classifier, bool* ok) { | 2136 ExpressionClassifier* classifier, bool* ok) { |
| 2146 // ObjectLiteral :: | 2137 // ObjectLiteral :: |
| 2147 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2138 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
| 2148 | 2139 |
| 2149 int pos = peek_position(); | 2140 int pos = peek_position(); |
| 2150 typename Traits::Type::PropertyList properties = impl()->NewPropertyList(4); | 2141 typename Types::PropertyList properties = impl()->NewPropertyList(4); |
| 2151 int number_of_boilerplate_properties = 0; | 2142 int number_of_boilerplate_properties = 0; |
| 2152 bool has_computed_names = false; | 2143 bool has_computed_names = false; |
| 2153 ObjectLiteralChecker checker(this); | 2144 ObjectLiteralChecker checker(this); |
| 2154 | 2145 |
| 2155 Expect(Token::LBRACE, CHECK_OK); | 2146 Expect(Token::LBRACE, CHECK_OK); |
| 2156 | 2147 |
| 2157 while (peek() != Token::RBRACE) { | 2148 while (peek() != Token::RBRACE) { |
| 2158 FuncNameInferrer::State fni_state(fni_); | 2149 FuncNameInferrer::State fni_state(fni_); |
| 2159 | 2150 |
| 2160 const bool in_class = false; | 2151 const bool in_class = false; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2189 // Computation of literal_index must happen before pre parse bailout. | 2180 // Computation of literal_index must happen before pre parse bailout. |
| 2190 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2181 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 2191 | 2182 |
| 2192 return factory()->NewObjectLiteral(properties, | 2183 return factory()->NewObjectLiteral(properties, |
| 2193 literal_index, | 2184 literal_index, |
| 2194 number_of_boilerplate_properties, | 2185 number_of_boilerplate_properties, |
| 2195 pos); | 2186 pos); |
| 2196 } | 2187 } |
| 2197 | 2188 |
| 2198 template <typename Impl> | 2189 template <typename Impl> |
| 2199 typename ParserBase<Impl>::Traits::Type::ExpressionList | 2190 typename ParserBase<Impl>::Types::ExpressionList |
| 2200 ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc, | 2191 ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc, |
| 2201 bool maybe_arrow, | 2192 bool maybe_arrow, |
| 2202 ExpressionClassifier* classifier, bool* ok) { | 2193 ExpressionClassifier* classifier, bool* ok) { |
| 2203 // Arguments :: | 2194 // Arguments :: |
| 2204 // '(' (AssignmentExpression)*[','] ')' | 2195 // '(' (AssignmentExpression)*[','] ')' |
| 2205 | 2196 |
| 2206 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2197 Scanner::Location spread_arg = Scanner::Location::invalid(); |
| 2207 typename Traits::Type::ExpressionList result = impl()->NewExpressionList(4); | 2198 typename Types::ExpressionList result = impl()->NewExpressionList(4); |
| 2208 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2199 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2209 bool done = (peek() == Token::RPAREN); | 2200 bool done = (peek() == Token::RPAREN); |
| 2210 bool was_unspread = false; | 2201 bool was_unspread = false; |
| 2211 int unspread_sequences_count = 0; | 2202 int unspread_sequences_count = 0; |
| 2212 while (!done) { | 2203 while (!done) { |
| 2213 int start_pos = peek_position(); | 2204 int start_pos = peek_position(); |
| 2214 bool is_spread = Check(Token::ELLIPSIS); | 2205 bool is_spread = Check(Token::ELLIPSIS); |
| 2215 int expr_pos = peek_position(); | 2206 int expr_pos = peek_position(); |
| 2216 | 2207 |
| 2217 ExpressionT argument = ParseAssignmentExpression( | 2208 ExpressionT argument = ParseAssignmentExpression( |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2537 } | 2528 } |
| 2538 } | 2529 } |
| 2539 | 2530 |
| 2540 if (delegating) { | 2531 if (delegating) { |
| 2541 return impl()->RewriteYieldStar(generator_object, expression, pos); | 2532 return impl()->RewriteYieldStar(generator_object, expression, pos); |
| 2542 } | 2533 } |
| 2543 | 2534 |
| 2544 expression = impl()->BuildIteratorResult(expression, false); | 2535 expression = impl()->BuildIteratorResult(expression, false); |
| 2545 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2536 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
| 2546 // TODO(verwaest): Come up with a better solution. | 2537 // TODO(verwaest): Come up with a better solution. |
| 2547 typename Traits::Type::YieldExpression yield = factory()->NewYield( | 2538 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, |
| 2548 generator_object, expression, pos, Yield::kOnExceptionThrow); | 2539 Yield::kOnExceptionThrow); |
| 2549 return yield; | 2540 return yield; |
| 2550 } | 2541 } |
| 2551 | 2542 |
| 2552 template <typename Impl> | 2543 template <typename Impl> |
| 2553 typename ParserBase<Impl>::ExpressionT | 2544 typename ParserBase<Impl>::ExpressionT |
| 2554 ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier, | 2545 ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier, |
| 2555 bool* ok) { | 2546 bool* ok) { |
| 2556 // TailCallExpression:: | 2547 // TailCallExpression:: |
| 2557 // 'continue' MemberExpression Arguments | 2548 // 'continue' MemberExpression Arguments |
| 2558 // 'continue' CallExpression Arguments | 2549 // 'continue' CallExpression Arguments |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2736 return impl()->EmptyExpression(); | 2727 return impl()->EmptyExpression(); |
| 2737 } | 2728 } |
| 2738 } | 2729 } |
| 2739 | 2730 |
| 2740 if (peek() == Token::EXP) { | 2731 if (peek() == Token::EXP) { |
| 2741 ReportUnexpectedToken(Next()); | 2732 ReportUnexpectedToken(Next()); |
| 2742 *ok = false; | 2733 *ok = false; |
| 2743 return impl()->EmptyExpression(); | 2734 return impl()->EmptyExpression(); |
| 2744 } | 2735 } |
| 2745 | 2736 |
| 2746 // Allow Traits do rewrite the expression. | 2737 // Allow the parser's implementation to rewrite the expression. |
| 2747 return impl()->BuildUnaryExpression(expression, op, pos); | 2738 return impl()->BuildUnaryExpression(expression, op, pos); |
| 2748 } else if (Token::IsCountOp(op)) { | 2739 } else if (Token::IsCountOp(op)) { |
| 2749 BindingPatternUnexpectedToken(classifier); | 2740 BindingPatternUnexpectedToken(classifier); |
| 2750 ArrowFormalParametersUnexpectedToken(classifier); | 2741 ArrowFormalParametersUnexpectedToken(classifier); |
| 2751 op = Next(); | 2742 op = Next(); |
| 2752 int beg_pos = peek_position(); | 2743 int beg_pos = peek_position(); |
| 2753 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2744 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 2754 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2745 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2755 expression = CheckAndRewriteReferenceExpression( | 2746 expression = CheckAndRewriteReferenceExpression( |
| 2756 expression, beg_pos, scanner()->location().end_pos, | 2747 expression, beg_pos, scanner()->location().end_pos, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2859 // with positions recorded for function literal and confuse debugger. | 2850 // with positions recorded for function literal and confuse debugger. |
| 2860 pos = peek_position(); | 2851 pos = peek_position(); |
| 2861 // Also the trailing parenthesis are a hint that the function will | 2852 // Also the trailing parenthesis are a hint that the function will |
| 2862 // be called immediately. If we happen to have parsed a preceding | 2853 // be called immediately. If we happen to have parsed a preceding |
| 2863 // function literal eagerly, we can also compile it eagerly. | 2854 // function literal eagerly, we can also compile it eagerly. |
| 2864 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2855 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 2865 result->AsFunctionLiteral()->set_should_eager_compile(); | 2856 result->AsFunctionLiteral()->set_should_eager_compile(); |
| 2866 } | 2857 } |
| 2867 } | 2858 } |
| 2868 Scanner::Location spread_pos; | 2859 Scanner::Location spread_pos; |
| 2869 typename Traits::Type::ExpressionList args; | 2860 typename Types::ExpressionList args; |
| 2870 if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) { | 2861 if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) { |
| 2871 ExpressionClassifier async_classifier(this); | 2862 ExpressionClassifier async_classifier(this); |
| 2872 args = ParseArguments(&spread_pos, true, &async_classifier, CHECK_OK); | 2863 args = ParseArguments(&spread_pos, true, &async_classifier, CHECK_OK); |
| 2873 if (peek() == Token::ARROW) { | 2864 if (peek() == Token::ARROW) { |
| 2874 if (fni_) { | 2865 if (fni_) { |
| 2875 fni_->RemoveAsyncKeywordFromEnd(); | 2866 fni_->RemoveAsyncKeywordFromEnd(); |
| 2876 } | 2867 } |
| 2877 ValidateBindingPattern(&async_classifier, CHECK_OK); | 2868 ValidateBindingPattern(&async_classifier, CHECK_OK); |
| 2878 ValidateFormalParameterInitializer(&async_classifier, CHECK_OK); | 2869 ValidateFormalParameterInitializer(&async_classifier, CHECK_OK); |
| 2879 if (!async_classifier.is_valid_async_arrow_formal_parameters()) { | 2870 if (!async_classifier.is_valid_async_arrow_formal_parameters()) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2994 } else if (peek() == Token::PERIOD) { | 2985 } else if (peek() == Token::PERIOD) { |
| 2995 return ParseNewTargetExpression(CHECK_OK); | 2986 return ParseNewTargetExpression(CHECK_OK); |
| 2996 } else { | 2987 } else { |
| 2997 result = | 2988 result = |
| 2998 ParseMemberWithNewPrefixesExpression(classifier, is_async, CHECK_OK); | 2989 ParseMemberWithNewPrefixesExpression(classifier, is_async, CHECK_OK); |
| 2999 } | 2990 } |
| 3000 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2991 impl()->RewriteNonPattern(classifier, CHECK_OK); |
| 3001 if (peek() == Token::LPAREN) { | 2992 if (peek() == Token::LPAREN) { |
| 3002 // NewExpression with arguments. | 2993 // NewExpression with arguments. |
| 3003 Scanner::Location spread_pos; | 2994 Scanner::Location spread_pos; |
| 3004 typename Traits::Type::ExpressionList args = | 2995 typename Types::ExpressionList args = |
| 3005 ParseArguments(&spread_pos, classifier, CHECK_OK); | 2996 ParseArguments(&spread_pos, classifier, CHECK_OK); |
| 3006 | 2997 |
| 3007 if (spread_pos.IsValid()) { | 2998 if (spread_pos.IsValid()) { |
| 3008 args = impl()->PrepareSpreadArguments(args); | 2999 args = impl()->PrepareSpreadArguments(args); |
| 3009 result = impl()->SpreadCallNew(result, args, new_pos); | 3000 result = impl()->SpreadCallNew(result, args, new_pos); |
| 3010 } else { | 3001 } else { |
| 3011 result = factory()->NewCallNew(result, args, new_pos); | 3002 result = factory()->NewCallNew(result, args, new_pos); |
| 3012 } | 3003 } |
| 3013 // The expression can still continue with . or [ after the arguments. | 3004 // The expression can still continue with . or [ after the arguments. |
| 3014 result = ParseMemberExpressionContinuation(result, is_async, classifier, | 3005 result = ParseMemberExpressionContinuation(result, is_async, classifier, |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3391 const ExpressionClassifier& formals_classifier, bool* ok) { | 3382 const ExpressionClassifier& formals_classifier, bool* ok) { |
| 3392 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3383 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 3393 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3384 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 3394 // `=> ...` is never a valid expression, so report as syntax error. | 3385 // `=> ...` is never a valid expression, so report as syntax error. |
| 3395 // If next token is not `=>`, it's a syntax error anyways. | 3386 // If next token is not `=>`, it's a syntax error anyways. |
| 3396 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3387 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 3397 *ok = false; | 3388 *ok = false; |
| 3398 return impl()->EmptyExpression(); | 3389 return impl()->EmptyExpression(); |
| 3399 } | 3390 } |
| 3400 | 3391 |
| 3401 typename Traits::Type::StatementList body; | 3392 typename Types::StatementList body; |
| 3402 int num_parameters = formal_parameters.scope->num_parameters(); | 3393 int num_parameters = formal_parameters.scope->num_parameters(); |
| 3403 int materialized_literal_count = -1; | 3394 int materialized_literal_count = -1; |
| 3404 int expected_property_count = -1; | 3395 int expected_property_count = -1; |
| 3405 | 3396 |
| 3406 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; | 3397 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; |
| 3407 { | 3398 { |
| 3408 FunctionState function_state(&function_state_, &scope_state_, | 3399 FunctionState function_state(&function_state_, &scope_state_, |
| 3409 formal_parameters.scope, arrow_kind); | 3400 formal_parameters.scope, arrow_kind); |
| 3410 | 3401 |
| 3411 function_state.SkipMaterializedLiterals( | 3402 function_state.SkipMaterializedLiterals( |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3706 has_seen_constructor_ = true; | 3697 has_seen_constructor_ = true; |
| 3707 return; | 3698 return; |
| 3708 } | 3699 } |
| 3709 } | 3700 } |
| 3710 | 3701 |
| 3711 | 3702 |
| 3712 } // namespace internal | 3703 } // namespace internal |
| 3713 } // namespace v8 | 3704 } // namespace v8 |
| 3714 | 3705 |
| 3715 #endif // V8_PARSING_PARSER_BASE_H | 3706 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |