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/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 }; | 191 }; |
192 | 192 |
193 struct TailCallExpression { | 193 struct TailCallExpression { |
194 TailCallExpression(ExpressionT expression, int pos) | 194 TailCallExpression(ExpressionT expression, int pos) |
195 : expression(expression), pos(pos) {} | 195 : expression(expression), pos(pos) {} |
196 | 196 |
197 ExpressionT expression; | 197 ExpressionT expression; |
198 int pos; | 198 int pos; |
199 }; | 199 }; |
200 | 200 |
| 201 // Defines whether tail call expressions are allowed or not. |
| 202 enum class ReturnExprContext { |
| 203 // Tail call expressions are allowed. |
| 204 kNormal, |
| 205 // Tail call expressions are not allowed. |
| 206 kInsideTryBlock, |
| 207 kInsideForInOfBody, |
| 208 }; |
| 209 |
201 class FunctionState BASE_EMBEDDED { | 210 class FunctionState BASE_EMBEDDED { |
202 public: | 211 public: |
203 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, | 212 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, |
204 Scope* scope, FunctionKind kind, | 213 Scope* scope, FunctionKind kind, |
205 typename Traits::Type::Factory* factory); | 214 typename Traits::Type::Factory* factory); |
206 ~FunctionState(); | 215 ~FunctionState(); |
207 | 216 |
208 int NextMaterializedLiteralIndex() { | 217 int NextMaterializedLiteralIndex() { |
209 return next_materialized_literal_index_++; | 218 return next_materialized_literal_index_++; |
210 } | 219 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 | 261 |
253 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 262 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
254 const { | 263 const { |
255 return destructuring_assignments_to_rewrite_; | 264 return destructuring_assignments_to_rewrite_; |
256 } | 265 } |
257 | 266 |
258 List<TailCallExpression>& expressions_in_tail_position() { | 267 List<TailCallExpression>& expressions_in_tail_position() { |
259 return expressions_in_tail_position_; | 268 return expressions_in_tail_position_; |
260 } | 269 } |
261 void AddExpressionInTailPosition(ExpressionT expression, int pos) { | 270 void AddExpressionInTailPosition(ExpressionT expression, int pos) { |
262 if (collect_expressions_in_tail_position_) { | 271 if (return_expr_context() == ReturnExprContext::kNormal) { |
263 expressions_in_tail_position_.Add(TailCallExpression(expression, pos)); | 272 expressions_in_tail_position_.Add(TailCallExpression(expression, pos)); |
264 } | 273 } |
265 } | 274 } |
266 | 275 |
267 bool collect_expressions_in_tail_position() const { | 276 ReturnExprContext return_expr_context() const { |
268 return collect_expressions_in_tail_position_; | 277 return return_expr_context_; |
269 } | 278 } |
270 void set_collect_expressions_in_tail_position(bool collect) { | 279 void set_return_expr_context(ReturnExprContext context) { |
271 collect_expressions_in_tail_position_ = collect; | 280 return_expr_context_ = context; |
272 } | 281 } |
273 | 282 |
274 ZoneList<ExpressionT>* non_patterns_to_rewrite() { | 283 ZoneList<ExpressionT>* non_patterns_to_rewrite() { |
275 return &non_patterns_to_rewrite_; | 284 return &non_patterns_to_rewrite_; |
276 } | 285 } |
277 | 286 |
278 void next_function_is_parenthesized(bool parenthesized) { | 287 void next_function_is_parenthesized(bool parenthesized) { |
279 next_function_is_parenthesized_ = parenthesized; | 288 next_function_is_parenthesized_ = parenthesized; |
280 } | 289 } |
281 | 290 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 // for generator functions to have this variable set. | 326 // for generator functions to have this variable set. |
318 Variable* generator_object_variable_; | 327 Variable* generator_object_variable_; |
319 | 328 |
320 FunctionState** function_state_stack_; | 329 FunctionState** function_state_stack_; |
321 FunctionState* outer_function_state_; | 330 FunctionState* outer_function_state_; |
322 Scope** scope_stack_; | 331 Scope** scope_stack_; |
323 Scope* outer_scope_; | 332 Scope* outer_scope_; |
324 | 333 |
325 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; | 334 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
326 List<TailCallExpression> expressions_in_tail_position_; | 335 List<TailCallExpression> expressions_in_tail_position_; |
327 bool collect_expressions_in_tail_position_; | 336 ReturnExprContext return_expr_context_; |
328 ZoneList<ExpressionT> non_patterns_to_rewrite_; | 337 ZoneList<ExpressionT> non_patterns_to_rewrite_; |
329 | 338 |
330 typename Traits::Type::Factory* factory_; | 339 typename Traits::Type::Factory* factory_; |
331 | 340 |
332 // If true, the next (and immediately following) function literal is | 341 // If true, the next (and immediately following) function literal is |
333 // preceded by a parenthesis. | 342 // preceded by a parenthesis. |
334 bool next_function_is_parenthesized_; | 343 bool next_function_is_parenthesized_; |
335 | 344 |
336 // The value of the parents' next_function_is_parenthesized_, as it applies | 345 // The value of the parents' next_function_is_parenthesized_, as it applies |
337 // to this function. Filled in by constructor. | 346 // to this function. Filled in by constructor. |
338 bool this_function_is_parenthesized_; | 347 bool this_function_is_parenthesized_; |
339 | 348 |
340 friend class ParserTraits; | 349 friend class ParserTraits; |
341 friend class PreParserTraits; | 350 friend class PreParserTraits; |
342 friend class Checkpoint; | 351 friend class Checkpoint; |
343 }; | 352 }; |
344 | 353 |
345 // This scope disables collecting of expressions at tail call position. | 354 // This scope sets current ReturnExprContext to given value. |
346 class DontCollectExpressionsInTailPositionScope { | 355 class ReturnExprScope { |
347 public: | 356 public: |
348 explicit DontCollectExpressionsInTailPositionScope( | 357 explicit ReturnExprScope(FunctionState* function_state, |
349 FunctionState* function_state) | 358 ReturnExprContext return_expr_context) |
350 : function_state_(function_state), | 359 : function_state_(function_state), |
351 old_value_(function_state->collect_expressions_in_tail_position()) { | 360 sav_return_expr_context_(function_state->return_expr_context()) { |
352 function_state->set_collect_expressions_in_tail_position(false); | 361 function_state->set_return_expr_context(return_expr_context); |
353 } | 362 } |
354 ~DontCollectExpressionsInTailPositionScope() { | 363 ~ReturnExprScope() { |
355 function_state_->set_collect_expressions_in_tail_position(old_value_); | 364 function_state_->set_return_expr_context(sav_return_expr_context_); |
356 } | 365 } |
357 | 366 |
358 private: | 367 private: |
359 FunctionState* function_state_; | 368 FunctionState* function_state_; |
360 bool old_value_; | 369 ReturnExprContext sav_return_expr_context_; |
361 }; | 370 }; |
362 | 371 |
363 // Collects all return expressions at tail call position in this scope | 372 // Collects all return expressions at tail call position in this scope |
364 // to a separate list. | 373 // to a separate list. |
365 class CollectExpressionsInTailPositionToListScope { | 374 class CollectExpressionsInTailPositionToListScope { |
366 public: | 375 public: |
367 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, | 376 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, |
368 List<TailCallExpression>* list) | 377 List<TailCallExpression>* list) |
369 : function_state_(function_state), list_(list) { | 378 : function_state_(function_state), list_(list) { |
370 function_state->expressions_in_tail_position().Swap(list_); | 379 function_state->expressions_in_tail_position().Swap(list_); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 Traits::ReportMessageAt(source_location, message, arg, error_type); | 635 Traits::ReportMessageAt(source_location, message, arg, error_type); |
627 } | 636 } |
628 | 637 |
629 void ReportMessageAt(Scanner::Location location, | 638 void ReportMessageAt(Scanner::Location location, |
630 MessageTemplate::Template message, | 639 MessageTemplate::Template message, |
631 ParseErrorType error_type = kSyntaxError) { | 640 ParseErrorType error_type = kSyntaxError) { |
632 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), | 641 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), |
633 error_type); | 642 error_type); |
634 } | 643 } |
635 | 644 |
| 645 void ReportIllegalTailCallAt(int pos, ReturnExprContext return_expr_context) { |
| 646 Scanner::Location loc(pos, pos + 1); |
| 647 MessageTemplate::Template msg = MessageTemplate::kNone; |
| 648 switch (return_expr_context) { |
| 649 case ReturnExprContext::kNormal: |
| 650 UNREACHABLE(); |
| 651 return; |
| 652 case ReturnExprContext::kInsideTryBlock: |
| 653 msg = MessageTemplate::kTailCallInTryBlock; |
| 654 break; |
| 655 case ReturnExprContext::kInsideForInOfBody: |
| 656 msg = MessageTemplate::kTailCallInForInOf; |
| 657 break; |
| 658 } |
| 659 ReportMessageAt(loc, msg); |
| 660 } |
| 661 |
636 void GetUnexpectedTokenMessage( | 662 void GetUnexpectedTokenMessage( |
637 Token::Value token, MessageTemplate::Template* message, | 663 Token::Value token, MessageTemplate::Template* message, |
638 Scanner::Location* location, const char** arg, | 664 Scanner::Location* location, const char** arg, |
639 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); | 665 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); |
640 | 666 |
641 void ReportUnexpectedToken(Token::Value token); | 667 void ReportUnexpectedToken(Token::Value token); |
642 void ReportUnexpectedTokenAt( | 668 void ReportUnexpectedTokenAt( |
643 Scanner::Location location, Token::Value token, | 669 Scanner::Location location, Token::Value token, |
644 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 670 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
645 | 671 |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 expected_property_count_(0), | 1009 expected_property_count_(0), |
984 this_location_(Scanner::Location::invalid()), | 1010 this_location_(Scanner::Location::invalid()), |
985 return_location_(Scanner::Location::invalid()), | 1011 return_location_(Scanner::Location::invalid()), |
986 super_location_(Scanner::Location::invalid()), | 1012 super_location_(Scanner::Location::invalid()), |
987 kind_(kind), | 1013 kind_(kind), |
988 generator_object_variable_(NULL), | 1014 generator_object_variable_(NULL), |
989 function_state_stack_(function_state_stack), | 1015 function_state_stack_(function_state_stack), |
990 outer_function_state_(*function_state_stack), | 1016 outer_function_state_(*function_state_stack), |
991 scope_stack_(scope_stack), | 1017 scope_stack_(scope_stack), |
992 outer_scope_(*scope_stack), | 1018 outer_scope_(*scope_stack), |
993 collect_expressions_in_tail_position_(true), | 1019 return_expr_context_(ReturnExprContext::kNormal), |
994 non_patterns_to_rewrite_(0, scope->zone()), | 1020 non_patterns_to_rewrite_(0, scope->zone()), |
995 factory_(factory), | 1021 factory_(factory), |
996 next_function_is_parenthesized_(false), | 1022 next_function_is_parenthesized_(false), |
997 this_function_is_parenthesized_(false) { | 1023 this_function_is_parenthesized_(false) { |
998 *scope_stack_ = scope; | 1024 *scope_stack_ = scope; |
999 *function_state_stack = this; | 1025 *function_state_stack = this; |
1000 if (outer_function_state_) { | 1026 if (outer_function_state_) { |
1001 this_function_is_parenthesized_ = | 1027 this_function_is_parenthesized_ = |
1002 outer_function_state_->next_function_is_parenthesized_; | 1028 outer_function_state_->next_function_is_parenthesized_; |
1003 outer_function_state_->next_function_is_parenthesized_ = false; | 1029 outer_function_state_->next_function_is_parenthesized_ = false; |
(...skipping 2177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3181 has_seen_constructor_ = true; | 3207 has_seen_constructor_ = true; |
3182 return; | 3208 return; |
3183 } | 3209 } |
3184 } | 3210 } |
3185 | 3211 |
3186 | 3212 |
3187 } // namespace internal | 3213 } // namespace internal |
3188 } // namespace v8 | 3214 } // namespace v8 |
3189 | 3215 |
3190 #endif // V8_PARSING_PARSER_BASE_H | 3216 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |