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 |