OLD | NEW |
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 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 bool* ok); | 375 bool* ok); |
376 | 376 |
377 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, | 377 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, |
378 bool* ok); | 378 bool* ok); |
379 | 379 |
380 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok); | 380 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok); |
381 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok); | 381 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok); |
382 typename Traits::Type::Expression ParseArrayLiteral(bool* ok); | 382 typename Traits::Type::Expression ParseArrayLiteral(bool* ok); |
383 typename Traits::Type::Expression ParseObjectLiteral(bool* ok); | 383 typename Traits::Type::Expression ParseObjectLiteral(bool* ok); |
384 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 384 typename Traits::Type::ExpressionList ParseArguments(bool* ok); |
385 typename Traits::Type::Expression ParseAssignmentExpression(bool accept_IN, | |
386 bool* ok); | |
387 | 385 |
388 // Used to detect duplicates in object literals. Each of the values | 386 // Used to detect duplicates in object literals. Each of the values |
389 // kGetterProperty, kSetterProperty and kValueProperty represents | 387 // kGetterProperty, kSetterProperty and kValueProperty represents |
390 // a type of object literal property. When parsing a property, its | 388 // a type of object literal property. When parsing a property, its |
391 // type value is stored in the DuplicateFinder for the property name. | 389 // type value is stored in the DuplicateFinder for the property name. |
392 // Values are chosen so that having intersection bits means the there is | 390 // Values are chosen so that having intersection bits means the there is |
393 // an incompatibility. | 391 // an incompatibility. |
394 // I.e., you can add a getter to a property that already has a setter, since | 392 // I.e., you can add a getter to a property that already has a setter, since |
395 // kGetterProperty and kSetterProperty doesn't intersect, but not if it | 393 // kGetterProperty and kSetterProperty doesn't intersect, but not if it |
396 // already has a getter or a value. Adding the getter to an existing | 394 // 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 Loading... |
559 bool IsUseStrictLiteral() { | 557 bool IsUseStrictLiteral() { |
560 return (code_ & kStringLiteralMask) == kUseStrictString; | 558 return (code_ & kStringLiteralMask) == kUseStrictString; |
561 } | 559 } |
562 | 560 |
563 bool IsThis() { return code_ == kThisExpression; } | 561 bool IsThis() { return code_ == kThisExpression; } |
564 | 562 |
565 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 563 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
566 | 564 |
567 bool IsStrictFunction() { return code_ == kStrictFunctionExpression; } | 565 bool IsStrictFunction() { return code_ == kStrictFunctionExpression; } |
568 | 566 |
569 // Dummy implementation for making expression->AsCall() work (see below). | |
570 PreParserExpression* operator->() { return this; } | |
571 | |
572 // These are only used when doing function name inferring, and PreParser | |
573 // doesn't do function name inferring. | |
574 void* AsCall() const { return NULL; } | |
575 void* AsCallNew() const { return NULL; } | |
576 | |
577 private: | 567 private: |
578 // First two/three bits are used as flags. | 568 // First two/three bits are used as flags. |
579 // Bit 0 and 1 represent identifiers or strings literals, and are | 569 // Bit 0 and 1 represent identifiers or strings literals, and are |
580 // mutually exclusive, but can both be absent. | 570 // mutually exclusive, but can both be absent. |
581 enum { | 571 enum { |
582 kUnknownExpression = 0, | 572 kUnknownExpression = 0, |
583 // Identifiers | 573 // Identifiers |
584 kIdentifierFlag = 1, // Used to detect labels. | 574 kIdentifierFlag = 1, // Used to detect labels. |
585 kIdentifierShift = 3, | 575 kIdentifierShift = 3, |
586 | 576 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 | 676 |
687 PreParserExpression NewLiteral(PreParserIdentifier identifier, | 677 PreParserExpression NewLiteral(PreParserIdentifier identifier, |
688 int pos) { | 678 int pos) { |
689 return PreParserExpression::Default(); | 679 return PreParserExpression::Default(); |
690 } | 680 } |
691 | 681 |
692 PreParserExpression NewNumberLiteral(double number, | 682 PreParserExpression NewNumberLiteral(double number, |
693 int pos) { | 683 int pos) { |
694 return PreParserExpression::Default(); | 684 return PreParserExpression::Default(); |
695 } | 685 } |
696 | |
697 PreParserExpression NewAssignment(Token::Value op, | |
698 PreParserExpression left, | |
699 PreParserExpression right, | |
700 int pos) { | |
701 return PreParserExpression::Default(); | |
702 } | |
703 }; | 686 }; |
704 | 687 |
705 | 688 |
706 class PreParser; | 689 class PreParser; |
707 | 690 |
708 class PreParserTraits { | 691 class PreParserTraits { |
709 public: | 692 public: |
710 struct Type { | 693 struct Type { |
711 // TODO(marja): To be removed. The Traits object should contain all the data | 694 // TODO(marja): To be removed. The Traits object should contain all the data |
712 // it needs. | 695 // it needs. |
(...skipping 26 matching lines...) Expand all Loading... |
739 template<typename FunctionState> | 722 template<typename FunctionState> |
740 static void SetUpFunctionState(FunctionState* function_state, void*) {} | 723 static void SetUpFunctionState(FunctionState* function_state, void*) {} |
741 template<typename FunctionState> | 724 template<typename FunctionState> |
742 static void TearDownFunctionState(FunctionState* function_state) {} | 725 static void TearDownFunctionState(FunctionState* function_state) {} |
743 | 726 |
744 // Helper functions for recursive descent. | 727 // Helper functions for recursive descent. |
745 static bool IsEvalOrArguments(PreParserIdentifier identifier) { | 728 static bool IsEvalOrArguments(PreParserIdentifier identifier) { |
746 return identifier.IsEvalOrArguments(); | 729 return identifier.IsEvalOrArguments(); |
747 } | 730 } |
748 | 731 |
749 // Returns true if the expression is of type "this.foo". | |
750 static bool IsThisProperty(PreParserExpression expression) { | |
751 return expression.IsThisProperty(); | |
752 } | |
753 | |
754 static bool IsBoilerplateProperty(PreParserExpression property) { | 732 static bool IsBoilerplateProperty(PreParserExpression property) { |
755 // PreParser doesn't count boilerplate properties. | 733 // PreParser doesn't count boilerplate properties. |
756 return false; | 734 return false; |
757 } | 735 } |
758 | 736 |
759 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 737 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
760 return false; | 738 return false; |
761 } | 739 } |
762 | 740 |
763 // Functions for encapsulating the differences between parsing and preparsing; | |
764 // operations interleaved with the recursive descent. | |
765 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 741 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
766 // PreParser should not use FuncNameInferrer. | 742 // PreParser should not use FuncNameInferrer. |
767 ASSERT(false); | 743 ASSERT(false); |
768 } | 744 } |
769 | 745 |
770 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 746 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
771 PreParserScope* scope, PreParserExpression value, bool* has_function) {} | 747 PreParserScope* scope, PreParserExpression value, bool* has_function) {} |
772 | 748 |
773 static void CheckAssigningFunctionLiteralToProperty( | |
774 PreParserExpression left, PreParserExpression right) {} | |
775 | |
776 | |
777 static PreParserExpression ValidateAssignmentLeftHandSide( | |
778 PreParserExpression expression) { | |
779 // Parser generates a runtime error here if the left hand side is not valid. | |
780 // PreParser doesn't have to. | |
781 return expression; | |
782 } | |
783 | |
784 static PreParserExpression MarkExpressionAsLValue( | |
785 PreParserExpression expression) { | |
786 // TODO(marja): To be able to produce the same errors, the preparser needs | |
787 // to start tracking which expressions are variables and which are lvalues. | |
788 return expression; | |
789 } | |
790 | |
791 // Checks LHS expression for assignment and prefix/postfix increment/decrement | |
792 // in strict mode. | |
793 void CheckStrictModeLValue(PreParserExpression expression, bool* ok); | |
794 | |
795 | |
796 // Reporting errors. | 749 // Reporting errors. |
797 void ReportMessageAt(Scanner::Location location, | 750 void ReportMessageAt(Scanner::Location location, |
798 const char* message, | 751 const char* message, |
799 Vector<const char*> args); | 752 Vector<const char*> args); |
800 void ReportMessageAt(Scanner::Location location, | 753 void ReportMessageAt(Scanner::Location location, |
801 const char* type, | 754 const char* type, |
802 const char* name_opt); | 755 const char* name_opt); |
803 void ReportMessageAt(int start_pos, | 756 void ReportMessageAt(int start_pos, |
804 int end_pos, | 757 int end_pos, |
805 const char* type, | 758 const char* type, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 | 808 |
856 static PreParserExpressionList NewExpressionList(int size, void* zone) { | 809 static PreParserExpressionList NewExpressionList(int size, void* zone) { |
857 return PreParserExpressionList(); | 810 return PreParserExpressionList(); |
858 } | 811 } |
859 | 812 |
860 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 813 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
861 return PreParserExpressionList(); | 814 return PreParserExpressionList(); |
862 } | 815 } |
863 | 816 |
864 // Temporary glue; these functions will move to ParserBase. | 817 // Temporary glue; these functions will move to ParserBase. |
| 818 PreParserExpression ParseAssignmentExpression(bool accept_IN, bool* ok); |
865 PreParserExpression ParseV8Intrinsic(bool* ok); | 819 PreParserExpression ParseV8Intrinsic(bool* ok); |
866 PreParserExpression ParseFunctionLiteral( | 820 PreParserExpression ParseFunctionLiteral( |
867 PreParserIdentifier name, | 821 PreParserIdentifier name, |
868 Scanner::Location function_name_location, | 822 Scanner::Location function_name_location, |
869 bool name_is_strict_reserved, | 823 bool name_is_strict_reserved, |
870 bool is_generator, | 824 bool is_generator, |
871 int function_token_position, | 825 int function_token_position, |
872 FunctionLiteral::FunctionType type, | 826 FunctionLiteral::FunctionType type, |
873 bool* ok); | 827 bool* ok); |
874 PreParserExpression ParseYieldExpression(bool* ok); | |
875 PreParserExpression ParseConditionalExpression(bool accept_IN, bool* ok); | |
876 | 828 |
877 private: | 829 private: |
878 PreParser* pre_parser_; | 830 PreParser* pre_parser_; |
879 }; | 831 }; |
880 | 832 |
881 | 833 |
882 // Preparsing checks a JavaScript program and emits preparse-data that helps | 834 // Preparsing checks a JavaScript program and emits preparse-data that helps |
883 // a later parsing to be faster. | 835 // a later parsing to be faster. |
884 // See preparse-data-format.h for the data format. | 836 // See preparse-data-format.h for the data format. |
885 | 837 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 Statement ParseBreakStatement(bool* ok); | 982 Statement ParseBreakStatement(bool* ok); |
1031 Statement ParseReturnStatement(bool* ok); | 983 Statement ParseReturnStatement(bool* ok); |
1032 Statement ParseWithStatement(bool* ok); | 984 Statement ParseWithStatement(bool* ok); |
1033 Statement ParseSwitchStatement(bool* ok); | 985 Statement ParseSwitchStatement(bool* ok); |
1034 Statement ParseDoWhileStatement(bool* ok); | 986 Statement ParseDoWhileStatement(bool* ok); |
1035 Statement ParseWhileStatement(bool* ok); | 987 Statement ParseWhileStatement(bool* ok); |
1036 Statement ParseForStatement(bool* ok); | 988 Statement ParseForStatement(bool* ok); |
1037 Statement ParseThrowStatement(bool* ok); | 989 Statement ParseThrowStatement(bool* ok); |
1038 Statement ParseTryStatement(bool* ok); | 990 Statement ParseTryStatement(bool* ok); |
1039 Statement ParseDebuggerStatement(bool* ok); | 991 Statement ParseDebuggerStatement(bool* ok); |
| 992 |
| 993 Expression ParseAssignmentExpression(bool accept_IN, bool* ok); |
1040 Expression ParseYieldExpression(bool* ok); | 994 Expression ParseYieldExpression(bool* ok); |
1041 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 995 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
1042 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 996 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
1043 Expression ParseUnaryExpression(bool* ok); | 997 Expression ParseUnaryExpression(bool* ok); |
1044 Expression ParsePostfixExpression(bool* ok); | 998 Expression ParsePostfixExpression(bool* ok); |
1045 Expression ParseLeftHandSideExpression(bool* ok); | 999 Expression ParseLeftHandSideExpression(bool* ok); |
1046 Expression ParseMemberExpression(bool* ok); | 1000 Expression ParseMemberExpression(bool* ok); |
1047 Expression ParseMemberExpressionContinuation(PreParserExpression expression, | 1001 Expression ParseMemberExpressionContinuation(PreParserExpression expression, |
1048 bool* ok); | 1002 bool* ok); |
1049 Expression ParseMemberWithNewPrefixesExpression(bool* ok); | 1003 Expression ParseMemberWithNewPrefixesExpression(bool* ok); |
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 done = (peek() == Token::RPAREN); | 1530 done = (peek() == Token::RPAREN); |
1577 if (!done) { | 1531 if (!done) { |
1578 // Need {} because of the CHECK_OK_CUSTOM macro. | 1532 // Need {} because of the CHECK_OK_CUSTOM macro. |
1579 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); | 1533 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); |
1580 } | 1534 } |
1581 } | 1535 } |
1582 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1536 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1583 return result; | 1537 return result; |
1584 } | 1538 } |
1585 | 1539 |
1586 // Precedence = 2 | |
1587 template <class Traits> | |
1588 typename Traits::Type::Expression ParserBase<Traits>::ParseAssignmentExpression( | |
1589 bool accept_IN, bool* ok) { | |
1590 // AssignmentExpression :: | |
1591 // ConditionalExpression | |
1592 // YieldExpression | |
1593 // LeftHandSideExpression AssignmentOperator AssignmentExpression | |
1594 | |
1595 if (peek() == Token::YIELD && is_generator()) { | |
1596 return this->ParseYieldExpression(ok); | |
1597 } | |
1598 | |
1599 if (fni_ != NULL) fni_->Enter(); | |
1600 typename Traits::Type::Expression expression = | |
1601 this->ParseConditionalExpression(accept_IN, CHECK_OK); | |
1602 | |
1603 if (!Token::IsAssignmentOp(peek())) { | |
1604 if (fni_ != NULL) fni_->Leave(); | |
1605 // Parsed conditional expression only (no assignment). | |
1606 return expression; | |
1607 } | |
1608 | |
1609 // Signal a reference error if the expression is an invalid left-hand | |
1610 // side expression. We could report this as a syntax error here but | |
1611 // for compatibility with JSC we choose to report the error at | |
1612 // runtime. | |
1613 // TODO(ES5): Should change parsing for spec conformance. | |
1614 expression = this->ValidateAssignmentLeftHandSide(expression); | |
1615 | |
1616 if (strict_mode() == STRICT) { | |
1617 // Assignment to eval or arguments is disallowed in strict mode. | |
1618 CheckStrictModeLValue(expression, CHECK_OK); | |
1619 } | |
1620 expression = this->MarkExpressionAsLValue(expression); | |
1621 | |
1622 Token::Value op = Next(); // Get assignment operator. | |
1623 int pos = position(); | |
1624 typename Traits::Type::Expression right = | |
1625 this->ParseAssignmentExpression(accept_IN, CHECK_OK); | |
1626 | |
1627 // TODO(1231235): We try to estimate the set of properties set by | |
1628 // constructors. We define a new property whenever there is an | |
1629 // assignment to a property of 'this'. We should probably only add | |
1630 // properties if we haven't seen them before. Otherwise we'll | |
1631 // probably overestimate the number of properties. | |
1632 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | |
1633 function_state_->AddProperty(); | |
1634 } | |
1635 | |
1636 this->CheckAssigningFunctionLiteralToProperty(expression, right); | |
1637 | |
1638 if (fni_ != NULL) { | |
1639 // Check if the right hand side is a call to avoid inferring a | |
1640 // name if we're dealing with "a = function(){...}();"-like | |
1641 // expression. | |
1642 if ((op == Token::INIT_VAR | |
1643 || op == Token::INIT_CONST_LEGACY | |
1644 || op == Token::ASSIGN) | |
1645 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) { | |
1646 fni_->Infer(); | |
1647 } else { | |
1648 fni_->RemoveLastFunction(); | |
1649 } | |
1650 fni_->Leave(); | |
1651 } | |
1652 | |
1653 return factory()->NewAssignment(op, expression, right, pos); | |
1654 } | |
1655 | 1540 |
1656 #undef CHECK_OK | 1541 #undef CHECK_OK |
1657 #undef CHECK_OK_CUSTOM | 1542 #undef CHECK_OK_CUSTOM |
1658 | 1543 |
1659 | 1544 |
1660 template <typename Traits> | 1545 template <typename Traits> |
1661 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 1546 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
1662 Token::Value property, | 1547 Token::Value property, |
1663 PropertyKind type, | 1548 PropertyKind type, |
1664 bool* ok) { | 1549 bool* ok) { |
(...skipping 21 matching lines...) Expand all Loading... |
1686 "accessor_get_set"); | 1571 "accessor_get_set"); |
1687 } | 1572 } |
1688 *ok = false; | 1573 *ok = false; |
1689 } | 1574 } |
1690 } | 1575 } |
1691 | 1576 |
1692 | 1577 |
1693 } } // v8::internal | 1578 } } // v8::internal |
1694 | 1579 |
1695 #endif // V8_PREPARSER_H | 1580 #endif // V8_PREPARSER_H |
OLD | NEW |