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

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: rebased 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
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('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 // 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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698