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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 | 183 |
184 struct DestructuringAssignment { | 184 struct DestructuringAssignment { |
185 public: | 185 public: |
186 DestructuringAssignment(ExpressionT expression, Scope* scope) | 186 DestructuringAssignment(ExpressionT expression, Scope* scope) |
187 : assignment(expression), scope(scope) {} | 187 : assignment(expression), scope(scope) {} |
188 | 188 |
189 ExpressionT assignment; | 189 ExpressionT assignment; |
190 Scope* scope; | 190 Scope* scope; |
191 }; | 191 }; |
192 | 192 |
193 struct TailCallExpression { | 193 class TailCallExpressionList { |
194 TailCallExpression(ExpressionT expression, int pos) | 194 public: |
195 : expression(expression), pos(pos) {} | 195 explicit TailCallExpressionList(Zone* zone) |
| 196 : zone_(zone), expressions_(0, zone) {} |
196 | 197 |
197 ExpressionT expression; | 198 const ZoneList<ExpressionT>& expressions() const { return expressions_; } |
198 int pos; | 199 const Scanner::Location& location() const { return loc_; } |
| 200 |
| 201 bool is_empty() const { return expressions_.is_empty(); } |
| 202 |
| 203 void Swap(TailCallExpressionList& other) { |
| 204 expressions_.Swap(&other.expressions_); |
| 205 std::swap(loc_, other.loc_); |
| 206 } |
| 207 |
| 208 void Add(ExpressionT expr, const Scanner::Location& loc) { |
| 209 if (expressions_.is_empty()) loc_ = loc; |
| 210 expressions_.Add(expr, zone_); |
| 211 } |
| 212 |
| 213 void Append(const TailCallExpressionList& other) { |
| 214 if (expressions_.is_empty()) loc_ = other.loc_; |
| 215 expressions_.AddAll(other.expressions_, zone_); |
| 216 } |
| 217 |
| 218 private: |
| 219 Zone* zone_; |
| 220 ZoneList<ExpressionT> expressions_; |
| 221 Scanner::Location loc_; |
199 }; | 222 }; |
200 | 223 |
201 // Defines whether tail call expressions are allowed or not. | 224 // Defines whether tail call expressions are allowed or not. |
202 enum class ReturnExprContext { | 225 enum class ReturnExprContext { |
203 // Tail call expressions are allowed. | 226 // We are inside return statement which is allowed to contain tail call |
204 kNormal, | 227 // expressions. Tail call expressions are allowed. |
205 // Tail call expressions are not allowed. | 228 kInsideValidReturnStatement, |
| 229 |
| 230 // We are inside a block in which tail call expressions are allowed but |
| 231 // not yet inside a return statement. |
| 232 kInsideValidBlock, |
| 233 |
| 234 // Tail call expressions are not allowed in the following blocks. |
206 kInsideTryBlock, | 235 kInsideTryBlock, |
207 kInsideForInOfBody, | 236 kInsideForInOfBody, |
208 }; | 237 }; |
209 | 238 |
210 class FunctionState BASE_EMBEDDED { | 239 class FunctionState BASE_EMBEDDED { |
211 public: | 240 public: |
212 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, | 241 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, |
213 Scope* scope, FunctionKind kind, | 242 Scope* scope, FunctionKind kind, |
214 typename Traits::Type::Factory* factory); | 243 typename Traits::Type::Factory* factory); |
215 ~FunctionState(); | 244 ~FunctionState(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 return generator_object_variable_; | 286 return generator_object_variable_; |
258 } | 287 } |
259 | 288 |
260 typename Traits::Type::Factory* factory() { return factory_; } | 289 typename Traits::Type::Factory* factory() { return factory_; } |
261 | 290 |
262 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 291 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
263 const { | 292 const { |
264 return destructuring_assignments_to_rewrite_; | 293 return destructuring_assignments_to_rewrite_; |
265 } | 294 } |
266 | 295 |
267 List<TailCallExpression>& expressions_in_tail_position() { | 296 TailCallExpressionList& tail_call_expressions() { |
268 return expressions_in_tail_position_; | 297 return tail_call_expressions_; |
269 } | 298 } |
270 void AddExpressionInTailPosition(ExpressionT expression, int pos) { | 299 void AddExpressionInTailPosition(ExpressionT expression, |
271 if (return_expr_context() == ReturnExprContext::kNormal) { | 300 const Scanner::Location& loc) { |
272 expressions_in_tail_position_.Add(TailCallExpression(expression, pos)); | 301 // If only FLAG_harmony_explicit_tailcalls is enabled then expression |
| 302 // must be a Call expression. |
| 303 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || |
| 304 expression->IsCall()); |
| 305 if (return_expr_context() == |
| 306 ReturnExprContext::kInsideValidReturnStatement) { |
| 307 tail_call_expressions_.Add(expression, loc); |
273 } | 308 } |
274 } | 309 } |
275 | 310 |
276 ReturnExprContext return_expr_context() const { | 311 ReturnExprContext return_expr_context() const { |
277 return return_expr_context_; | 312 return return_expr_context_; |
278 } | 313 } |
279 void set_return_expr_context(ReturnExprContext context) { | 314 void set_return_expr_context(ReturnExprContext context) { |
280 return_expr_context_ = context; | 315 return_expr_context_ = context; |
281 } | 316 } |
282 | 317 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 // is used by yield expressions and return statements. It is not necessary | 360 // is used by yield expressions and return statements. It is not necessary |
326 // for generator functions to have this variable set. | 361 // for generator functions to have this variable set. |
327 Variable* generator_object_variable_; | 362 Variable* generator_object_variable_; |
328 | 363 |
329 FunctionState** function_state_stack_; | 364 FunctionState** function_state_stack_; |
330 FunctionState* outer_function_state_; | 365 FunctionState* outer_function_state_; |
331 Scope** scope_stack_; | 366 Scope** scope_stack_; |
332 Scope* outer_scope_; | 367 Scope* outer_scope_; |
333 | 368 |
334 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; | 369 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
335 List<TailCallExpression> expressions_in_tail_position_; | 370 TailCallExpressionList tail_call_expressions_; |
336 ReturnExprContext return_expr_context_; | 371 ReturnExprContext return_expr_context_; |
337 ZoneList<ExpressionT> non_patterns_to_rewrite_; | 372 ZoneList<ExpressionT> non_patterns_to_rewrite_; |
338 | 373 |
339 typename Traits::Type::Factory* factory_; | 374 typename Traits::Type::Factory* factory_; |
340 | 375 |
341 // If true, the next (and immediately following) function literal is | 376 // If true, the next (and immediately following) function literal is |
342 // preceded by a parenthesis. | 377 // preceded by a parenthesis. |
343 bool next_function_is_parenthesized_; | 378 bool next_function_is_parenthesized_; |
344 | 379 |
345 // The value of the parents' next_function_is_parenthesized_, as it applies | 380 // The value of the parents' next_function_is_parenthesized_, as it applies |
346 // to this function. Filled in by constructor. | 381 // to this function. Filled in by constructor. |
347 bool this_function_is_parenthesized_; | 382 bool this_function_is_parenthesized_; |
348 | 383 |
349 friend class ParserTraits; | 384 friend class ParserTraits; |
350 friend class PreParserTraits; | 385 friend class PreParserTraits; |
351 friend class Checkpoint; | 386 friend class Checkpoint; |
352 }; | 387 }; |
353 | 388 |
354 // This scope sets current ReturnExprContext to given value. | 389 // This scope sets current ReturnExprContext to given value. |
355 class ReturnExprScope { | 390 class ReturnExprScope { |
356 public: | 391 public: |
357 explicit ReturnExprScope(FunctionState* function_state, | 392 explicit ReturnExprScope(FunctionState* function_state, |
358 ReturnExprContext return_expr_context) | 393 ReturnExprContext return_expr_context) |
359 : function_state_(function_state), | 394 : function_state_(function_state), |
360 sav_return_expr_context_(function_state->return_expr_context()) { | 395 sav_return_expr_context_(function_state->return_expr_context()) { |
361 function_state->set_return_expr_context(return_expr_context); | 396 // Don't update context if we are requested to enable tail call |
| 397 // expressions but current block does not allow them. |
| 398 if (return_expr_context != |
| 399 ReturnExprContext::kInsideValidReturnStatement || |
| 400 sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) { |
| 401 function_state->set_return_expr_context(return_expr_context); |
| 402 } |
362 } | 403 } |
363 ~ReturnExprScope() { | 404 ~ReturnExprScope() { |
364 function_state_->set_return_expr_context(sav_return_expr_context_); | 405 function_state_->set_return_expr_context(sav_return_expr_context_); |
365 } | 406 } |
366 | 407 |
367 private: | 408 private: |
368 FunctionState* function_state_; | 409 FunctionState* function_state_; |
369 ReturnExprContext sav_return_expr_context_; | 410 ReturnExprContext sav_return_expr_context_; |
370 }; | 411 }; |
371 | 412 |
372 // Collects all return expressions at tail call position in this scope | 413 // Collects all return expressions at tail call position in this scope |
373 // to a separate list. | 414 // to a separate list. |
374 class CollectExpressionsInTailPositionToListScope { | 415 class CollectExpressionsInTailPositionToListScope { |
375 public: | 416 public: |
376 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, | 417 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, |
377 List<TailCallExpression>* list) | 418 TailCallExpressionList* list) |
378 : function_state_(function_state), list_(list) { | 419 : function_state_(function_state), list_(list) { |
379 function_state->expressions_in_tail_position().Swap(list_); | 420 function_state->tail_call_expressions().Swap(*list_); |
380 } | 421 } |
381 ~CollectExpressionsInTailPositionToListScope() { | 422 ~CollectExpressionsInTailPositionToListScope() { |
382 function_state_->expressions_in_tail_position().Swap(list_); | 423 function_state_->tail_call_expressions().Swap(*list_); |
383 } | 424 } |
384 | 425 |
385 private: | 426 private: |
386 FunctionState* function_state_; | 427 FunctionState* function_state_; |
387 List<TailCallExpression>* list_; | 428 TailCallExpressionList* list_; |
388 }; | 429 }; |
389 | 430 |
390 // Annoyingly, arrow functions first parse as comma expressions, then when we | 431 // Annoyingly, arrow functions first parse as comma expressions, then when we |
391 // see the => we have to go back and reinterpret the arguments as being formal | 432 // see the => we have to go back and reinterpret the arguments as being formal |
392 // parameters. To do so we need to reset some of the parser state back to | 433 // parameters. To do so we need to reset some of the parser state back to |
393 // what it was before the arguments were first seen. | 434 // what it was before the arguments were first seen. |
394 class Checkpoint BASE_EMBEDDED { | 435 class Checkpoint BASE_EMBEDDED { |
395 public: | 436 public: |
396 explicit Checkpoint(ParserBase* parser) { | 437 explicit Checkpoint(ParserBase* parser) { |
397 function_state_ = parser->function_state_; | 438 function_state_ = parser->function_state_; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 Traits::ReportMessageAt(source_location, message, arg, error_type); | 676 Traits::ReportMessageAt(source_location, message, arg, error_type); |
636 } | 677 } |
637 | 678 |
638 void ReportMessageAt(Scanner::Location location, | 679 void ReportMessageAt(Scanner::Location location, |
639 MessageTemplate::Template message, | 680 MessageTemplate::Template message, |
640 ParseErrorType error_type = kSyntaxError) { | 681 ParseErrorType error_type = kSyntaxError) { |
641 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), | 682 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), |
642 error_type); | 683 error_type); |
643 } | 684 } |
644 | 685 |
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 | |
662 void GetUnexpectedTokenMessage( | 686 void GetUnexpectedTokenMessage( |
663 Token::Value token, MessageTemplate::Template* message, | 687 Token::Value token, MessageTemplate::Template* message, |
664 Scanner::Location* location, const char** arg, | 688 Scanner::Location* location, const char** arg, |
665 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); | 689 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); |
666 | 690 |
667 void ReportUnexpectedToken(Token::Value token); | 691 void ReportUnexpectedToken(Token::Value token); |
668 void ReportUnexpectedTokenAt( | 692 void ReportUnexpectedTokenAt( |
669 Scanner::Location location, Token::Value token, | 693 Scanner::Location location, Token::Value token, |
670 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 694 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
671 | 695 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 } | 776 } |
753 } | 777 } |
754 | 778 |
755 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 779 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { |
756 if (!classifier->is_valid_let_pattern()) { | 780 if (!classifier->is_valid_let_pattern()) { |
757 ReportClassifierError(classifier->let_pattern_error()); | 781 ReportClassifierError(classifier->let_pattern_error()); |
758 *ok = false; | 782 *ok = false; |
759 } | 783 } |
760 } | 784 } |
761 | 785 |
| 786 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier, |
| 787 bool* ok) { |
| 788 if (FLAG_harmony_explicit_tailcalls && |
| 789 classifier->has_tail_call_expression()) { |
| 790 ReportClassifierError(classifier->tail_call_expression_error()); |
| 791 *ok = false; |
| 792 } |
| 793 } |
| 794 |
762 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { | 795 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { |
763 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 796 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
764 const char* arg; | 797 const char* arg; |
765 Scanner::Location location = scanner()->peek_location(); | 798 Scanner::Location location = scanner()->peek_location(); |
766 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 799 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
767 classifier->RecordExpressionError(location, message, arg); | 800 classifier->RecordExpressionError(location, message, arg); |
768 } | 801 } |
769 | 802 |
770 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { | 803 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { |
771 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 804 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 871 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
839 typename Traits::Type::ExpressionList ParseArguments( | 872 typename Traits::Type::ExpressionList ParseArguments( |
840 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 873 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
841 bool* ok); | 874 bool* ok); |
842 | 875 |
843 ExpressionT ParseAssignmentExpression(bool accept_IN, | 876 ExpressionT ParseAssignmentExpression(bool accept_IN, |
844 ExpressionClassifier* classifier, | 877 ExpressionClassifier* classifier, |
845 bool* ok); | 878 bool* ok); |
846 ExpressionT ParseYieldExpression(bool accept_IN, | 879 ExpressionT ParseYieldExpression(bool accept_IN, |
847 ExpressionClassifier* classifier, bool* ok); | 880 ExpressionClassifier* classifier, bool* ok); |
| 881 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, |
| 882 bool* ok); |
848 ExpressionT ParseConditionalExpression(bool accept_IN, | 883 ExpressionT ParseConditionalExpression(bool accept_IN, |
849 ExpressionClassifier* classifier, | 884 ExpressionClassifier* classifier, |
850 bool* ok); | 885 bool* ok); |
851 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 886 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
852 ExpressionClassifier* classifier, bool* ok); | 887 ExpressionClassifier* classifier, bool* ok); |
853 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 888 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
854 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 889 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
855 bool* ok); | 890 bool* ok); |
856 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 891 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
857 bool* ok); | 892 bool* ok); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 expected_property_count_(0), | 1044 expected_property_count_(0), |
1010 this_location_(Scanner::Location::invalid()), | 1045 this_location_(Scanner::Location::invalid()), |
1011 return_location_(Scanner::Location::invalid()), | 1046 return_location_(Scanner::Location::invalid()), |
1012 super_location_(Scanner::Location::invalid()), | 1047 super_location_(Scanner::Location::invalid()), |
1013 kind_(kind), | 1048 kind_(kind), |
1014 generator_object_variable_(NULL), | 1049 generator_object_variable_(NULL), |
1015 function_state_stack_(function_state_stack), | 1050 function_state_stack_(function_state_stack), |
1016 outer_function_state_(*function_state_stack), | 1051 outer_function_state_(*function_state_stack), |
1017 scope_stack_(scope_stack), | 1052 scope_stack_(scope_stack), |
1018 outer_scope_(*scope_stack), | 1053 outer_scope_(*scope_stack), |
1019 return_expr_context_(ReturnExprContext::kNormal), | 1054 tail_call_expressions_(scope->zone()), |
| 1055 return_expr_context_(ReturnExprContext::kInsideValidBlock), |
1020 non_patterns_to_rewrite_(0, scope->zone()), | 1056 non_patterns_to_rewrite_(0, scope->zone()), |
1021 factory_(factory), | 1057 factory_(factory), |
1022 next_function_is_parenthesized_(false), | 1058 next_function_is_parenthesized_(false), |
1023 this_function_is_parenthesized_(false) { | 1059 this_function_is_parenthesized_(false) { |
1024 *scope_stack_ = scope; | 1060 *scope_stack_ = scope; |
1025 *function_state_stack = this; | 1061 *function_state_stack = this; |
1026 if (outer_function_state_) { | 1062 if (outer_function_state_) { |
1027 this_function_is_parenthesized_ = | 1063 this_function_is_parenthesized_ = |
1028 outer_function_state_->next_function_is_parenthesized_; | 1064 outer_function_state_->next_function_is_parenthesized_; |
1029 outer_function_state_->next_function_is_parenthesized_ = false; | 1065 outer_function_state_->next_function_is_parenthesized_ = false; |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1449 | 1485 |
1450 template <class Traits> | 1486 template <class Traits> |
1451 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1487 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
1452 bool accept_IN, bool* ok) { | 1488 bool accept_IN, bool* ok) { |
1453 ExpressionClassifier classifier(this); | 1489 ExpressionClassifier classifier(this); |
1454 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1490 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
1455 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 1491 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
1456 return result; | 1492 return result; |
1457 } | 1493 } |
1458 | 1494 |
1459 | |
1460 template <class Traits> | 1495 template <class Traits> |
1461 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1496 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
1462 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1497 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
1463 // Expression :: | 1498 // Expression :: |
1464 // AssignmentExpression | 1499 // AssignmentExpression |
1465 // Expression ',' AssignmentExpression | 1500 // Expression ',' AssignmentExpression |
1466 | 1501 |
1467 ExpressionClassifier binding_classifier(this); | 1502 ExpressionClassifier binding_classifier(this); |
1468 ExpressionT result = | 1503 ExpressionT result = |
1469 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 1504 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
1470 classifier->Accumulate(&binding_classifier, | 1505 classifier->Accumulate(&binding_classifier, |
1471 ExpressionClassifier::AllProductions); | 1506 ExpressionClassifier::AllProductions); |
1472 bool is_simple_parameter_list = this->IsIdentifier(result); | 1507 bool is_simple_parameter_list = this->IsIdentifier(result); |
1473 bool seen_rest = false; | 1508 bool seen_rest = false; |
1474 while (peek() == Token::COMMA) { | 1509 while (peek() == Token::COMMA) { |
| 1510 CheckNoTailCallExpressions(classifier, CHECK_OK); |
1475 if (seen_rest) { | 1511 if (seen_rest) { |
1476 // At this point the production can't possibly be valid, but we don't know | 1512 // At this point the production can't possibly be valid, but we don't know |
1477 // which error to signal. | 1513 // which error to signal. |
1478 classifier->RecordArrowFormalParametersError( | 1514 classifier->RecordArrowFormalParametersError( |
1479 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 1515 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
1480 } | 1516 } |
1481 Consume(Token::COMMA); | 1517 Consume(Token::COMMA); |
1482 bool is_rest = false; | 1518 bool is_rest = false; |
1483 if (peek() == Token::ELLIPSIS) { | 1519 if (peek() == Token::ELLIPSIS) { |
1484 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1520 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1528 while (peek() != Token::RBRACK) { | 1564 while (peek() != Token::RBRACK) { |
1529 ExpressionT elem = this->EmptyExpression(); | 1565 ExpressionT elem = this->EmptyExpression(); |
1530 if (peek() == Token::COMMA) { | 1566 if (peek() == Token::COMMA) { |
1531 elem = this->GetLiteralTheHole(peek_position(), factory()); | 1567 elem = this->GetLiteralTheHole(peek_position(), factory()); |
1532 } else if (peek() == Token::ELLIPSIS) { | 1568 } else if (peek() == Token::ELLIPSIS) { |
1533 int start_pos = peek_position(); | 1569 int start_pos = peek_position(); |
1534 Consume(Token::ELLIPSIS); | 1570 Consume(Token::ELLIPSIS); |
1535 int expr_pos = peek_position(); | 1571 int expr_pos = peek_position(); |
1536 ExpressionT argument = | 1572 ExpressionT argument = |
1537 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1573 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 1574 CheckNoTailCallExpressions(classifier, CHECK_OK); |
1538 elem = factory()->NewSpread(argument, start_pos, expr_pos); | 1575 elem = factory()->NewSpread(argument, start_pos, expr_pos); |
1539 | 1576 |
1540 if (first_spread_index < 0) { | 1577 if (first_spread_index < 0) { |
1541 first_spread_index = values->length(); | 1578 first_spread_index = values->length(); |
1542 } | 1579 } |
1543 | 1580 |
1544 if (argument->IsAssignment()) { | 1581 if (argument->IsAssignment()) { |
1545 classifier->RecordPatternError( | 1582 classifier->RecordPatternError( |
1546 Scanner::Location(start_pos, scanner()->location().end_pos), | 1583 Scanner::Location(start_pos, scanner()->location().end_pos), |
1547 MessageTemplate::kInvalidDestructuringTarget); | 1584 MessageTemplate::kInvalidDestructuringTarget); |
1548 } else { | 1585 } else { |
1549 CheckDestructuringElement(argument, classifier, start_pos, | 1586 CheckDestructuringElement(argument, classifier, start_pos, |
1550 scanner()->location().end_pos); | 1587 scanner()->location().end_pos); |
1551 } | 1588 } |
1552 | 1589 |
1553 if (peek() == Token::COMMA) { | 1590 if (peek() == Token::COMMA) { |
1554 classifier->RecordPatternError( | 1591 classifier->RecordPatternError( |
1555 Scanner::Location(start_pos, scanner()->location().end_pos), | 1592 Scanner::Location(start_pos, scanner()->location().end_pos), |
1556 MessageTemplate::kElementAfterRest); | 1593 MessageTemplate::kElementAfterRest); |
1557 } | 1594 } |
1558 } else { | 1595 } else { |
1559 int beg_pos = peek_position(); | 1596 int beg_pos = peek_position(); |
1560 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1597 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 1598 CheckNoTailCallExpressions(classifier, CHECK_OK); |
1561 CheckDestructuringElement(elem, classifier, beg_pos, | 1599 CheckDestructuringElement(elem, classifier, beg_pos, |
1562 scanner()->location().end_pos); | 1600 scanner()->location().end_pos); |
1563 } | 1601 } |
1564 values->Add(elem, zone_); | 1602 values->Add(elem, zone_); |
1565 if (peek() != Token::RBRACK) { | 1603 if (peek() != Token::RBRACK) { |
1566 Expect(Token::COMMA, CHECK_OK); | 1604 Expect(Token::COMMA, CHECK_OK); |
1567 } | 1605 } |
1568 } | 1606 } |
1569 Expect(Token::RBRACK, CHECK_OK); | 1607 Expect(Token::RBRACK, CHECK_OK); |
1570 | 1608 |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1898 bool done = (peek() == Token::RPAREN); | 1936 bool done = (peek() == Token::RPAREN); |
1899 bool was_unspread = false; | 1937 bool was_unspread = false; |
1900 int unspread_sequences_count = 0; | 1938 int unspread_sequences_count = 0; |
1901 while (!done) { | 1939 while (!done) { |
1902 int start_pos = peek_position(); | 1940 int start_pos = peek_position(); |
1903 bool is_spread = Check(Token::ELLIPSIS); | 1941 bool is_spread = Check(Token::ELLIPSIS); |
1904 int expr_pos = peek_position(); | 1942 int expr_pos = peek_position(); |
1905 | 1943 |
1906 ExpressionT argument = this->ParseAssignmentExpression( | 1944 ExpressionT argument = this->ParseAssignmentExpression( |
1907 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 1945 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1946 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
1908 Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 1947 Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
1909 if (is_spread) { | 1948 if (is_spread) { |
1910 if (!spread_arg.IsValid()) { | 1949 if (!spread_arg.IsValid()) { |
1911 spread_arg.beg_pos = start_pos; | 1950 spread_arg.beg_pos = start_pos; |
1912 spread_arg.end_pos = peek_position(); | 1951 spread_arg.end_pos = peek_position(); |
1913 } | 1952 } |
1914 argument = factory()->NewSpread(argument, start_pos, expr_pos); | 1953 argument = factory()->NewSpread(argument, start_pos, expr_pos); |
1915 } | 1954 } |
1916 result->Add(argument, zone_); | 1955 result->Add(argument, zone_); |
1917 | 1956 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1956 template <class Traits> | 1995 template <class Traits> |
1957 typename ParserBase<Traits>::ExpressionT | 1996 typename ParserBase<Traits>::ExpressionT |
1958 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 1997 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
1959 ExpressionClassifier* classifier, | 1998 ExpressionClassifier* classifier, |
1960 bool* ok) { | 1999 bool* ok) { |
1961 // AssignmentExpression :: | 2000 // AssignmentExpression :: |
1962 // ConditionalExpression | 2001 // ConditionalExpression |
1963 // ArrowFunction | 2002 // ArrowFunction |
1964 // YieldExpression | 2003 // YieldExpression |
1965 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2004 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1966 // TailCallExpression | |
1967 bool is_destructuring_assignment = false; | 2005 bool is_destructuring_assignment = false; |
1968 int lhs_beg_pos = peek_position(); | 2006 int lhs_beg_pos = peek_position(); |
1969 | 2007 |
1970 if (peek() == Token::YIELD && is_generator()) { | 2008 if (peek() == Token::YIELD && is_generator()) { |
1971 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2009 return this->ParseYieldExpression(accept_IN, classifier, ok); |
1972 } | 2010 } |
1973 | 2011 |
1974 FuncNameInferrer::State fni_state(fni_); | 2012 FuncNameInferrer::State fni_state(fni_); |
1975 ParserBase<Traits>::Checkpoint checkpoint(this); | 2013 ParserBase<Traits>::Checkpoint checkpoint(this); |
1976 ExpressionClassifier arrow_formals_classifier(this, | 2014 ExpressionClassifier arrow_formals_classifier(this, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2035 if (!Token::IsAssignmentOp(peek())) { | 2073 if (!Token::IsAssignmentOp(peek())) { |
2036 // Parsed conditional expression only (no assignment). | 2074 // Parsed conditional expression only (no assignment). |
2037 // Now pending non-pattern expressions must be merged. | 2075 // Now pending non-pattern expressions must be merged. |
2038 classifier->MergeNonPatterns(&arrow_formals_classifier); | 2076 classifier->MergeNonPatterns(&arrow_formals_classifier); |
2039 return expression; | 2077 return expression; |
2040 } | 2078 } |
2041 | 2079 |
2042 // Now pending non-pattern expressions must be discarded. | 2080 // Now pending non-pattern expressions must be discarded. |
2043 arrow_formals_classifier.Discard(); | 2081 arrow_formals_classifier.Discard(); |
2044 | 2082 |
| 2083 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2084 |
2045 if (IsValidPattern(expression) && peek() == Token::ASSIGN) { | 2085 if (IsValidPattern(expression) && peek() == Token::ASSIGN) { |
2046 classifier->ForgiveCoverInitializedNameError(); | 2086 classifier->ForgiveCoverInitializedNameError(); |
2047 ValidateAssignmentPattern(classifier, CHECK_OK); | 2087 ValidateAssignmentPattern(classifier, CHECK_OK); |
2048 is_destructuring_assignment = true; | 2088 is_destructuring_assignment = true; |
2049 } else { | 2089 } else { |
2050 expression = this->CheckAndRewriteReferenceExpression( | 2090 expression = this->CheckAndRewriteReferenceExpression( |
2051 expression, lhs_beg_pos, scanner()->location().end_pos, | 2091 expression, lhs_beg_pos, scanner()->location().end_pos, |
2052 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 2092 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
2053 } | 2093 } |
2054 | 2094 |
2055 expression = this->MarkExpressionAsAssigned(expression); | 2095 expression = this->MarkExpressionAsAssigned(expression); |
2056 | 2096 |
2057 Token::Value op = Next(); // Get assignment operator. | 2097 Token::Value op = Next(); // Get assignment operator. |
2058 if (op != Token::ASSIGN) { | 2098 if (op != Token::ASSIGN) { |
2059 classifier->RecordPatternError(scanner()->location(), | 2099 classifier->RecordPatternError(scanner()->location(), |
2060 MessageTemplate::kUnexpectedToken, | 2100 MessageTemplate::kUnexpectedToken, |
2061 Token::String(op)); | 2101 Token::String(op)); |
2062 } | 2102 } |
2063 int pos = position(); | 2103 int pos = position(); |
2064 | 2104 |
2065 ExpressionClassifier rhs_classifier(this); | 2105 ExpressionClassifier rhs_classifier(this); |
2066 | 2106 |
2067 ExpressionT right = | 2107 ExpressionT right = |
2068 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2108 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); |
| 2109 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); |
2069 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); | 2110 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); |
2070 classifier->Accumulate( | 2111 classifier->Accumulate( |
2071 &rhs_classifier, ExpressionClassifier::ExpressionProductions | | 2112 &rhs_classifier, ExpressionClassifier::ExpressionProductions | |
2072 ExpressionClassifier::CoverInitializedNameProduction); | 2113 ExpressionClassifier::CoverInitializedNameProduction); |
2073 | 2114 |
2074 // TODO(1231235): We try to estimate the set of properties set by | 2115 // TODO(1231235): We try to estimate the set of properties set by |
2075 // constructors. We define a new property whenever there is an | 2116 // constructors. We define a new property whenever there is an |
2076 // assignment to a property of 'this'. We should probably only add | 2117 // assignment to a property of 'this'. We should probably only add |
2077 // properties if we haven't seen them before. Otherwise we'll | 2118 // properties if we haven't seen them before. Otherwise we'll |
2078 // probably overestimate the number of properties. | 2119 // probably overestimate the number of properties. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2157 } | 2198 } |
2158 | 2199 |
2159 expression = Traits::BuildIteratorResult(expression, false); | 2200 expression = Traits::BuildIteratorResult(expression, false); |
2160 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2201 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
2161 // TODO(verwaest): Come up with a better solution. | 2202 // TODO(verwaest): Come up with a better solution. |
2162 typename Traits::Type::YieldExpression yield = | 2203 typename Traits::Type::YieldExpression yield = |
2163 factory()->NewYield(generator_object, expression, pos); | 2204 factory()->NewYield(generator_object, expression, pos); |
2164 return yield; | 2205 return yield; |
2165 } | 2206 } |
2166 | 2207 |
| 2208 template <class Traits> |
| 2209 typename ParserBase<Traits>::ExpressionT |
| 2210 ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier, |
| 2211 bool* ok) { |
| 2212 // TailCallExpression:: |
| 2213 // 'continue' MemberExpression Arguments |
| 2214 // 'continue' CallExpression Arguments |
| 2215 // 'continue' MemberExpression TemplateLiteral |
| 2216 // 'continue' CallExpression TemplateLiteral |
| 2217 Expect(Token::CONTINUE, CHECK_OK); |
| 2218 int pos = position(); |
| 2219 int sub_expression_pos = peek_position(); |
| 2220 ExpressionT expression = |
| 2221 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
| 2222 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2223 |
| 2224 Scanner::Location loc(pos, scanner()->location().end_pos); |
| 2225 ReturnExprContext return_expr_context = |
| 2226 function_state_->return_expr_context(); |
| 2227 if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) { |
| 2228 MessageTemplate::Template msg = MessageTemplate::kNone; |
| 2229 switch (return_expr_context) { |
| 2230 case ReturnExprContext::kInsideValidReturnStatement: |
| 2231 UNREACHABLE(); |
| 2232 return Traits::EmptyExpression(); |
| 2233 case ReturnExprContext::kInsideValidBlock: |
| 2234 msg = MessageTemplate::kUnexpectedTailCall; |
| 2235 break; |
| 2236 case ReturnExprContext::kInsideTryBlock: |
| 2237 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; |
| 2238 break; |
| 2239 case ReturnExprContext::kInsideForInOfBody: |
| 2240 msg = MessageTemplate::kUnexpectedTailCallInForInOf; |
| 2241 break; |
| 2242 } |
| 2243 ReportMessageAt(loc, msg); |
| 2244 *ok = false; |
| 2245 return Traits::EmptyExpression(); |
| 2246 } |
| 2247 if (!expression->IsCall()) { |
| 2248 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); |
| 2249 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedInsideTailCall); |
| 2250 *ok = false; |
| 2251 return Traits::EmptyExpression(); |
| 2252 } |
| 2253 classifier->RecordTailCallExpressionError( |
| 2254 loc, MessageTemplate::kUnexpectedTailCall); |
| 2255 function_state_->AddExpressionInTailPosition(expression, loc); |
| 2256 return expression; |
| 2257 } |
2167 | 2258 |
2168 // Precedence = 3 | 2259 // Precedence = 3 |
2169 template <class Traits> | 2260 template <class Traits> |
2170 typename ParserBase<Traits>::ExpressionT | 2261 typename ParserBase<Traits>::ExpressionT |
2171 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, | 2262 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, |
2172 ExpressionClassifier* classifier, | 2263 ExpressionClassifier* classifier, |
2173 bool* ok) { | 2264 bool* ok) { |
2174 // ConditionalExpression :: | 2265 // ConditionalExpression :: |
2175 // LogicalOrExpression | 2266 // LogicalOrExpression |
2176 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2267 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
2177 | 2268 |
2178 int pos = peek_position(); | 2269 int pos = peek_position(); |
2179 // We start using the binary expression parser for prec >= 4 only! | 2270 // We start using the binary expression parser for prec >= 4 only! |
2180 ExpressionT expression = | 2271 ExpressionT expression = |
2181 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | 2272 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); |
2182 if (peek() != Token::CONDITIONAL) return expression; | 2273 if (peek() != Token::CONDITIONAL) return expression; |
| 2274 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2183 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2275 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2184 ArrowFormalParametersUnexpectedToken(classifier); | 2276 ArrowFormalParametersUnexpectedToken(classifier); |
2185 BindingPatternUnexpectedToken(classifier); | 2277 BindingPatternUnexpectedToken(classifier); |
2186 Consume(Token::CONDITIONAL); | 2278 Consume(Token::CONDITIONAL); |
2187 // In parsing the first assignment expression in conditional | 2279 // In parsing the first assignment expression in conditional |
2188 // expressions we always accept the 'in' keyword; see ECMA-262, | 2280 // expressions we always accept the 'in' keyword; see ECMA-262, |
2189 // section 11.12, page 58. | 2281 // section 11.12, page 58. |
2190 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 2282 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); |
2191 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2283 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2192 Expect(Token::COLON, CHECK_OK); | 2284 Expect(Token::COLON, CHECK_OK); |
2193 ExpressionT right = | 2285 ExpressionT right = |
2194 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2286 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2195 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2287 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2196 return factory()->NewConditional(expression, left, right, pos); | 2288 return factory()->NewConditional(expression, left, right, pos); |
2197 } | 2289 } |
2198 | 2290 |
2199 | 2291 |
2200 // Precedence >= 4 | 2292 // Precedence >= 4 |
2201 template <class Traits> | 2293 template <class Traits> |
2202 typename ParserBase<Traits>::ExpressionT | 2294 typename ParserBase<Traits>::ExpressionT |
2203 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, | 2295 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
2204 ExpressionClassifier* classifier, | 2296 ExpressionClassifier* classifier, |
2205 bool* ok) { | 2297 bool* ok) { |
2206 DCHECK(prec >= 4); | 2298 DCHECK(prec >= 4); |
2207 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 2299 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
2208 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2300 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2209 // prec1 >= 4 | 2301 // prec1 >= 4 |
2210 while (Precedence(peek(), accept_IN) == prec1) { | 2302 while (Precedence(peek(), accept_IN) == prec1) { |
| 2303 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2211 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2304 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2212 BindingPatternUnexpectedToken(classifier); | 2305 BindingPatternUnexpectedToken(classifier); |
2213 ArrowFormalParametersUnexpectedToken(classifier); | 2306 ArrowFormalParametersUnexpectedToken(classifier); |
2214 Token::Value op = Next(); | 2307 Token::Value op = Next(); |
2215 int pos = position(); | 2308 int pos = position(); |
2216 | 2309 |
2217 const bool is_right_associative = op == Token::EXP; | 2310 const bool is_right_associative = op == Token::EXP; |
2218 const int next_prec = is_right_associative ? prec1 : prec1 + 1; | 2311 const int next_prec = is_right_associative ? prec1 : prec1 + 1; |
2219 ExpressionT y = | 2312 ExpressionT y = |
2220 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); | 2313 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); |
| 2314 if (op != Token::OR && op != Token::AND) { |
| 2315 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2316 } |
2221 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2317 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2222 | 2318 |
2223 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2319 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
2224 factory())) { | 2320 factory())) { |
2225 continue; | 2321 continue; |
2226 } | 2322 } |
2227 | 2323 |
2228 // For now we distinguish between comparisons and other binary | 2324 // For now we distinguish between comparisons and other binary |
2229 // operations. (We could combine the two and get rid of this | 2325 // operations. (We could combine the two and get rid of this |
2230 // code and AST node eventually.) | 2326 // code and AST node eventually.) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2275 // '!' UnaryExpression | 2371 // '!' UnaryExpression |
2276 | 2372 |
2277 Token::Value op = peek(); | 2373 Token::Value op = peek(); |
2278 if (Token::IsUnaryOp(op)) { | 2374 if (Token::IsUnaryOp(op)) { |
2279 BindingPatternUnexpectedToken(classifier); | 2375 BindingPatternUnexpectedToken(classifier); |
2280 ArrowFormalParametersUnexpectedToken(classifier); | 2376 ArrowFormalParametersUnexpectedToken(classifier); |
2281 | 2377 |
2282 op = Next(); | 2378 op = Next(); |
2283 int pos = position(); | 2379 int pos = position(); |
2284 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2380 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 2381 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2285 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2382 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2286 | 2383 |
2287 if (op == Token::DELETE && is_strict(language_mode())) { | 2384 if (op == Token::DELETE && is_strict(language_mode())) { |
2288 if (this->IsIdentifier(expression)) { | 2385 if (this->IsIdentifier(expression)) { |
2289 // "delete identifier" is a syntax error in strict mode. | 2386 // "delete identifier" is a syntax error in strict mode. |
2290 ReportMessage(MessageTemplate::kStrictDelete); | 2387 ReportMessage(MessageTemplate::kStrictDelete); |
2291 *ok = false; | 2388 *ok = false; |
2292 return this->EmptyExpression(); | 2389 return this->EmptyExpression(); |
2293 } | 2390 } |
2294 } | 2391 } |
2295 | 2392 |
2296 if (peek() == Token::EXP) { | 2393 if (peek() == Token::EXP) { |
2297 ReportUnexpectedToken(Next()); | 2394 ReportUnexpectedToken(Next()); |
2298 *ok = false; | 2395 *ok = false; |
2299 return this->EmptyExpression(); | 2396 return this->EmptyExpression(); |
2300 } | 2397 } |
2301 | 2398 |
2302 // Allow Traits do rewrite the expression. | 2399 // Allow Traits do rewrite the expression. |
2303 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2400 return this->BuildUnaryExpression(expression, op, pos, factory()); |
2304 } else if (Token::IsCountOp(op)) { | 2401 } else if (Token::IsCountOp(op)) { |
2305 BindingPatternUnexpectedToken(classifier); | 2402 BindingPatternUnexpectedToken(classifier); |
2306 ArrowFormalParametersUnexpectedToken(classifier); | 2403 ArrowFormalParametersUnexpectedToken(classifier); |
2307 op = Next(); | 2404 op = Next(); |
2308 int beg_pos = peek_position(); | 2405 int beg_pos = peek_position(); |
2309 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 2406 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 2407 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2310 expression = this->CheckAndRewriteReferenceExpression( | 2408 expression = this->CheckAndRewriteReferenceExpression( |
2311 expression, beg_pos, scanner()->location().end_pos, | 2409 expression, beg_pos, scanner()->location().end_pos, |
2312 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2410 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
2313 this->MarkExpressionAsAssigned(expression); | 2411 this->MarkExpressionAsAssigned(expression); |
2314 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2412 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2315 | 2413 |
2316 return factory()->NewCountOperation(op, | 2414 return factory()->NewCountOperation(op, |
2317 true /* prefix */, | 2415 true /* prefix */, |
2318 expression, | 2416 expression, |
2319 position()); | 2417 position()); |
2320 | 2418 |
2321 } else { | 2419 } else { |
2322 return this->ParsePostfixExpression(classifier, ok); | 2420 return this->ParsePostfixExpression(classifier, ok); |
2323 } | 2421 } |
2324 } | 2422 } |
2325 | 2423 |
2326 | 2424 |
2327 template <class Traits> | 2425 template <class Traits> |
2328 typename ParserBase<Traits>::ExpressionT | 2426 typename ParserBase<Traits>::ExpressionT |
2329 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 2427 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
2330 bool* ok) { | 2428 bool* ok) { |
2331 // PostfixExpression :: | 2429 // PostfixExpression :: |
2332 // LeftHandSideExpression ('++' | '--')? | 2430 // LeftHandSideExpression ('++' | '--')? |
2333 | 2431 |
2334 int lhs_beg_pos = peek_position(); | 2432 int lhs_beg_pos = peek_position(); |
2335 ExpressionT expression = | 2433 ExpressionT expression = |
2336 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 2434 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
2337 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2435 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2338 Token::IsCountOp(peek())) { | 2436 Token::IsCountOp(peek())) { |
| 2437 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2339 BindingPatternUnexpectedToken(classifier); | 2438 BindingPatternUnexpectedToken(classifier); |
2340 ArrowFormalParametersUnexpectedToken(classifier); | 2439 ArrowFormalParametersUnexpectedToken(classifier); |
2341 | 2440 |
2342 expression = this->CheckAndRewriteReferenceExpression( | 2441 expression = this->CheckAndRewriteReferenceExpression( |
2343 expression, lhs_beg_pos, scanner()->location().end_pos, | 2442 expression, lhs_beg_pos, scanner()->location().end_pos, |
2344 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); | 2443 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); |
2345 expression = this->MarkExpressionAsAssigned(expression); | 2444 expression = this->MarkExpressionAsAssigned(expression); |
2346 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2445 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2347 | 2446 |
2348 Token::Value next = Next(); | 2447 Token::Value next = Next(); |
2349 expression = | 2448 expression = |
2350 factory()->NewCountOperation(next, | 2449 factory()->NewCountOperation(next, |
2351 false /* postfix */, | 2450 false /* postfix */, |
2352 expression, | 2451 expression, |
2353 position()); | 2452 position()); |
2354 } | 2453 } |
2355 return expression; | 2454 return expression; |
2356 } | 2455 } |
2357 | 2456 |
2358 | |
2359 template <class Traits> | 2457 template <class Traits> |
2360 typename ParserBase<Traits>::ExpressionT | 2458 typename ParserBase<Traits>::ExpressionT |
2361 ParserBase<Traits>::ParseLeftHandSideExpression( | 2459 ParserBase<Traits>::ParseLeftHandSideExpression( |
2362 ExpressionClassifier* classifier, bool* ok) { | 2460 ExpressionClassifier* classifier, bool* ok) { |
2363 // LeftHandSideExpression :: | 2461 // LeftHandSideExpression :: |
2364 // (NewExpression | MemberExpression) ... | 2462 // (NewExpression | MemberExpression) ... |
2365 | 2463 |
| 2464 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { |
| 2465 return this->ParseTailCallExpression(classifier, ok); |
| 2466 } |
| 2467 |
2366 ExpressionT result = | 2468 ExpressionT result = |
2367 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2469 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
2368 | 2470 |
2369 while (true) { | 2471 while (true) { |
2370 switch (peek()) { | 2472 switch (peek()) { |
2371 case Token::LBRACK: { | 2473 case Token::LBRACK: { |
| 2474 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2372 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2475 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2373 BindingPatternUnexpectedToken(classifier); | 2476 BindingPatternUnexpectedToken(classifier); |
2374 ArrowFormalParametersUnexpectedToken(classifier); | 2477 ArrowFormalParametersUnexpectedToken(classifier); |
2375 Consume(Token::LBRACK); | 2478 Consume(Token::LBRACK); |
2376 int pos = position(); | 2479 int pos = position(); |
2377 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2480 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
2378 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2481 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2379 result = factory()->NewProperty(result, index, pos); | 2482 result = factory()->NewProperty(result, index, pos); |
2380 Expect(Token::RBRACK, CHECK_OK); | 2483 Expect(Token::RBRACK, CHECK_OK); |
2381 break; | 2484 break; |
2382 } | 2485 } |
2383 | 2486 |
2384 case Token::LPAREN: { | 2487 case Token::LPAREN: { |
| 2488 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2385 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2489 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2386 BindingPatternUnexpectedToken(classifier); | 2490 BindingPatternUnexpectedToken(classifier); |
2387 ArrowFormalParametersUnexpectedToken(classifier); | 2491 ArrowFormalParametersUnexpectedToken(classifier); |
2388 | 2492 |
2389 int pos; | 2493 int pos; |
2390 if (scanner()->current_token() == Token::IDENTIFIER || | 2494 if (scanner()->current_token() == Token::IDENTIFIER || |
2391 scanner()->current_token() == Token::SUPER) { | 2495 scanner()->current_token() == Token::SUPER) { |
2392 // For call of an identifier we want to report position of | 2496 // For call of an identifier we want to report position of |
2393 // the identifier as position of the call in the stack trace. | 2497 // the identifier as position of the call in the stack trace. |
2394 pos = position(); | 2498 pos = position(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2433 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | 2537 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); |
2434 result = | 2538 result = |
2435 factory()->NewAssignment(Token::INIT, this_expr, result, pos); | 2539 factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
2436 } | 2540 } |
2437 | 2541 |
2438 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2542 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2439 break; | 2543 break; |
2440 } | 2544 } |
2441 | 2545 |
2442 case Token::PERIOD: { | 2546 case Token::PERIOD: { |
| 2547 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2443 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2548 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2444 BindingPatternUnexpectedToken(classifier); | 2549 BindingPatternUnexpectedToken(classifier); |
2445 ArrowFormalParametersUnexpectedToken(classifier); | 2550 ArrowFormalParametersUnexpectedToken(classifier); |
2446 Consume(Token::PERIOD); | 2551 Consume(Token::PERIOD); |
2447 int pos = position(); | 2552 int pos = position(); |
2448 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2553 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2449 result = factory()->NewProperty( | 2554 result = factory()->NewProperty( |
2450 result, factory()->NewStringLiteral(name, pos), pos); | 2555 result, factory()->NewStringLiteral(name, pos), pos); |
2451 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 2556 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
2452 break; | 2557 break; |
2453 } | 2558 } |
2454 | 2559 |
2455 case Token::TEMPLATE_SPAN: | 2560 case Token::TEMPLATE_SPAN: |
2456 case Token::TEMPLATE_TAIL: { | 2561 case Token::TEMPLATE_TAIL: { |
| 2562 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2457 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2563 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2458 BindingPatternUnexpectedToken(classifier); | 2564 BindingPatternUnexpectedToken(classifier); |
2459 ArrowFormalParametersUnexpectedToken(classifier); | 2565 ArrowFormalParametersUnexpectedToken(classifier); |
2460 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2566 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); |
2461 break; | 2567 break; |
2462 } | 2568 } |
2463 | 2569 |
2464 default: | 2570 default: |
2465 return result; | 2571 return result; |
2466 } | 2572 } |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2924 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 3030 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
2925 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3031 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
2926 materialized_literal_count = | 3032 materialized_literal_count = |
2927 function_state.materialized_literal_count(); | 3033 function_state.materialized_literal_count(); |
2928 expected_property_count = function_state.expected_property_count(); | 3034 expected_property_count = function_state.expected_property_count(); |
2929 } | 3035 } |
2930 } else { | 3036 } else { |
2931 // Single-expression body | 3037 // Single-expression body |
2932 int pos = position(); | 3038 int pos = position(); |
2933 ExpressionClassifier classifier(this); | 3039 ExpressionClassifier classifier(this); |
2934 bool is_tail_call_expression; | 3040 DCHECK(ReturnExprContext::kInsideValidBlock == |
2935 if (FLAG_harmony_explicit_tailcalls) { | 3041 function_state_->return_expr_context()); |
2936 // TODO(ishell): update chapter number. | 3042 ReturnExprScope allow_tail_calls( |
2937 // ES8 XX.YY.ZZ | 3043 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
2938 if (peek() == Token::CONTINUE) { | |
2939 Consume(Token::CONTINUE); | |
2940 pos = position(); | |
2941 is_tail_call_expression = true; | |
2942 } else { | |
2943 is_tail_call_expression = false; | |
2944 } | |
2945 } else { | |
2946 // ES6 14.6.1 Static Semantics: IsInTailPosition | |
2947 is_tail_call_expression = | |
2948 allow_tailcalls() && !is_sloppy(language_mode()); | |
2949 } | |
2950 ExpressionT expression = | 3044 ExpressionT expression = |
2951 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | 3045 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
2952 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 3046 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
2953 body = this->NewStatementList(1, zone()); | 3047 body = this->NewStatementList(1, zone()); |
2954 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 3048 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); |
2955 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3049 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
2956 materialized_literal_count = function_state.materialized_literal_count(); | 3050 materialized_literal_count = function_state.materialized_literal_count(); |
2957 expected_property_count = function_state.expected_property_count(); | 3051 expected_property_count = function_state.expected_property_count(); |
2958 if (is_tail_call_expression) { | 3052 if (allow_tailcalls() && !is_sloppy(language_mode())) { |
| 3053 // ES6 14.6.1 Static Semantics: IsInTailPosition |
2959 this->MarkTailPosition(expression); | 3054 this->MarkTailPosition(expression); |
2960 } | 3055 } |
| 3056 this->MarkCollectedTailCallExpressions(); |
2961 } | 3057 } |
2962 super_loc = function_state.super_location(); | 3058 super_loc = function_state.super_location(); |
2963 | 3059 |
2964 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3060 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
2965 | 3061 |
2966 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3062 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
2967 // which is not the same as "parameters of a strict function"; it only means | 3063 // which is not the same as "parameters of a strict function"; it only means |
2968 // that duplicates are not allowed. Of course, the arrow function may | 3064 // that duplicates are not allowed. Of course, the arrow function may |
2969 // itself be strict as well. | 3065 // itself be strict as well. |
2970 const bool allow_duplicate_parameters = false; | 3066 const bool allow_duplicate_parameters = false; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3049 } else if (next == Token::ILLEGAL) { | 3145 } else if (next == Token::ILLEGAL) { |
3050 Traits::ReportMessageAt( | 3146 Traits::ReportMessageAt( |
3051 Scanner::Location(position() + 1, peek_position()), | 3147 Scanner::Location(position() + 1, peek_position()), |
3052 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 3148 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
3053 *ok = false; | 3149 *ok = false; |
3054 return Traits::EmptyExpression(); | 3150 return Traits::EmptyExpression(); |
3055 } | 3151 } |
3056 | 3152 |
3057 int expr_pos = peek_position(); | 3153 int expr_pos = peek_position(); |
3058 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); | 3154 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); |
| 3155 CheckNoTailCallExpressions(classifier, CHECK_OK); |
3059 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3156 Traits::RewriteNonPattern(classifier, CHECK_OK); |
3060 Traits::AddTemplateExpression(&ts, expression); | 3157 Traits::AddTemplateExpression(&ts, expression); |
3061 | 3158 |
3062 if (peek() != Token::RBRACE) { | 3159 if (peek() != Token::RBRACE) { |
3063 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3160 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
3064 MessageTemplate::kUnterminatedTemplateExpr); | 3161 MessageTemplate::kUnterminatedTemplateExpr); |
3065 *ok = false; | 3162 *ok = false; |
3066 return Traits::EmptyExpression(); | 3163 return Traits::EmptyExpression(); |
3067 } | 3164 } |
3068 | 3165 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3207 has_seen_constructor_ = true; | 3304 has_seen_constructor_ = true; |
3208 return; | 3305 return; |
3209 } | 3306 } |
3210 } | 3307 } |
3211 | 3308 |
3212 | 3309 |
3213 } // namespace internal | 3310 } // namespace internal |
3214 } // namespace v8 | 3311 } // namespace v8 |
3215 | 3312 |
3216 #endif // V8_PARSING_PARSER_BASE_H | 3313 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |