Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: src/parsing/parser-base.h

Issue 1928203002: [es8] More spec compliant syntactic tail calls implementation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Moar tests Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698