| 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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 ExpressionT ParsePrimaryExpression(bool* ok); | 388 ExpressionT ParsePrimaryExpression(bool* ok); |
| 389 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 389 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 390 ExpressionT ParseArrayLiteral(bool* ok); | 390 ExpressionT ParseArrayLiteral(bool* ok); |
| 391 ExpressionT ParseObjectLiteral(bool* ok); | 391 ExpressionT ParseObjectLiteral(bool* ok); |
| 392 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 392 typename Traits::Type::ExpressionList ParseArguments(bool* ok); |
| 393 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 393 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
| 394 ExpressionT ParseYieldExpression(bool* ok); | 394 ExpressionT ParseYieldExpression(bool* ok); |
| 395 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 395 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 396 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 396 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 397 ExpressionT ParseUnaryExpression(bool* ok); | 397 ExpressionT ParseUnaryExpression(bool* ok); |
| 398 ExpressionT ParsePostfixExpression(bool* ok); |
| 398 | 399 |
| 399 // Used to detect duplicates in object literals. Each of the values | 400 // Used to detect duplicates in object literals. Each of the values |
| 400 // kGetterProperty, kSetterProperty and kValueProperty represents | 401 // kGetterProperty, kSetterProperty and kValueProperty represents |
| 401 // a type of object literal property. When parsing a property, its | 402 // a type of object literal property. When parsing a property, its |
| 402 // type value is stored in the DuplicateFinder for the property name. | 403 // type value is stored in the DuplicateFinder for the property name. |
| 403 // Values are chosen so that having intersection bits means the there is | 404 // Values are chosen so that having intersection bits means the there is |
| 404 // an incompatibility. | 405 // an incompatibility. |
| 405 // I.e., you can add a getter to a property that already has a setter, since | 406 // I.e., you can add a getter to a property that already has a setter, since |
| 406 // kGetterProperty and kSetterProperty doesn't intersect, but not if it | 407 // kGetterProperty and kSetterProperty doesn't intersect, but not if it |
| 407 // already has a getter or a value. Adding the getter to an existing | 408 // already has a getter or a value. Adding the getter to an existing |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 } | 574 } |
| 574 | 575 |
| 575 bool IsThis() { return code_ == kThisExpression; } | 576 bool IsThis() { return code_ == kThisExpression; } |
| 576 | 577 |
| 577 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 578 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
| 578 | 579 |
| 579 bool IsProperty() { | 580 bool IsProperty() { |
| 580 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 581 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
| 581 } | 582 } |
| 582 | 583 |
| 583 // Dummy implementation for making expression->AsCall() work (see below). | 584 bool IsValidLeftHandSide() { |
| 585 return IsIdentifier() || IsProperty(); |
| 586 } |
| 587 |
| 588 // Dummy implementation for making expression->somefunc() work in both Parser |
| 589 // and PreParser. |
| 584 PreParserExpression* operator->() { return this; } | 590 PreParserExpression* operator->() { return this; } |
| 585 | 591 |
| 586 // These are only used when doing function name inferring, and PreParser | 592 // These are only used when doing function name inferring, and PreParser |
| 587 // doesn't do function name inferring. | 593 // doesn't do function name inferring. |
| 588 void* AsCall() const { return NULL; } | 594 void* AsCall() const { return NULL; } |
| 589 void* AsCallNew() const { return NULL; } | 595 void* AsCallNew() const { return NULL; } |
| 590 | 596 |
| 591 // More dummy implementations of things PreParser doesn't need to track: | 597 // More dummy implementations of things PreParser doesn't need to track: |
| 592 void set_index(int index) {} // For YieldExpressions | 598 void set_index(int index) {} // For YieldExpressions |
| 593 | 599 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 // PreParser should not use FuncNameInferrer. | 832 // PreParser should not use FuncNameInferrer. |
| 827 ASSERT(false); | 833 ASSERT(false); |
| 828 } | 834 } |
| 829 | 835 |
| 830 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 836 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
| 831 PreParserScope* scope, PreParserExpression value, bool* has_function) {} | 837 PreParserScope* scope, PreParserExpression value, bool* has_function) {} |
| 832 | 838 |
| 833 static void CheckAssigningFunctionLiteralToProperty( | 839 static void CheckAssigningFunctionLiteralToProperty( |
| 834 PreParserExpression left, PreParserExpression right) {} | 840 PreParserExpression left, PreParserExpression right) {} |
| 835 | 841 |
| 836 // Determine whether the expression is a valid assignment left-hand side. | |
| 837 static bool IsValidLeftHandSide(PreParserExpression expression) { | |
| 838 return expression.IsIdentifier() || expression.IsProperty(); | |
| 839 } | |
| 840 | |
| 841 static PreParserExpression MarkExpressionAsLValue( | 842 static PreParserExpression MarkExpressionAsLValue( |
| 842 PreParserExpression expression) { | 843 PreParserExpression expression) { |
| 843 // TODO(marja): To be able to produce the same errors, the preparser needs | 844 // TODO(marja): To be able to produce the same errors, the preparser needs |
| 844 // to start tracking which expressions are variables and which are lvalues. | 845 // to start tracking which expressions are variables and which are lvalues. |
| 845 return expression; | 846 return expression; |
| 846 } | 847 } |
| 847 | 848 |
| 848 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 849 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 849 // in strict mode. | 850 // in strict mode. |
| 850 void CheckStrictModeLValue(PreParserExpression expression, bool* ok); | 851 void CheckStrictModeLValue(PreParserExpression expression, bool* ok); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 // Temporary glue; these functions will move to ParserBase. | 938 // Temporary glue; these functions will move to ParserBase. |
| 938 PreParserExpression ParseV8Intrinsic(bool* ok); | 939 PreParserExpression ParseV8Intrinsic(bool* ok); |
| 939 PreParserExpression ParseFunctionLiteral( | 940 PreParserExpression ParseFunctionLiteral( |
| 940 PreParserIdentifier name, | 941 PreParserIdentifier name, |
| 941 Scanner::Location function_name_location, | 942 Scanner::Location function_name_location, |
| 942 bool name_is_strict_reserved, | 943 bool name_is_strict_reserved, |
| 943 bool is_generator, | 944 bool is_generator, |
| 944 int function_token_position, | 945 int function_token_position, |
| 945 FunctionLiteral::FunctionType type, | 946 FunctionLiteral::FunctionType type, |
| 946 bool* ok); | 947 bool* ok); |
| 947 PreParserExpression ParsePostfixExpression(bool* ok); | 948 PreParserExpression ParseLeftHandSideExpression(bool* ok); |
| 948 | 949 |
| 949 private: | 950 private: |
| 950 PreParser* pre_parser_; | 951 PreParser* pre_parser_; |
| 951 }; | 952 }; |
| 952 | 953 |
| 953 | 954 |
| 954 // Preparsing checks a JavaScript program and emits preparse-data that helps | 955 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 955 // a later parsing to be faster. | 956 // a later parsing to be faster. |
| 956 // See preparse-data-format.h for the data format. | 957 // See preparse-data-format.h for the data format. |
| 957 | 958 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 Statement ParseReturnStatement(bool* ok); | 1102 Statement ParseReturnStatement(bool* ok); |
| 1102 Statement ParseWithStatement(bool* ok); | 1103 Statement ParseWithStatement(bool* ok); |
| 1103 Statement ParseSwitchStatement(bool* ok); | 1104 Statement ParseSwitchStatement(bool* ok); |
| 1104 Statement ParseDoWhileStatement(bool* ok); | 1105 Statement ParseDoWhileStatement(bool* ok); |
| 1105 Statement ParseWhileStatement(bool* ok); | 1106 Statement ParseWhileStatement(bool* ok); |
| 1106 Statement ParseForStatement(bool* ok); | 1107 Statement ParseForStatement(bool* ok); |
| 1107 Statement ParseThrowStatement(bool* ok); | 1108 Statement ParseThrowStatement(bool* ok); |
| 1108 Statement ParseTryStatement(bool* ok); | 1109 Statement ParseTryStatement(bool* ok); |
| 1109 Statement ParseDebuggerStatement(bool* ok); | 1110 Statement ParseDebuggerStatement(bool* ok); |
| 1110 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1111 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
| 1111 Expression ParsePostfixExpression(bool* ok); | |
| 1112 Expression ParseLeftHandSideExpression(bool* ok); | 1112 Expression ParseLeftHandSideExpression(bool* ok); |
| 1113 Expression ParseMemberExpression(bool* ok); | 1113 Expression ParseMemberExpression(bool* ok); |
| 1114 Expression ParseMemberExpressionContinuation(PreParserExpression expression, | 1114 Expression ParseMemberExpressionContinuation(PreParserExpression expression, |
| 1115 bool* ok); | 1115 bool* ok); |
| 1116 Expression ParseMemberWithNewPrefixesExpression(bool* ok); | 1116 Expression ParseMemberWithNewPrefixesExpression(bool* ok); |
| 1117 Expression ParseObjectLiteral(bool* ok); | 1117 Expression ParseObjectLiteral(bool* ok); |
| 1118 Expression ParseV8Intrinsic(bool* ok); | 1118 Expression ParseV8Intrinsic(bool* ok); |
| 1119 | 1119 |
| 1120 Expression ParseFunctionLiteral( | 1120 Expression ParseFunctionLiteral( |
| 1121 Identifier name, | 1121 Identifier name, |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1657 if (fni_ != NULL) fni_->Enter(); | 1657 if (fni_ != NULL) fni_->Enter(); |
| 1658 ExpressionT expression = | 1658 ExpressionT expression = |
| 1659 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 1659 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
| 1660 | 1660 |
| 1661 if (!Token::IsAssignmentOp(peek())) { | 1661 if (!Token::IsAssignmentOp(peek())) { |
| 1662 if (fni_ != NULL) fni_->Leave(); | 1662 if (fni_ != NULL) fni_->Leave(); |
| 1663 // Parsed conditional expression only (no assignment). | 1663 // Parsed conditional expression only (no assignment). |
| 1664 return expression; | 1664 return expression; |
| 1665 } | 1665 } |
| 1666 | 1666 |
| 1667 if (!this->IsValidLeftHandSide(expression)) { | 1667 if (!expression->IsValidLeftHandSide()) { |
| 1668 this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true); | 1668 this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true); |
| 1669 *ok = false; | 1669 *ok = false; |
| 1670 return this->EmptyExpression(); | 1670 return this->EmptyExpression(); |
| 1671 } | 1671 } |
| 1672 | 1672 |
| 1673 if (strict_mode() == STRICT) { | 1673 if (strict_mode() == STRICT) { |
| 1674 // Assignment to eval or arguments is disallowed in strict mode. | 1674 // Assignment to eval or arguments is disallowed in strict mode. |
| 1675 this->CheckStrictModeLValue(expression, CHECK_OK); | 1675 this->CheckStrictModeLValue(expression, CHECK_OK); |
| 1676 } | 1676 } |
| 1677 expression = this->MarkExpressionAsLValue(expression); | 1677 expression = this->MarkExpressionAsLValue(expression); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1827 *ok = false; | 1827 *ok = false; |
| 1828 return this->EmptyExpression(); | 1828 return this->EmptyExpression(); |
| 1829 } | 1829 } |
| 1830 | 1830 |
| 1831 // Allow Traits do rewrite the expression. | 1831 // Allow Traits do rewrite the expression. |
| 1832 return this->BuildUnaryExpression(expression, op, pos, factory()); | 1832 return this->BuildUnaryExpression(expression, op, pos, factory()); |
| 1833 } else if (Token::IsCountOp(op)) { | 1833 } else if (Token::IsCountOp(op)) { |
| 1834 op = Next(); | 1834 op = Next(); |
| 1835 Scanner::Location lhs_location = scanner()->peek_location(); | 1835 Scanner::Location lhs_location = scanner()->peek_location(); |
| 1836 ExpressionT expression = ParseUnaryExpression(CHECK_OK); | 1836 ExpressionT expression = ParseUnaryExpression(CHECK_OK); |
| 1837 if (!this->IsValidLeftHandSide(expression)) { | 1837 if (!expression->IsValidLeftHandSide()) { |
| 1838 ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true); | 1838 ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true); |
| 1839 *ok = false; | 1839 *ok = false; |
| 1840 return this->EmptyExpression(); | 1840 return this->EmptyExpression(); |
| 1841 } | 1841 } |
| 1842 | 1842 |
| 1843 if (strict_mode() == STRICT) { | 1843 if (strict_mode() == STRICT) { |
| 1844 // Prefix expression operand in strict mode may not be eval or arguments. | 1844 // Prefix expression operand in strict mode may not be eval or arguments. |
| 1845 this->CheckStrictModeLValue(expression, CHECK_OK); | 1845 this->CheckStrictModeLValue(expression, CHECK_OK); |
| 1846 } | 1846 } |
| 1847 this->MarkExpressionAsLValue(expression); | 1847 this->MarkExpressionAsLValue(expression); |
| 1848 | 1848 |
| 1849 return factory()->NewCountOperation(op, | 1849 return factory()->NewCountOperation(op, |
| 1850 true /* prefix */, | 1850 true /* prefix */, |
| 1851 expression, | 1851 expression, |
| 1852 position()); | 1852 position()); |
| 1853 | 1853 |
| 1854 } else { | 1854 } else { |
| 1855 return this->ParsePostfixExpression(ok); | 1855 return this->ParsePostfixExpression(ok); |
| 1856 } | 1856 } |
| 1857 } | 1857 } |
| 1858 | 1858 |
| 1859 | 1859 |
| 1860 template <class Traits> |
| 1861 typename ParserBase<Traits>::ExpressionT |
| 1862 ParserBase<Traits>::ParsePostfixExpression(bool* ok) { |
| 1863 // PostfixExpression :: |
| 1864 // LeftHandSideExpression ('++' | '--')? |
| 1865 |
| 1866 Scanner::Location lhs_location = scanner()->peek_location(); |
| 1867 ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK); |
| 1868 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 1869 Token::IsCountOp(peek())) { |
| 1870 if (!expression->IsValidLeftHandSide()) { |
| 1871 ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true); |
| 1872 *ok = false; |
| 1873 return this->EmptyExpression(); |
| 1874 } |
| 1875 |
| 1876 if (strict_mode() == STRICT) { |
| 1877 // Postfix expression operand in strict mode may not be eval or arguments. |
| 1878 this->CheckStrictModeLValue(expression, CHECK_OK); |
| 1879 } |
| 1880 expression = this->MarkExpressionAsLValue(expression); |
| 1881 |
| 1882 Token::Value next = Next(); |
| 1883 expression = |
| 1884 factory()->NewCountOperation(next, |
| 1885 false /* postfix */, |
| 1886 expression, |
| 1887 position()); |
| 1888 } |
| 1889 return expression; |
| 1890 } |
| 1891 |
| 1892 |
| 1860 #undef CHECK_OK | 1893 #undef CHECK_OK |
| 1861 #undef CHECK_OK_CUSTOM | 1894 #undef CHECK_OK_CUSTOM |
| 1862 | 1895 |
| 1863 | 1896 |
| 1864 template <typename Traits> | 1897 template <typename Traits> |
| 1865 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 1898 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
| 1866 Token::Value property, | 1899 Token::Value property, |
| 1867 PropertyKind type, | 1900 PropertyKind type, |
| 1868 bool* ok) { | 1901 bool* ok) { |
| 1869 int old; | 1902 int old; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1890 "accessor_get_set"); | 1923 "accessor_get_set"); |
| 1891 } | 1924 } |
| 1892 *ok = false; | 1925 *ok = false; |
| 1893 } | 1926 } |
| 1894 } | 1927 } |
| 1895 | 1928 |
| 1896 | 1929 |
| 1897 } } // v8::internal | 1930 } } // v8::internal |
| 1898 | 1931 |
| 1899 #endif // V8_PREPARSER_H | 1932 #endif // V8_PREPARSER_H |
| OLD | NEW |