Chromium Code Reviews| 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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |