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

Side by Side Diff: src/preparser.h

Issue 458613004: Refactor ParseObjectLiteral (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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.h ('k') | no next file » | 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 // 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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698