| 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); |
| 385 | 387 |
| 386 // Used to detect duplicates in object literals. Each of the values | 388 // Used to detect duplicates in object literals. Each of the values |
| 387 // kGetterProperty, kSetterProperty and kValueProperty represents | 389 // kGetterProperty, kSetterProperty and kValueProperty represents |
| 388 // a type of object literal property. When parsing a property, its | 390 // a type of object literal property. When parsing a property, its |
| 389 // type value is stored in the DuplicateFinder for the property name. | 391 // type value is stored in the DuplicateFinder for the property name. |
| 390 // Values are chosen so that having intersection bits means the there is | 392 // Values are chosen so that having intersection bits means the there is |
| 391 // an incompatibility. | 393 // an incompatibility. |
| 392 // I.e., you can add a getter to a property that already has a setter, since | 394 // I.e., you can add a getter to a property that already has a setter, since |
| 393 // kGetterProperty and kSetterProperty doesn't intersect, but not if it | 395 // kGetterProperty and kSetterProperty doesn't intersect, but not if it |
| 394 // already has a getter or a value. Adding the getter to an existing | 396 // 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... |
| 557 bool IsUseStrictLiteral() { | 559 bool IsUseStrictLiteral() { |
| 558 return (code_ & kStringLiteralMask) == kUseStrictString; | 560 return (code_ & kStringLiteralMask) == kUseStrictString; |
| 559 } | 561 } |
| 560 | 562 |
| 561 bool IsThis() { return code_ == kThisExpression; } | 563 bool IsThis() { return code_ == kThisExpression; } |
| 562 | 564 |
| 563 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 565 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
| 564 | 566 |
| 565 bool IsStrictFunction() { return code_ == kStrictFunctionExpression; } | 567 bool IsStrictFunction() { return code_ == kStrictFunctionExpression; } |
| 566 | 568 |
| 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 |
| 567 private: | 577 private: |
| 568 // First two/three bits are used as flags. | 578 // First two/three bits are used as flags. |
| 569 // Bit 0 and 1 represent identifiers or strings literals, and are | 579 // Bit 0 and 1 represent identifiers or strings literals, and are |
| 570 // mutually exclusive, but can both be absent. | 580 // mutually exclusive, but can both be absent. |
| 571 enum { | 581 enum { |
| 572 kUnknownExpression = 0, | 582 kUnknownExpression = 0, |
| 573 // Identifiers | 583 // Identifiers |
| 574 kIdentifierFlag = 1, // Used to detect labels. | 584 kIdentifierFlag = 1, // Used to detect labels. |
| 575 kIdentifierShift = 3, | 585 kIdentifierShift = 3, |
| 576 | 586 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 | 686 |
| 677 PreParserExpression NewLiteral(PreParserIdentifier identifier, | 687 PreParserExpression NewLiteral(PreParserIdentifier identifier, |
| 678 int pos) { | 688 int pos) { |
| 679 return PreParserExpression::Default(); | 689 return PreParserExpression::Default(); |
| 680 } | 690 } |
| 681 | 691 |
| 682 PreParserExpression NewNumberLiteral(double number, | 692 PreParserExpression NewNumberLiteral(double number, |
| 683 int pos) { | 693 int pos) { |
| 684 return PreParserExpression::Default(); | 694 return PreParserExpression::Default(); |
| 685 } | 695 } |
| 696 |
| 697 PreParserExpression NewAssignment(Token::Value op, |
| 698 PreParserExpression left, |
| 699 PreParserExpression right, |
| 700 int pos) { |
| 701 return PreParserExpression::Default(); |
| 702 } |
| 686 }; | 703 }; |
| 687 | 704 |
| 688 | 705 |
| 689 class PreParser; | 706 class PreParser; |
| 690 | 707 |
| 691 class PreParserTraits { | 708 class PreParserTraits { |
| 692 public: | 709 public: |
| 693 struct Type { | 710 struct Type { |
| 694 // TODO(marja): To be removed. The Traits object should contain all the data | 711 // TODO(marja): To be removed. The Traits object should contain all the data |
| 695 // it needs. | 712 // it needs. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 722 template<typename FunctionState> | 739 template<typename FunctionState> |
| 723 static void SetUpFunctionState(FunctionState* function_state, void*) {} | 740 static void SetUpFunctionState(FunctionState* function_state, void*) {} |
| 724 template<typename FunctionState> | 741 template<typename FunctionState> |
| 725 static void TearDownFunctionState(FunctionState* function_state) {} | 742 static void TearDownFunctionState(FunctionState* function_state) {} |
| 726 | 743 |
| 727 // Helper functions for recursive descent. | 744 // Helper functions for recursive descent. |
| 728 static bool IsEvalOrArguments(PreParserIdentifier identifier) { | 745 static bool IsEvalOrArguments(PreParserIdentifier identifier) { |
| 729 return identifier.IsEvalOrArguments(); | 746 return identifier.IsEvalOrArguments(); |
| 730 } | 747 } |
| 731 | 748 |
| 749 // Returns true if the expression is of type "this.foo". |
| 750 static bool IsThisProperty(PreParserExpression expression) { |
| 751 return expression.IsThisProperty(); |
| 752 } |
| 753 |
| 732 static bool IsBoilerplateProperty(PreParserExpression property) { | 754 static bool IsBoilerplateProperty(PreParserExpression property) { |
| 733 // PreParser doesn't count boilerplate properties. | 755 // PreParser doesn't count boilerplate properties. |
| 734 return false; | 756 return false; |
| 735 } | 757 } |
| 736 | 758 |
| 737 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 759 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
| 738 return false; | 760 return false; |
| 739 } | 761 } |
| 740 | 762 |
| 763 // Functions for encapsulating the differences between parsing and preparsing; |
| 764 // operations interleaved with the recursive descent. |
| 741 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 765 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
| 742 // PreParser should not use FuncNameInferrer. | 766 // PreParser should not use FuncNameInferrer. |
| 743 ASSERT(false); | 767 ASSERT(false); |
| 744 } | 768 } |
| 745 | 769 |
| 746 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 770 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
| 747 PreParserScope* scope, PreParserExpression value, bool* has_function) {} | 771 PreParserScope* scope, PreParserExpression value, bool* has_function) {} |
| 748 | 772 |
| 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 |
| 749 // Reporting errors. | 796 // Reporting errors. |
| 750 void ReportMessageAt(Scanner::Location location, | 797 void ReportMessageAt(Scanner::Location location, |
| 751 const char* message, | 798 const char* message, |
| 752 Vector<const char*> args); | 799 Vector<const char*> args); |
| 753 void ReportMessageAt(Scanner::Location location, | 800 void ReportMessageAt(Scanner::Location location, |
| 754 const char* type, | 801 const char* type, |
| 755 const char* name_opt); | 802 const char* name_opt); |
| 756 void ReportMessageAt(int start_pos, | 803 void ReportMessageAt(int start_pos, |
| 757 int end_pos, | 804 int end_pos, |
| 758 const char* type, | 805 const char* type, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 | 855 |
| 809 static PreParserExpressionList NewExpressionList(int size, void* zone) { | 856 static PreParserExpressionList NewExpressionList(int size, void* zone) { |
| 810 return PreParserExpressionList(); | 857 return PreParserExpressionList(); |
| 811 } | 858 } |
| 812 | 859 |
| 813 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 860 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
| 814 return PreParserExpressionList(); | 861 return PreParserExpressionList(); |
| 815 } | 862 } |
| 816 | 863 |
| 817 // Temporary glue; these functions will move to ParserBase. | 864 // Temporary glue; these functions will move to ParserBase. |
| 818 PreParserExpression ParseAssignmentExpression(bool accept_IN, bool* ok); | |
| 819 PreParserExpression ParseV8Intrinsic(bool* ok); | 865 PreParserExpression ParseV8Intrinsic(bool* ok); |
| 820 PreParserExpression ParseFunctionLiteral( | 866 PreParserExpression ParseFunctionLiteral( |
| 821 PreParserIdentifier name, | 867 PreParserIdentifier name, |
| 822 Scanner::Location function_name_location, | 868 Scanner::Location function_name_location, |
| 823 bool name_is_strict_reserved, | 869 bool name_is_strict_reserved, |
| 824 bool is_generator, | 870 bool is_generator, |
| 825 int function_token_position, | 871 int function_token_position, |
| 826 FunctionLiteral::FunctionType type, | 872 FunctionLiteral::FunctionType type, |
| 827 bool* ok); | 873 bool* ok); |
| 874 PreParserExpression ParseYieldExpression(bool* ok); |
| 875 PreParserExpression ParseConditionalExpression(bool accept_IN, bool* ok); |
| 828 | 876 |
| 829 private: | 877 private: |
| 830 PreParser* pre_parser_; | 878 PreParser* pre_parser_; |
| 831 }; | 879 }; |
| 832 | 880 |
| 833 | 881 |
| 834 // Preparsing checks a JavaScript program and emits preparse-data that helps | 882 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 835 // a later parsing to be faster. | 883 // a later parsing to be faster. |
| 836 // See preparse-data-format.h for the data format. | 884 // See preparse-data-format.h for the data format. |
| 837 | 885 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 Statement ParseBreakStatement(bool* ok); | 1030 Statement ParseBreakStatement(bool* ok); |
| 983 Statement ParseReturnStatement(bool* ok); | 1031 Statement ParseReturnStatement(bool* ok); |
| 984 Statement ParseWithStatement(bool* ok); | 1032 Statement ParseWithStatement(bool* ok); |
| 985 Statement ParseSwitchStatement(bool* ok); | 1033 Statement ParseSwitchStatement(bool* ok); |
| 986 Statement ParseDoWhileStatement(bool* ok); | 1034 Statement ParseDoWhileStatement(bool* ok); |
| 987 Statement ParseWhileStatement(bool* ok); | 1035 Statement ParseWhileStatement(bool* ok); |
| 988 Statement ParseForStatement(bool* ok); | 1036 Statement ParseForStatement(bool* ok); |
| 989 Statement ParseThrowStatement(bool* ok); | 1037 Statement ParseThrowStatement(bool* ok); |
| 990 Statement ParseTryStatement(bool* ok); | 1038 Statement ParseTryStatement(bool* ok); |
| 991 Statement ParseDebuggerStatement(bool* ok); | 1039 Statement ParseDebuggerStatement(bool* ok); |
| 992 | |
| 993 Expression ParseAssignmentExpression(bool accept_IN, bool* ok); | |
| 994 Expression ParseYieldExpression(bool* ok); | 1040 Expression ParseYieldExpression(bool* ok); |
| 995 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1041 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
| 996 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 1042 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 997 Expression ParseUnaryExpression(bool* ok); | 1043 Expression ParseUnaryExpression(bool* ok); |
| 998 Expression ParsePostfixExpression(bool* ok); | 1044 Expression ParsePostfixExpression(bool* ok); |
| 999 Expression ParseLeftHandSideExpression(bool* ok); | 1045 Expression ParseLeftHandSideExpression(bool* ok); |
| 1000 Expression ParseMemberExpression(bool* ok); | 1046 Expression ParseMemberExpression(bool* ok); |
| 1001 Expression ParseMemberExpressionContinuation(PreParserExpression expression, | 1047 Expression ParseMemberExpressionContinuation(PreParserExpression expression, |
| 1002 bool* ok); | 1048 bool* ok); |
| 1003 Expression ParseMemberWithNewPrefixesExpression(bool* ok); | 1049 Expression ParseMemberWithNewPrefixesExpression(bool* ok); |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1530 done = (peek() == Token::RPAREN); | 1576 done = (peek() == Token::RPAREN); |
| 1531 if (!done) { | 1577 if (!done) { |
| 1532 // Need {} because of the CHECK_OK_CUSTOM macro. | 1578 // Need {} because of the CHECK_OK_CUSTOM macro. |
| 1533 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); | 1579 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1534 } | 1580 } |
| 1535 } | 1581 } |
| 1536 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1582 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1537 return result; | 1583 return result; |
| 1538 } | 1584 } |
| 1539 | 1585 |
| 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 this->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 } |
| 1540 | 1655 |
| 1541 #undef CHECK_OK | 1656 #undef CHECK_OK |
| 1542 #undef CHECK_OK_CUSTOM | 1657 #undef CHECK_OK_CUSTOM |
| 1543 | 1658 |
| 1544 | 1659 |
| 1545 template <typename Traits> | 1660 template <typename Traits> |
| 1546 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 1661 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
| 1547 Token::Value property, | 1662 Token::Value property, |
| 1548 PropertyKind type, | 1663 PropertyKind type, |
| 1549 bool* ok) { | 1664 bool* ok) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1571 "accessor_get_set"); | 1686 "accessor_get_set"); |
| 1572 } | 1687 } |
| 1573 *ok = false; | 1688 *ok = false; |
| 1574 } | 1689 } |
| 1575 } | 1690 } |
| 1576 | 1691 |
| 1577 | 1692 |
| 1578 } } // v8::internal | 1693 } } // v8::internal |
| 1579 | 1694 |
| 1580 #endif // V8_PREPARSER_H | 1695 #endif // V8_PREPARSER_H |
| OLD | NEW |