OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 // PreParser functions return PreParserExpression. | 23 // PreParser functions return PreParserExpression. |
24 | 24 |
25 // - Creating parse tree nodes: Parser generates an AST during the recursive | 25 // - Creating parse tree nodes: Parser generates an AST during the recursive |
26 // descent. PreParser doesn't create a tree. Instead, it passes around minimal | 26 // descent. PreParser doesn't create a tree. Instead, it passes around minimal |
27 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain | 27 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain |
28 // just enough data for the upper layer functions. PreParserFactory is | 28 // just enough data for the upper layer functions. PreParserFactory is |
29 // responsible for creating these dummy objects. It provides a similar kind of | 29 // responsible for creating these dummy objects. It provides a similar kind of |
30 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is | 30 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is |
31 // used. | 31 // used. |
32 | 32 |
33 // - Miscellanous other tasks interleaved with the recursive descent. For | 33 // - Miscellaneous other tasks interleaved with the recursive descent. For |
34 // example, Parser keeps track of which function literals should be marked as | 34 // example, Parser keeps track of which function literals should be marked as |
35 // pretenured, and PreParser doesn't care. | 35 // pretenured, and PreParser doesn't care. |
36 | 36 |
37 // The traits are expected to contain the following typedefs: | 37 // The traits are expected to contain the following typedefs: |
38 // struct Traits { | 38 // struct Traits { |
39 // // In particular... | 39 // // In particular... |
40 // struct Type { | 40 // struct Type { |
41 // // Used by FunctionState and BlockState. | 41 // // Used by FunctionState and BlockState. |
42 // typedef Scope; | 42 // typedef Scope; |
43 // typedef GeneratorVariable; | 43 // typedef GeneratorVariable; |
(...skipping 12 matching lines...) Expand all Loading... |
56 // // ... | 56 // // ... |
57 // }; | 57 // }; |
58 | 58 |
59 template <typename Traits> | 59 template <typename Traits> |
60 class ParserBase : public Traits { | 60 class ParserBase : public Traits { |
61 public: | 61 public: |
62 // Shorten type names defined by Traits. | 62 // Shorten type names defined by Traits. |
63 typedef typename Traits::Type::Expression ExpressionT; | 63 typedef typename Traits::Type::Expression ExpressionT; |
64 typedef typename Traits::Type::Identifier IdentifierT; | 64 typedef typename Traits::Type::Identifier IdentifierT; |
65 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | 65 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
| 66 typedef typename Traits::Type::Literal LiteralT; |
| 67 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; |
66 | 68 |
67 ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension, | 69 ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension, |
68 ParserRecorder* log, typename Traits::Type::Zone* zone, | 70 ParserRecorder* log, typename Traits::Type::Zone* zone, |
69 typename Traits::Type::Parser this_object) | 71 typename Traits::Type::Parser this_object) |
70 : Traits(this_object), | 72 : Traits(this_object), |
71 parenthesized_function_(false), | 73 parenthesized_function_(false), |
72 scope_(NULL), | 74 scope_(NULL), |
73 function_state_(NULL), | 75 function_state_(NULL), |
74 extension_(extension), | 76 extension_(extension), |
75 fni_(NULL), | 77 fni_(NULL), |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, | 465 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, |
464 bool* is_set, | 466 bool* is_set, |
465 bool* ok); | 467 bool* ok); |
466 | 468 |
467 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); | 469 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); |
468 | 470 |
469 ExpressionT ParsePrimaryExpression(bool* ok); | 471 ExpressionT ParsePrimaryExpression(bool* ok); |
470 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 472 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
471 ExpressionT ParseArrayLiteral(bool* ok); | 473 ExpressionT ParseArrayLiteral(bool* ok); |
472 ExpressionT ParseObjectLiteral(bool* ok); | 474 ExpressionT ParseObjectLiteral(bool* ok); |
| 475 ObjectLiteralPropertyT ParsePropertyDefinition(bool* ok); |
473 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 476 typename Traits::Type::ExpressionList ParseArguments(bool* ok); |
474 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 477 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
475 ExpressionT ParseYieldExpression(bool* ok); | 478 ExpressionT ParseYieldExpression(bool* ok); |
476 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 479 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
477 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 480 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
478 ExpressionT ParseUnaryExpression(bool* ok); | 481 ExpressionT ParseUnaryExpression(bool* ok); |
479 ExpressionT ParsePostfixExpression(bool* ok); | 482 ExpressionT ParsePostfixExpression(bool* ok); |
480 ExpressionT ParseLeftHandSideExpression(bool* ok); | 483 ExpressionT ParseLeftHandSideExpression(bool* ok); |
481 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 484 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
482 ExpressionT ParseMemberExpression(bool* ok); | 485 ExpressionT ParseMemberExpression(bool* ok); |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1093 // PreParser should not use FuncNameInferrer. | 1096 // PreParser should not use FuncNameInferrer. |
1094 UNREACHABLE(); | 1097 UNREACHABLE(); |
1095 } | 1098 } |
1096 static void InferFunctionName(FuncNameInferrer* fni, | 1099 static void InferFunctionName(FuncNameInferrer* fni, |
1097 PreParserExpression expression) { | 1100 PreParserExpression expression) { |
1098 // PreParser should not use FuncNameInferrer. | 1101 // PreParser should not use FuncNameInferrer. |
1099 UNREACHABLE(); | 1102 UNREACHABLE(); |
1100 } | 1103 } |
1101 | 1104 |
1102 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 1105 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
1103 PreParserScope* scope, PreParserExpression value, bool* has_function) {} | 1106 PreParserScope* scope, PreParserExpression property, bool* has_function) { |
| 1107 } |
1104 | 1108 |
1105 static void CheckAssigningFunctionLiteralToProperty( | 1109 static void CheckAssigningFunctionLiteralToProperty( |
1106 PreParserExpression left, PreParserExpression right) {} | 1110 PreParserExpression left, PreParserExpression right) {} |
1107 | 1111 |
1108 // PreParser doesn't need to keep track of eval calls. | 1112 // PreParser doesn't need to keep track of eval calls. |
1109 static void CheckPossibleEvalCall(PreParserExpression expression, | 1113 static void CheckPossibleEvalCall(PreParserExpression expression, |
1110 PreParserScope* scope) {} | 1114 PreParserScope* scope) {} |
1111 | 1115 |
1112 static PreParserExpression MarkExpressionAsAssigned( | 1116 static PreParserExpression MarkExpressionAsAssigned( |
1113 PreParserExpression expression) { | 1117 PreParserExpression expression) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 } | 1169 } |
1166 static PreParserExpression EmptyExpression() { | 1170 static PreParserExpression EmptyExpression() { |
1167 return PreParserExpression::Default(); | 1171 return PreParserExpression::Default(); |
1168 } | 1172 } |
1169 static PreParserExpression EmptyArrowParamList() { | 1173 static PreParserExpression EmptyArrowParamList() { |
1170 return PreParserExpression::EmptyArrowParamList(); | 1174 return PreParserExpression::EmptyArrowParamList(); |
1171 } | 1175 } |
1172 static PreParserExpression EmptyLiteral() { | 1176 static PreParserExpression EmptyLiteral() { |
1173 return PreParserExpression::Default(); | 1177 return PreParserExpression::Default(); |
1174 } | 1178 } |
| 1179 static PreParserExpression EmptyObjectLiteralProperty() { |
| 1180 return PreParserExpression::Default(); |
| 1181 } |
1175 static PreParserExpressionList NullExpressionList() { | 1182 static PreParserExpressionList NullExpressionList() { |
1176 return PreParserExpressionList(); | 1183 return PreParserExpressionList(); |
1177 } | 1184 } |
1178 | 1185 |
1179 // Odd-ball literal creators. | 1186 // Odd-ball literal creators. |
1180 static PreParserExpression GetLiteralTheHole(int position, | 1187 static PreParserExpression GetLiteralTheHole(int position, |
1181 PreParserFactory* factory) { | 1188 PreParserFactory* factory) { |
1182 return PreParserExpression::Default(); | 1189 return PreParserExpression::Default(); |
1183 } | 1190 } |
1184 | 1191 |
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1773 Expect(Token::RBRACK, CHECK_OK); | 1780 Expect(Token::RBRACK, CHECK_OK); |
1774 | 1781 |
1775 // Update the scope information before the pre-parsing bailout. | 1782 // Update the scope information before the pre-parsing bailout. |
1776 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1783 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1777 | 1784 |
1778 return factory()->NewArrayLiteral(values, literal_index, pos); | 1785 return factory()->NewArrayLiteral(values, literal_index, pos); |
1779 } | 1786 } |
1780 | 1787 |
1781 | 1788 |
1782 template <class Traits> | 1789 template <class Traits> |
| 1790 typename ParserBase<Traits>::ObjectLiteralPropertyT |
| 1791 ParserBase<Traits>::ParsePropertyDefinition(bool* ok) { |
| 1792 LiteralT key = this->EmptyLiteral(); |
| 1793 Token::Value next = peek(); |
| 1794 int next_pos = peek_position(); |
| 1795 |
| 1796 switch (next) { |
| 1797 case Token::STRING: { |
| 1798 Consume(Token::STRING); |
| 1799 IdentifierT string = this->GetSymbol(scanner_); |
| 1800 if (fni_ != NULL) this->PushLiteralName(fni_, string); |
| 1801 uint32_t index; |
| 1802 if (this->IsArrayIndex(string, &index)) { |
| 1803 key = factory()->NewNumberLiteral(index, next_pos); |
| 1804 break; |
| 1805 } |
| 1806 key = factory()->NewStringLiteral(string, next_pos); |
| 1807 break; |
| 1808 } |
| 1809 case Token::NUMBER: { |
| 1810 Consume(Token::NUMBER); |
| 1811 key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_, |
| 1812 factory()); |
| 1813 break; |
| 1814 } |
| 1815 default: { |
| 1816 bool is_getter = false; |
| 1817 bool is_setter = false; |
| 1818 IdentifierT id = ParseIdentifierNameOrGetOrSet( |
| 1819 &is_getter, &is_setter, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1820 if (fni_ != NULL) this->PushLiteralName(fni_, id); |
| 1821 |
| 1822 if ((is_getter || is_setter) && peek() != Token::COLON) { |
| 1823 // Special handling of getter and setter syntax: |
| 1824 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } |
| 1825 // We have already read the "get" or "set" keyword. |
| 1826 IdentifierT name = this->EmptyIdentifier(); |
| 1827 switch (peek()) { |
| 1828 case Token::STRING: |
| 1829 Consume(Token::STRING); |
| 1830 name = this->GetSymbol(scanner_); |
| 1831 break; |
| 1832 case Token::NUMBER: |
| 1833 Consume(Token::NUMBER); |
| 1834 // TODO(arv): Fix issue with numeric keys. get 1.0() should be |
| 1835 // treated as if the key was '1' |
| 1836 // https://code.google.com/p/v8/issues/detail?id=3507 |
| 1837 name = this->GetSymbol(scanner_); |
| 1838 break; |
| 1839 default: |
| 1840 name = ParseIdentifierName( |
| 1841 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1842 } |
| 1843 typename Traits::Type::FunctionLiteral value = |
| 1844 this->ParseFunctionLiteral( |
| 1845 name, scanner()->location(), |
| 1846 false, // reserved words are allowed here |
| 1847 false, // not a generator |
| 1848 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 1849 is_getter ? FunctionLiteral::GETTER_ARITY |
| 1850 : FunctionLiteral::SETTER_ARITY, |
| 1851 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1852 return factory()->NewObjectLiteralProperty(is_getter, value, next_pos); |
| 1853 } |
| 1854 // Failed to parse as get/set property, so it's just a normal property |
| 1855 // (which might be called "get" or "set" or something else). |
| 1856 key = factory()->NewStringLiteral(id, next_pos); |
| 1857 } |
| 1858 } |
| 1859 |
| 1860 Expect(Token::COLON, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1861 ExpressionT value = this->ParseAssignmentExpression( |
| 1862 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1863 |
| 1864 return factory()->NewObjectLiteralProperty(key, value); |
| 1865 } |
| 1866 |
| 1867 |
| 1868 template <class Traits> |
1783 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 1869 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
1784 bool* ok) { | 1870 bool* ok) { |
1785 // ObjectLiteral :: | 1871 // ObjectLiteral :: |
1786 // '{' (( | 1872 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
1787 // ((IdentifierName | String | Number) ':' AssignmentExpression) | | |
1788 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | |
1789 // ) ',')* '}' | |
1790 // (Except that the trailing comma is not required.) | |
1791 | 1873 |
1792 int pos = peek_position(); | 1874 int pos = peek_position(); |
1793 typename Traits::Type::PropertyList properties = | 1875 typename Traits::Type::PropertyList properties = |
1794 this->NewPropertyList(4, zone_); | 1876 this->NewPropertyList(4, zone_); |
1795 int number_of_boilerplate_properties = 0; | 1877 int number_of_boilerplate_properties = 0; |
1796 bool has_function = false; | 1878 bool has_function = false; |
1797 | 1879 |
1798 Expect(Token::LBRACE, CHECK_OK); | 1880 Expect(Token::LBRACE, CHECK_OK); |
1799 | 1881 |
1800 while (peek() != Token::RBRACE) { | 1882 while (peek() != Token::RBRACE) { |
1801 if (fni_ != NULL) fni_->Enter(); | 1883 if (fni_ != NULL) fni_->Enter(); |
1802 | 1884 |
1803 typename Traits::Type::Literal key = this->EmptyLiteral(); | 1885 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(CHECK_OK); |
1804 Token::Value next = peek(); | |
1805 int next_pos = peek_position(); | |
1806 | |
1807 switch (next) { | |
1808 case Token::FUTURE_RESERVED_WORD: | |
1809 case Token::FUTURE_STRICT_RESERVED_WORD: | |
1810 case Token::LET: | |
1811 case Token::YIELD: | |
1812 case Token::IDENTIFIER: { | |
1813 bool is_getter = false; | |
1814 bool is_setter = false; | |
1815 IdentifierT id = | |
1816 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | |
1817 if (fni_ != NULL) this->PushLiteralName(fni_, id); | |
1818 | |
1819 if ((is_getter || is_setter) && peek() != Token::COLON) { | |
1820 // Special handling of getter and setter syntax: | |
1821 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } | |
1822 // We have already read the "get" or "set" keyword. | |
1823 Token::Value next = Next(); | |
1824 if (next != i::Token::IDENTIFIER && | |
1825 next != i::Token::FUTURE_RESERVED_WORD && | |
1826 next != i::Token::FUTURE_STRICT_RESERVED_WORD && | |
1827 next != i::Token::LET && | |
1828 next != i::Token::YIELD && | |
1829 next != i::Token::NUMBER && | |
1830 next != i::Token::STRING && | |
1831 !Token::IsKeyword(next)) { | |
1832 ReportUnexpectedToken(next); | |
1833 *ok = false; | |
1834 return this->EmptyLiteral(); | |
1835 } | |
1836 IdentifierT name = this->GetSymbol(scanner_); | |
1837 typename Traits::Type::FunctionLiteral value = | |
1838 this->ParseFunctionLiteral( | |
1839 name, scanner()->location(), | |
1840 false, // reserved words are allowed here | |
1841 false, // not a generator | |
1842 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | |
1843 is_getter ? FunctionLiteral::GETTER_ARITY | |
1844 : FunctionLiteral::SETTER_ARITY, | |
1845 CHECK_OK); | |
1846 typename Traits::Type::ObjectLiteralProperty property = | |
1847 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); | |
1848 if (this->IsBoilerplateProperty(property)) { | |
1849 number_of_boilerplate_properties++; | |
1850 } | |
1851 properties->Add(property, zone()); | |
1852 if (peek() != Token::RBRACE) { | |
1853 // Need {} because of the CHECK_OK macro. | |
1854 Expect(Token::COMMA, CHECK_OK); | |
1855 } | |
1856 | |
1857 if (fni_ != NULL) { | |
1858 fni_->Infer(); | |
1859 fni_->Leave(); | |
1860 } | |
1861 continue; // restart the while | |
1862 } | |
1863 // Failed to parse as get/set property, so it's just a normal property | |
1864 // (which might be called "get" or "set" or something else). | |
1865 key = factory()->NewStringLiteral(id, next_pos); | |
1866 break; | |
1867 } | |
1868 case Token::STRING: { | |
1869 Consume(Token::STRING); | |
1870 IdentifierT string = this->GetSymbol(scanner_); | |
1871 if (fni_ != NULL) this->PushLiteralName(fni_, string); | |
1872 uint32_t index; | |
1873 if (this->IsArrayIndex(string, &index)) { | |
1874 key = factory()->NewNumberLiteral(index, next_pos); | |
1875 break; | |
1876 } | |
1877 key = factory()->NewStringLiteral(string, next_pos); | |
1878 break; | |
1879 } | |
1880 case Token::NUMBER: { | |
1881 Consume(Token::NUMBER); | |
1882 key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_, | |
1883 factory()); | |
1884 break; | |
1885 } | |
1886 default: | |
1887 if (Token::IsKeyword(next)) { | |
1888 Consume(next); | |
1889 IdentifierT string = this->GetSymbol(scanner_); | |
1890 key = factory()->NewStringLiteral(string, next_pos); | |
1891 } else { | |
1892 Token::Value next = Next(); | |
1893 ReportUnexpectedToken(next); | |
1894 *ok = false; | |
1895 return this->EmptyLiteral(); | |
1896 } | |
1897 } | |
1898 | |
1899 Expect(Token::COLON, CHECK_OK); | |
1900 ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK); | |
1901 | |
1902 typename Traits::Type::ObjectLiteralProperty property = | |
1903 factory()->NewObjectLiteralProperty(key, value); | |
1904 | 1886 |
1905 // Mark top-level object literals that contain function literals and | 1887 // Mark top-level object literals that contain function literals and |
1906 // pretenure the literal so it can be added as a constant function | 1888 // pretenure the literal so it can be added as a constant function |
1907 // property. (Parser only.) | 1889 // property. (Parser only.) |
1908 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value, | 1890 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, |
1909 &has_function); | 1891 &has_function); |
1910 | 1892 |
1911 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 1893 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
1912 if (this->IsBoilerplateProperty(property)) { | 1894 if (this->IsBoilerplateProperty(property)) { |
1913 number_of_boilerplate_properties++; | 1895 number_of_boilerplate_properties++; |
1914 } | 1896 } |
1915 properties->Add(property, zone()); | 1897 properties->Add(property, zone()); |
1916 | 1898 |
1917 if (peek() != Token::RBRACE) { | 1899 if (peek() != Token::RBRACE) { |
1918 // Need {} because of the CHECK_OK macro. | 1900 // Need {} because of the CHECK_OK macro. |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2562 } | 2544 } |
2563 | 2545 |
2564 | 2546 |
2565 #undef CHECK_OK | 2547 #undef CHECK_OK |
2566 #undef CHECK_OK_CUSTOM | 2548 #undef CHECK_OK_CUSTOM |
2567 | 2549 |
2568 | 2550 |
2569 } } // v8::internal | 2551 } } // v8::internal |
2570 | 2552 |
2571 #endif // V8_PREPARSER_H | 2553 #endif // V8_PREPARSER_H |
OLD | NEW |