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

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: Some STC tests ported for PTC 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
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698