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