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/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 bool allow_arrow_functions() const { return allow_arrow_functions_; } | 95 bool allow_arrow_functions() const { return allow_arrow_functions_; } |
96 bool allow_modules() const { return scanner()->HarmonyModules(); } | 96 bool allow_modules() const { return scanner()->HarmonyModules(); } |
97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
98 bool allow_harmony_numeric_literals() const { | 98 bool allow_harmony_numeric_literals() const { |
99 return scanner()->HarmonyNumericLiterals(); | 99 return scanner()->HarmonyNumericLiterals(); |
100 } | 100 } |
101 bool allow_classes() const { return scanner()->HarmonyClasses(); } | 101 bool allow_classes() const { return scanner()->HarmonyClasses(); } |
102 bool allow_harmony_object_literals() const { | 102 bool allow_harmony_object_literals() const { |
103 return allow_harmony_object_literals_; | 103 return allow_harmony_object_literals_; |
104 } | 104 } |
| 105 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } |
105 | 106 |
106 // Setters that determine whether certain syntactical constructs are | 107 // Setters that determine whether certain syntactical constructs are |
107 // allowed to be parsed by this instance of the parser. | 108 // allowed to be parsed by this instance of the parser. |
108 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 109 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
109 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } | 110 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } |
110 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } | 111 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } |
111 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 112 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
112 void set_allow_harmony_scoping(bool allow) { | 113 void set_allow_harmony_scoping(bool allow) { |
113 scanner()->SetHarmonyScoping(allow); | 114 scanner()->SetHarmonyScoping(allow); |
114 } | 115 } |
115 void set_allow_harmony_numeric_literals(bool allow) { | 116 void set_allow_harmony_numeric_literals(bool allow) { |
116 scanner()->SetHarmonyNumericLiterals(allow); | 117 scanner()->SetHarmonyNumericLiterals(allow); |
117 } | 118 } |
118 void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); } | 119 void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); } |
119 void set_allow_harmony_object_literals(bool allow) { | 120 void set_allow_harmony_object_literals(bool allow) { |
120 allow_harmony_object_literals_ = allow; | 121 allow_harmony_object_literals_ = allow; |
121 } | 122 } |
| 123 void set_allow_harmony_templates(bool allow) { |
| 124 scanner()->SetHarmonyTemplates(allow); |
| 125 } |
122 | 126 |
123 protected: | 127 protected: |
124 enum AllowEvalOrArgumentsAsIdentifier { | 128 enum AllowEvalOrArgumentsAsIdentifier { |
125 kAllowEvalOrArguments, | 129 kAllowEvalOrArguments, |
126 kDontAllowEvalOrArguments | 130 kDontAllowEvalOrArguments |
127 }; | 131 }; |
128 | 132 |
129 enum Mode { | 133 enum Mode { |
130 PARSE_LAZILY, | 134 PARSE_LAZILY, |
131 PARSE_EAGERLY | 135 PARSE_EAGERLY |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 bool stack_overflow() const { return stack_overflow_; } | 278 bool stack_overflow() const { return stack_overflow_; } |
275 void set_stack_overflow() { stack_overflow_ = true; } | 279 void set_stack_overflow() { stack_overflow_ = true; } |
276 Mode mode() const { return mode_; } | 280 Mode mode() const { return mode_; } |
277 typename Traits::Type::Zone* zone() const { return zone_; } | 281 typename Traits::Type::Zone* zone() const { return zone_; } |
278 | 282 |
279 INLINE(Token::Value peek()) { | 283 INLINE(Token::Value peek()) { |
280 if (stack_overflow_) return Token::ILLEGAL; | 284 if (stack_overflow_) return Token::ILLEGAL; |
281 return scanner()->peek(); | 285 return scanner()->peek(); |
282 } | 286 } |
283 | 287 |
284 INLINE(Token::Value Next()) { | 288 INLINE(Token::Value Next(Scanner::Mode mode = Scanner::None)) { |
285 if (stack_overflow_) return Token::ILLEGAL; | 289 if (stack_overflow_) return Token::ILLEGAL; |
286 { | 290 { |
287 if (GetCurrentStackPosition() < stack_limit_) { | 291 if (GetCurrentStackPosition() < stack_limit_) { |
288 // Any further calls to Next or peek will return the illegal token. | 292 // Any further calls to Next or peek will return the illegal token. |
289 // The current call must return the next token, which might already | 293 // The current call must return the next token, which might already |
290 // have been peek'ed. | 294 // have been peek'ed. |
291 stack_overflow_ = true; | 295 stack_overflow_ = true; |
292 } | 296 } |
293 } | 297 } |
294 return scanner()->Next(); | 298 return scanner()->Next(mode); |
295 } | 299 } |
296 | 300 |
297 void Consume(Token::Value token) { | 301 void Consume(Token::Value token) { |
298 Token::Value next = Next(); | 302 Token::Value next = Next(); |
299 USE(next); | 303 USE(next); |
300 USE(token); | 304 USE(token); |
301 DCHECK(next == token); | 305 DCHECK(next == token); |
302 } | 306 } |
303 | 307 |
304 bool Check(Token::Value token) { | 308 bool Check(Token::Value token) { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 ExpressionT ParseMemberExpression(bool* ok); | 493 ExpressionT ParseMemberExpression(bool* ok); |
490 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 494 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
491 bool* ok); | 495 bool* ok); |
492 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 496 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
493 bool* ok); | 497 bool* ok); |
494 ExpressionT ParseClassLiteral(IdentifierT name, | 498 ExpressionT ParseClassLiteral(IdentifierT name, |
495 Scanner::Location function_name_location, | 499 Scanner::Location function_name_location, |
496 bool name_is_strict_reserved, int pos, | 500 bool name_is_strict_reserved, int pos, |
497 bool* ok); | 501 bool* ok); |
498 | 502 |
| 503 void AddTemplateSpan(); |
| 504 void AddTemplateExpression(ExpressionT); |
| 505 |
499 // Checks if the expression is a valid reference expression (e.g., on the | 506 // Checks if the expression is a valid reference expression (e.g., on the |
500 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 507 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
501 // we allow calls for web compatibility and rewrite them to a runtime throw. | 508 // we allow calls for web compatibility and rewrite them to a runtime throw. |
502 ExpressionT CheckAndRewriteReferenceExpression( | 509 ExpressionT CheckAndRewriteReferenceExpression( |
503 ExpressionT expression, | 510 ExpressionT expression, |
504 Scanner::Location location, const char* message, bool* ok); | 511 Scanner::Location location, const char* message, bool* ok); |
505 | 512 |
506 // Used to detect duplicates in object literals. Each of the values | 513 // Used to detect duplicates in object literals. Each of the values |
507 // kGetterProperty, kSetterProperty and kValueProperty represents | 514 // kGetterProperty, kSetterProperty and kValueProperty represents |
508 // a type of object literal property. When parsing a property, its | 515 // a type of object literal property. When parsing a property, its |
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1369 // Utility functions | 1376 // Utility functions |
1370 int DeclareArrowParametersFromExpression(PreParserExpression expression, | 1377 int DeclareArrowParametersFromExpression(PreParserExpression expression, |
1371 PreParserScope* scope, | 1378 PreParserScope* scope, |
1372 Scanner::Location* dupe_loc, | 1379 Scanner::Location* dupe_loc, |
1373 bool* ok) { | 1380 bool* ok) { |
1374 // TODO(aperez): Detect duplicated identifiers in paramlists. | 1381 // TODO(aperez): Detect duplicated identifiers in paramlists. |
1375 *ok = expression.IsValidArrowParamList(); | 1382 *ok = expression.IsValidArrowParamList(); |
1376 return 0; | 1383 return 0; |
1377 } | 1384 } |
1378 | 1385 |
| 1386 struct TemplateLiteralState {}; |
| 1387 |
| 1388 TemplateLiteralState OpenTemplateLiteral() { return TemplateLiteralState(); } |
| 1389 void AddTemplateSpan(TemplateLiteralState* state) { USE(state); } |
| 1390 void AddTemplateExpression(TemplateLiteralState* state, |
| 1391 PreParserExpression expression) { |
| 1392 USE(state); |
| 1393 USE(expression); |
| 1394 } |
| 1395 PreParserExpression CloseTemplateLiteral(TemplateLiteralState* state, |
| 1396 int pos) { |
| 1397 USE(state); |
| 1398 USE(pos); |
| 1399 return EmptyExpression(); |
| 1400 } |
| 1401 |
1379 static AstValueFactory* ast_value_factory() { return NULL; } | 1402 static AstValueFactory* ast_value_factory() { return NULL; } |
1380 | 1403 |
1381 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} | 1404 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} |
1382 | 1405 |
1383 // Temporary glue; these functions will move to ParserBase. | 1406 // Temporary glue; these functions will move to ParserBase. |
1384 PreParserExpression ParseV8Intrinsic(bool* ok); | 1407 PreParserExpression ParseV8Intrinsic(bool* ok); |
1385 PreParserExpression ParseFunctionLiteral( | 1408 PreParserExpression ParseFunctionLiteral( |
1386 PreParserIdentifier name, Scanner::Location function_name_location, | 1409 PreParserIdentifier name, Scanner::Location function_name_location, |
1387 bool name_is_strict_reserved, FunctionKind kind, | 1410 bool name_is_strict_reserved, FunctionKind kind, |
1388 int function_token_position, FunctionLiteral::FunctionType type, | 1411 int function_token_position, FunctionLiteral::FunctionType type, |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1738 // 'true' | 1761 // 'true' |
1739 // 'false' | 1762 // 'false' |
1740 // Identifier | 1763 // Identifier |
1741 // Number | 1764 // Number |
1742 // String | 1765 // String |
1743 // ArrayLiteral | 1766 // ArrayLiteral |
1744 // ObjectLiteral | 1767 // ObjectLiteral |
1745 // RegExpLiteral | 1768 // RegExpLiteral |
1746 // ClassLiteral | 1769 // ClassLiteral |
1747 // '(' Expression ')' | 1770 // '(' Expression ')' |
| 1771 // TemplateLiteral |
1748 | 1772 |
1749 int pos = peek_position(); | 1773 int pos = peek_position(); |
1750 ExpressionT result = this->EmptyExpression(); | 1774 ExpressionT result = this->EmptyExpression(); |
1751 Token::Value token = peek(); | 1775 Token::Value token = peek(); |
1752 switch (token) { | 1776 switch (token) { |
1753 case Token::THIS: { | 1777 case Token::THIS: { |
1754 Consume(Token::THIS); | 1778 Consume(Token::THIS); |
1755 scope_->RecordThisUsage(); | 1779 scope_->RecordThisUsage(); |
1756 result = this->ThisExpression(scope_, factory()); | 1780 result = this->ThisExpression(scope_, factory()); |
1757 break; | 1781 break; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1833 } | 1857 } |
1834 | 1858 |
1835 case Token::MOD: | 1859 case Token::MOD: |
1836 if (allow_natives_syntax() || extension_ != NULL) { | 1860 if (allow_natives_syntax() || extension_ != NULL) { |
1837 result = this->ParseV8Intrinsic(CHECK_OK); | 1861 result = this->ParseV8Intrinsic(CHECK_OK); |
1838 break; | 1862 break; |
1839 } | 1863 } |
1840 // If we're not allowing special syntax we fall-through to the | 1864 // If we're not allowing special syntax we fall-through to the |
1841 // default case. | 1865 // default case. |
1842 | 1866 |
| 1867 case Token::TEMPLATE_SPAN: { |
| 1868 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(); |
| 1869 // Add TV / TRV |
| 1870 Consume(Token::TEMPLATE_SPAN); |
| 1871 int pos = position(); |
| 1872 Traits::AddTemplateSpan(&ts); |
| 1873 |
| 1874 for (;;) { |
| 1875 Token::Value next = peek(); |
| 1876 if (next < 0) { |
| 1877 ReportMessage("unterminated_template"); |
| 1878 *ok = false; |
| 1879 return Traits::EmptyExpression(); |
| 1880 } |
| 1881 |
| 1882 // Parse an Expression |
| 1883 ExpressionT expression = this->ParseExpression(false, CHECK_OK); |
| 1884 Traits::AddTemplateExpression(&ts, expression); |
| 1885 |
| 1886 // If we didn't die parsing that expression, our next token should be a |
| 1887 // TEMPLATE_SPAN or |
| 1888 // TEMPLATE_TAIL. |
| 1889 next = Next(Scanner::TemplateLiteral); |
| 1890 if (next == Token::ILLEGAL || next < 0) { |
| 1891 ReportMessage("unterminated_template"); |
| 1892 *ok = false; |
| 1893 return Traits::EmptyExpression(); |
| 1894 } |
| 1895 |
| 1896 CHECK(next == Token::TEMPLATE_SPAN || next == Token::TEMPLATE_TAIL); |
| 1897 Traits::AddTemplateSpan(&ts); |
| 1898 |
| 1899 if (next == Token::TEMPLATE_TAIL) { |
| 1900 break; |
| 1901 } |
| 1902 } |
| 1903 result = Traits::CloseTemplateLiteral(&ts, pos); |
| 1904 } break; |
| 1905 |
| 1906 case Token::TEMPLATE_TAIL: { |
| 1907 // Close TemplateLiteral |
| 1908 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(); |
| 1909 Consume(Token::TEMPLATE_TAIL); |
| 1910 int pos = position(); |
| 1911 Traits::AddTemplateSpan(&ts); |
| 1912 result = Traits::CloseTemplateLiteral(&ts, pos); |
| 1913 } break; |
| 1914 |
1843 default: { | 1915 default: { |
1844 Next(); | 1916 Next(); |
1845 ReportUnexpectedToken(token); | 1917 ReportUnexpectedToken(token); |
1846 *ok = false; | 1918 *ok = false; |
1847 } | 1919 } |
1848 } | 1920 } |
1849 | 1921 |
1850 return result; | 1922 return result; |
1851 } | 1923 } |
1852 | 1924 |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2436 // direct eval calls. These calls are all of the form eval(...), with | 2508 // direct eval calls. These calls are all of the form eval(...), with |
2437 // no explicit receiver. | 2509 // no explicit receiver. |
2438 // These calls are marked as potentially direct eval calls. Whether | 2510 // These calls are marked as potentially direct eval calls. Whether |
2439 // they are actually direct calls to eval is determined at run time. | 2511 // they are actually direct calls to eval is determined at run time. |
2440 this->CheckPossibleEvalCall(result, scope_); | 2512 this->CheckPossibleEvalCall(result, scope_); |
2441 result = factory()->NewCall(result, args, pos); | 2513 result = factory()->NewCall(result, args, pos); |
2442 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2514 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2443 break; | 2515 break; |
2444 } | 2516 } |
2445 | 2517 |
| 2518 case Token::TEMPLATE_SPAN: |
| 2519 case Token::TEMPLATE_TAIL: { |
| 2520 ExpressionT templateLiteral = ParsePrimaryExpression(CHECK_OK); |
| 2521 USE(templateLiteral); |
| 2522 // TODO: Make sure we can invoke the tag with the expected parameters. |
| 2523 break; |
| 2524 } |
| 2525 |
2446 case Token::PERIOD: { | 2526 case Token::PERIOD: { |
2447 Consume(Token::PERIOD); | 2527 Consume(Token::PERIOD); |
2448 int pos = position(); | 2528 int pos = position(); |
2449 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2529 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2450 result = factory()->NewProperty( | 2530 result = factory()->NewProperty( |
2451 result, factory()->NewStringLiteral(name, pos), pos); | 2531 result, factory()->NewStringLiteral(name, pos), pos); |
2452 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 2532 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
2453 break; | 2533 break; |
2454 } | 2534 } |
2455 | 2535 |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2831 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2911 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
2832 // Both accessors of the same type. | 2912 // Both accessors of the same type. |
2833 parser()->ReportMessage("accessor_get_set"); | 2913 parser()->ReportMessage("accessor_get_set"); |
2834 } | 2914 } |
2835 *ok = false; | 2915 *ok = false; |
2836 } | 2916 } |
2837 } | 2917 } |
2838 } } // v8::internal | 2918 } } // v8::internal |
2839 | 2919 |
2840 #endif // V8_PREPARSER_H | 2920 #endif // V8_PREPARSER_H |
OLD | NEW |