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 |