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

Side by Side Diff: src/preparser.h

Issue 197653002: Move ParseAssignmentExpression to ParserBase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 bool* ok); 336 bool* ok);
337 337
338 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, 338 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal,
339 bool* ok); 339 bool* ok);
340 340
341 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok); 341 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok);
342 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok); 342 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok);
343 typename Traits::Type::Expression ParseArrayLiteral(bool* ok); 343 typename Traits::Type::Expression ParseArrayLiteral(bool* ok);
344 typename Traits::Type::Expression ParseObjectLiteral(bool* ok); 344 typename Traits::Type::Expression ParseObjectLiteral(bool* ok);
345 typename Traits::Type::ExpressionList ParseArguments(bool* ok); 345 typename Traits::Type::ExpressionList ParseArguments(bool* ok);
346 typename Traits::Type::Expression ParseAssignmentExpression(bool accept_IN,
347 bool* ok);
346 348
347 // Used to detect duplicates in object literals. Each of the values 349 // Used to detect duplicates in object literals. Each of the values
348 // kGetterProperty, kSetterProperty and kValueProperty represents 350 // kGetterProperty, kSetterProperty and kValueProperty represents
349 // a type of object literal property. When parsing a property, its 351 // a type of object literal property. When parsing a property, its
350 // type value is stored in the DuplicateFinder for the property name. 352 // type value is stored in the DuplicateFinder for the property name.
351 // Values are chosen so that having intersection bits means the there is 353 // Values are chosen so that having intersection bits means the there is
352 // an incompatibility. 354 // an incompatibility.
353 // I.e., you can add a getter to a property that already has a setter, since 355 // I.e., you can add a getter to a property that already has a setter, since
354 // kGetterProperty and kSetterProperty doesn't intersect, but not if it 356 // kGetterProperty and kSetterProperty doesn't intersect, but not if it
355 // already has a getter or a value. Adding the getter to an existing 357 // already has a getter or a value. Adding the getter to an existing
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 bool IsUseStrictLiteral() { 520 bool IsUseStrictLiteral() {
519 return (code_ & kStringLiteralMask) == kUseStrictString; 521 return (code_ & kStringLiteralMask) == kUseStrictString;
520 } 522 }
521 523
522 bool IsThis() { return code_ == kThisExpression; } 524 bool IsThis() { return code_ == kThisExpression; }
523 525
524 bool IsThisProperty() { return code_ == kThisPropertyExpression; } 526 bool IsThisProperty() { return code_ == kThisPropertyExpression; }
525 527
526 bool IsStrictFunction() { return code_ == kStrictFunctionExpression; } 528 bool IsStrictFunction() { return code_ == kStrictFunctionExpression; }
527 529
530 // Dummy implementation for making expression->AsCall() work (see below).
531 PreParserExpression* operator->() { return this; }
532
533 // These are only used when doing function name inferring, and PreParser
534 // doesn't do function name inferring.
535 void* AsCall() const { return NULL; }
536 void* AsCallNew() const { return NULL; }
537
528 private: 538 private:
529 // First two/three bits are used as flags. 539 // First two/three bits are used as flags.
530 // Bit 0 and 1 represent identifiers or strings literals, and are 540 // Bit 0 and 1 represent identifiers or strings literals, and are
531 // mutually exclusive, but can both be absent. 541 // mutually exclusive, but can both be absent.
532 enum { 542 enum {
533 kUnknownExpression = 0, 543 kUnknownExpression = 0,
534 // Identifiers 544 // Identifiers
535 kIdentifierFlag = 1, // Used to detect labels. 545 kIdentifierFlag = 1, // Used to detect labels.
536 kIdentifierShift = 3, 546 kIdentifierShift = 3,
537 547
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 647
638 PreParserExpression NewLiteral(PreParserIdentifier identifier, 648 PreParserExpression NewLiteral(PreParserIdentifier identifier,
639 int pos) { 649 int pos) {
640 return PreParserExpression::Default(); 650 return PreParserExpression::Default();
641 } 651 }
642 652
643 PreParserExpression NewNumberLiteral(double number, 653 PreParserExpression NewNumberLiteral(double number,
644 int pos) { 654 int pos) {
645 return PreParserExpression::Default(); 655 return PreParserExpression::Default();
646 } 656 }
657
658 PreParserExpression NewAssignment(Token::Value op,
659 PreParserExpression left,
660 PreParserExpression right,
661 int pos) {
662 return PreParserExpression::Default();
663 }
647 }; 664 };
648 665
649 666
650 class PreParser; 667 class PreParser;
651 668
652 class PreParserTraits { 669 class PreParserTraits {
653 public: 670 public:
654 struct Type { 671 struct Type {
655 typedef PreParser* Parser; 672 typedef PreParser* Parser;
656 673
(...skipping 22 matching lines...) Expand all
679 template<typename FunctionState> 696 template<typename FunctionState>
680 static void SetUpFunctionState(FunctionState* function_state, void*) {} 697 static void SetUpFunctionState(FunctionState* function_state, void*) {}
681 template<typename FunctionState> 698 template<typename FunctionState>
682 static void TearDownFunctionState(FunctionState* function_state) {} 699 static void TearDownFunctionState(FunctionState* function_state) {}
683 700
684 // Helper functions for recursive descent. 701 // Helper functions for recursive descent.
685 static bool IsEvalOrArguments(PreParserIdentifier identifier) { 702 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
686 return identifier.IsEvalOrArguments(); 703 return identifier.IsEvalOrArguments();
687 } 704 }
688 705
706 // Returns true if the expression is of type "this.foo".
707 static bool IsThisProperty(PreParserExpression expression) {
708 return expression.IsThisProperty();
709 }
710
689 static bool IsBoilerplateProperty(PreParserExpression property) { 711 static bool IsBoilerplateProperty(PreParserExpression property) {
690 // PreParser doesn't count boilerplate properties. 712 // PreParser doesn't count boilerplate properties.
691 return false; 713 return false;
692 } 714 }
693 715
694 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 716 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
695 return false; 717 return false;
696 } 718 }
697 719
720 // Functions for encapsulating the differences between parsing and preparsing;
721 // operations interleaved with the recursive descent.
698 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 722 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
699 // PreParser should not use FuncNameInferrer. 723 // PreParser should not use FuncNameInferrer.
700 ASSERT(false); 724 ASSERT(false);
701 } 725 }
702 726
703 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 727 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
704 PreParserScope* scope, PreParserExpression value, bool* has_function) {} 728 PreParserScope* scope, PreParserExpression value, bool* has_function) {}
705 729
730 static void CheckAssigningFunctionLiteralToProperty(
731 PreParserExpression left, PreParserExpression right) {}
732
733
734 static PreParserExpression ValidateAssignmentLeftHandSide(
735 PreParserExpression expression) {
736 // Parser generates a runtime error here if the left hand side is not valid.
737 // PreParser doesn't have to.
738 return expression;
739 }
740
741 static PreParserExpression MarkExpressionAsLValue(
742 PreParserExpression expression) {
743 // TODO(marja): To be able to produce the same errors, the preparser needs
744 // to start tracking which expressions are variables and which are lvalues.
745 return expression;
746 }
747
748 // Checks LHS expression for assignment and prefix/postfix increment/decrement
749 // in strict mode.
750 void CheckStrictModeLValue(PreParserExpression expression, bool* ok);
751
752
706 // Reporting errors. 753 // Reporting errors.
707 void ReportMessageAt(Scanner::Location location, 754 void ReportMessageAt(Scanner::Location location,
708 const char* message, 755 const char* message,
709 Vector<const char*> args); 756 Vector<const char*> args);
710 void ReportMessageAt(Scanner::Location location, 757 void ReportMessageAt(Scanner::Location location,
711 const char* type, 758 const char* type,
712 const char* name_opt); 759 const char* name_opt);
713 void ReportMessageAt(int start_pos, 760 void ReportMessageAt(int start_pos,
714 int end_pos, 761 int end_pos,
715 const char* type, 762 const char* type,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 812
766 static PreParserExpressionList NewExpressionList(int size, void* zone) { 813 static PreParserExpressionList NewExpressionList(int size, void* zone) {
767 return PreParserExpressionList(); 814 return PreParserExpressionList();
768 } 815 }
769 816
770 static PreParserExpressionList NewPropertyList(int size, void* zone) { 817 static PreParserExpressionList NewPropertyList(int size, void* zone) {
771 return PreParserExpressionList(); 818 return PreParserExpressionList();
772 } 819 }
773 820
774 // Temporary glue; these functions will move to ParserBase. 821 // Temporary glue; these functions will move to ParserBase.
775 PreParserExpression ParseAssignmentExpression(bool accept_IN, bool* ok);
776 PreParserExpression ParseV8Intrinsic(bool* ok); 822 PreParserExpression ParseV8Intrinsic(bool* ok);
777 PreParserExpression ParseFunctionLiteral( 823 PreParserExpression ParseFunctionLiteral(
778 PreParserIdentifier name, 824 PreParserIdentifier name,
779 Scanner::Location function_name_location, 825 Scanner::Location function_name_location,
780 bool name_is_strict_reserved, 826 bool name_is_strict_reserved,
781 bool is_generator, 827 bool is_generator,
782 int function_token_position, 828 int function_token_position,
783 FunctionLiteral::FunctionType type, 829 FunctionLiteral::FunctionType type,
784 bool* ok); 830 bool* ok);
831 PreParserExpression ParseYieldExpression(bool* ok);
832 PreParserExpression ParseConditionalExpression(bool accept_IN, bool* ok);
785 833
786 private: 834 private:
787 PreParser* pre_parser_; 835 PreParser* pre_parser_;
788 }; 836 };
789 837
790 838
791 // Preparsing checks a JavaScript program and emits preparse-data that helps 839 // Preparsing checks a JavaScript program and emits preparse-data that helps
792 // a later parsing to be faster. 840 // a later parsing to be faster.
793 // See preparse-data-format.h for the data format. 841 // See preparse-data-format.h for the data format.
794 842
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 Statement ParseBreakStatement(bool* ok); 987 Statement ParseBreakStatement(bool* ok);
940 Statement ParseReturnStatement(bool* ok); 988 Statement ParseReturnStatement(bool* ok);
941 Statement ParseWithStatement(bool* ok); 989 Statement ParseWithStatement(bool* ok);
942 Statement ParseSwitchStatement(bool* ok); 990 Statement ParseSwitchStatement(bool* ok);
943 Statement ParseDoWhileStatement(bool* ok); 991 Statement ParseDoWhileStatement(bool* ok);
944 Statement ParseWhileStatement(bool* ok); 992 Statement ParseWhileStatement(bool* ok);
945 Statement ParseForStatement(bool* ok); 993 Statement ParseForStatement(bool* ok);
946 Statement ParseThrowStatement(bool* ok); 994 Statement ParseThrowStatement(bool* ok);
947 Statement ParseTryStatement(bool* ok); 995 Statement ParseTryStatement(bool* ok);
948 Statement ParseDebuggerStatement(bool* ok); 996 Statement ParseDebuggerStatement(bool* ok);
949
950 Expression ParseAssignmentExpression(bool accept_IN, bool* ok);
951 Expression ParseYieldExpression(bool* ok); 997 Expression ParseYieldExpression(bool* ok);
952 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 998 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
953 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 999 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
954 Expression ParseUnaryExpression(bool* ok); 1000 Expression ParseUnaryExpression(bool* ok);
955 Expression ParsePostfixExpression(bool* ok); 1001 Expression ParsePostfixExpression(bool* ok);
956 Expression ParseLeftHandSideExpression(bool* ok); 1002 Expression ParseLeftHandSideExpression(bool* ok);
957 Expression ParseMemberExpression(bool* ok); 1003 Expression ParseMemberExpression(bool* ok);
958 Expression ParseMemberExpressionContinuation(PreParserExpression expression, 1004 Expression ParseMemberExpressionContinuation(PreParserExpression expression,
959 bool* ok); 1005 bool* ok);
960 Expression ParseMemberWithNewPrefixesExpression(bool* ok); 1006 Expression ParseMemberWithNewPrefixesExpression(bool* ok);
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 done = (peek() == Token::RPAREN); 1539 done = (peek() == Token::RPAREN);
1494 if (!done) { 1540 if (!done) {
1495 // Need {} because of the CHECK_OK_CUSTOM macro. 1541 // Need {} because of the CHECK_OK_CUSTOM macro.
1496 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); 1542 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
1497 } 1543 }
1498 } 1544 }
1499 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 1545 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1500 return result; 1546 return result;
1501 } 1547 }
1502 1548
1549 // Precedence = 2
1550 template <class Traits>
1551 typename Traits::Type::Expression ParserBase<Traits>::ParseAssignmentExpression(
1552 bool accept_IN, bool* ok) {
1553 // AssignmentExpression ::
1554 // ConditionalExpression
1555 // YieldExpression
1556 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1557
1558 if (peek() == Token::YIELD && is_generator()) {
1559 return this->ParseYieldExpression(ok);
Michael Starzinger 2014/03/13 08:52:41 As discussed offline: It would be nice to get rid
rossberg 2014/03/13 09:25:34 FWIW, I like the explicit this->, and would prefer
1560 }
1561
1562 if (fni_ != NULL) fni_->Enter();
1563 typename Traits::Type::Expression expression =
1564 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1565
1566 if (!Token::IsAssignmentOp(peek())) {
1567 if (fni_ != NULL) fni_->Leave();
1568 // Parsed conditional expression only (no assignment).
1569 return expression;
1570 }
1571
1572 // Signal a reference error if the expression is an invalid left-hand
1573 // side expression. We could report this as a syntax error here but
1574 // for compatibility with JSC we choose to report the error at
1575 // runtime.
1576 // TODO(ES5): Should change parsing for spec conformance.
1577 expression = this->ValidateAssignmentLeftHandSide(expression);
1578
1579 if (strict_mode() == STRICT) {
1580 // Assignment to eval or arguments is disallowed in strict mode.
1581 CheckStrictModeLValue(expression, CHECK_OK);
1582 }
1583 expression = this->MarkExpressionAsLValue(expression);
1584
1585 Token::Value op = Next(); // Get assignment operator.
1586 int pos = position();
1587 typename Traits::Type::Expression right =
1588 this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1589
1590 // TODO(1231235): We try to estimate the set of properties set by
1591 // constructors. We define a new property whenever there is an
1592 // assignment to a property of 'this'. We should probably only add
1593 // properties if we haven't seen them before. Otherwise we'll
1594 // probably overestimate the number of properties.
1595 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
1596 function_state_->AddProperty();
1597 }
1598
1599 this->CheckAssigningFunctionLiteralToProperty(expression, right);
1600
1601 if (fni_ != NULL) {
1602 // Check if the right hand side is a call to avoid inferring a
1603 // name if we're dealing with "a = function(){...}();"-like
1604 // expression.
1605 if ((op == Token::INIT_VAR
1606 || op == Token::INIT_CONST_LEGACY
1607 || op == Token::ASSIGN)
1608 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
1609 fni_->Infer();
1610 } else {
1611 fni_->RemoveLastFunction();
1612 }
1613 fni_->Leave();
1614 }
1615
1616 return factory()->NewAssignment(op, expression, right, pos);
1617 }
1503 1618
1504 #undef CHECK_OK 1619 #undef CHECK_OK
1505 #undef CHECK_OK_CUSTOM 1620 #undef CHECK_OK_CUSTOM
1506 1621
1507 1622
1508 template <typename Traits> 1623 template <typename Traits>
1509 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 1624 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
1510 Token::Value property, 1625 Token::Value property,
1511 PropertyKind type, 1626 PropertyKind type,
1512 bool* ok) { 1627 bool* ok) {
(...skipping 23 matching lines...) Expand all
1536 "accessor_get_set"); 1651 "accessor_get_set");
1537 } 1652 }
1538 *ok = false; 1653 *ok = false;
1539 } 1654 }
1540 } 1655 }
1541 1656
1542 1657
1543 } } // v8::internal 1658 } } // v8::internal
1544 1659
1545 #endif // V8_PREPARSER_H 1660 #endif // V8_PREPARSER_H
OLDNEW
« src/parser.h ('K') | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698