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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 // typedef ObjectLiteralProperty; | 71 // typedef ObjectLiteralProperty; |
72 // typedef Literal; | 72 // typedef Literal; |
73 // typedef ExpressionList; | 73 // typedef ExpressionList; |
74 // typedef PropertyList; | 74 // typedef PropertyList; |
75 // // For constructing objects returned by the traversing functions. | 75 // // For constructing objects returned by the traversing functions. |
76 // typedef Factory; | 76 // typedef Factory; |
77 // }; | 77 // }; |
78 // // ... | 78 // // ... |
79 // }; | 79 // }; |
80 | 80 |
81 enum FunctionParsingMode { | |
82 kNormalFunction, | |
83 kArrowFunction, | |
84 kGeneratorFunction | |
85 }; | |
86 | |
87 | |
81 template <typename Traits> | 88 template <typename Traits> |
82 class ParserBase : public Traits { | 89 class ParserBase : public Traits { |
83 public: | 90 public: |
84 // Shorten type names defined by Traits. | 91 // Shorten type names defined by Traits. |
85 typedef typename Traits::Type::Expression ExpressionT; | 92 typedef typename Traits::Type::Expression ExpressionT; |
86 typedef typename Traits::Type::Identifier IdentifierT; | 93 typedef typename Traits::Type::Identifier IdentifierT; |
87 | 94 |
88 ParserBase(Scanner* scanner, uintptr_t stack_limit, | 95 ParserBase(Scanner* scanner, uintptr_t stack_limit, |
89 v8::Extension* extension, | 96 v8::Extension* extension, |
90 ParserRecorder* log, | 97 ParserRecorder* log, |
91 typename Traits::Type::Zone* zone, | 98 typename Traits::Type::Zone* zone, |
92 typename Traits::Type::Parser this_object) | 99 typename Traits::Type::Parser this_object) |
93 : Traits(this_object), | 100 : Traits(this_object), |
94 parenthesized_function_(false), | 101 parenthesized_function_(false), |
95 scope_(NULL), | 102 scope_(NULL), |
96 function_state_(NULL), | 103 function_state_(NULL), |
97 extension_(extension), | 104 extension_(extension), |
98 fni_(NULL), | 105 fni_(NULL), |
99 log_(log), | 106 log_(log), |
100 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 107 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
101 scanner_(scanner), | 108 scanner_(scanner), |
102 stack_limit_(stack_limit), | 109 stack_limit_(stack_limit), |
103 stack_overflow_(false), | 110 stack_overflow_(false), |
104 allow_lazy_(false), | 111 allow_lazy_(false), |
105 allow_natives_syntax_(false), | 112 allow_natives_syntax_(false), |
106 allow_generators_(false), | 113 allow_generators_(false), |
107 allow_for_of_(false), | 114 allow_for_of_(false), |
115 allow_arrow_functions_(false), | |
108 zone_(zone) { } | 116 zone_(zone) { } |
109 | 117 |
110 // Getters that indicate whether certain syntactical constructs are | 118 // Getters that indicate whether certain syntactical constructs are |
111 // allowed to be parsed by this instance of the parser. | 119 // allowed to be parsed by this instance of the parser. |
112 bool allow_lazy() const { return allow_lazy_; } | 120 bool allow_lazy() const { return allow_lazy_; } |
113 bool allow_natives_syntax() const { return allow_natives_syntax_; } | 121 bool allow_natives_syntax() const { return allow_natives_syntax_; } |
114 bool allow_generators() const { return allow_generators_; } | 122 bool allow_generators() const { return allow_generators_; } |
115 bool allow_for_of() const { return allow_for_of_; } | 123 bool allow_for_of() const { return allow_for_of_; } |
124 bool allow_arrow_functions() const { return allow_arrow_functions_; } | |
116 bool allow_modules() const { return scanner()->HarmonyModules(); } | 125 bool allow_modules() const { return scanner()->HarmonyModules(); } |
117 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 126 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
118 bool allow_harmony_numeric_literals() const { | 127 bool allow_harmony_numeric_literals() const { |
119 return scanner()->HarmonyNumericLiterals(); | 128 return scanner()->HarmonyNumericLiterals(); |
120 } | 129 } |
121 | 130 |
122 // Setters that determine whether certain syntactical constructs are | 131 // Setters that determine whether certain syntactical constructs are |
123 // allowed to be parsed by this instance of the parser. | 132 // allowed to be parsed by this instance of the parser. |
124 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 133 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
125 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } | 134 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } |
126 void set_allow_generators(bool allow) { allow_generators_ = allow; } | 135 void set_allow_generators(bool allow) { allow_generators_ = allow; } |
127 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 136 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
137 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } | |
128 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 138 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
129 void set_allow_harmony_scoping(bool allow) { | 139 void set_allow_harmony_scoping(bool allow) { |
130 scanner()->SetHarmonyScoping(allow); | 140 scanner()->SetHarmonyScoping(allow); |
131 } | 141 } |
132 void set_allow_harmony_numeric_literals(bool allow) { | 142 void set_allow_harmony_numeric_literals(bool allow) { |
133 scanner()->SetHarmonyNumericLiterals(allow); | 143 scanner()->SetHarmonyNumericLiterals(allow); |
134 } | 144 } |
135 | 145 |
136 protected: | 146 protected: |
137 enum AllowEvalOrArgumentsAsIdentifier { | 147 enum AllowEvalOrArgumentsAsIdentifier { |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
494 | 504 |
495 private: | 505 private: |
496 Scanner* scanner_; | 506 Scanner* scanner_; |
497 uintptr_t stack_limit_; | 507 uintptr_t stack_limit_; |
498 bool stack_overflow_; | 508 bool stack_overflow_; |
499 | 509 |
500 bool allow_lazy_; | 510 bool allow_lazy_; |
501 bool allow_natives_syntax_; | 511 bool allow_natives_syntax_; |
502 bool allow_generators_; | 512 bool allow_generators_; |
503 bool allow_for_of_; | 513 bool allow_for_of_; |
514 bool allow_arrow_functions_; | |
504 | 515 |
505 typename Traits::Type::Zone* zone_; // Only used by Parser. | 516 typename Traits::Type::Zone* zone_; // Only used by Parser. |
506 }; | 517 }; |
507 | 518 |
508 | 519 |
509 class PreParserIdentifier { | 520 class PreParserIdentifier { |
510 public: | 521 public: |
511 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 522 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
512 static PreParserIdentifier Default() { | 523 static PreParserIdentifier Default() { |
513 return PreParserIdentifier(kUnknownIdentifier); | 524 return PreParserIdentifier(kUnknownIdentifier); |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
983 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 994 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
984 return PreParserExpressionList(); | 995 return PreParserExpressionList(); |
985 } | 996 } |
986 | 997 |
987 // Temporary glue; these functions will move to ParserBase. | 998 // Temporary glue; these functions will move to ParserBase. |
988 PreParserExpression ParseV8Intrinsic(bool* ok); | 999 PreParserExpression ParseV8Intrinsic(bool* ok); |
989 PreParserExpression ParseFunctionLiteral( | 1000 PreParserExpression ParseFunctionLiteral( |
990 PreParserIdentifier name, | 1001 PreParserIdentifier name, |
991 Scanner::Location function_name_location, | 1002 Scanner::Location function_name_location, |
992 bool name_is_strict_reserved, | 1003 bool name_is_strict_reserved, |
993 bool is_generator, | 1004 FunctionParsingMode parsing_mode, |
1005 PreParserExpression params_ast, | |
994 int function_token_position, | 1006 int function_token_position, |
995 FunctionLiteral::FunctionType type, | 1007 FunctionLiteral::FunctionType type, |
996 bool* ok); | 1008 bool* ok); |
997 | 1009 |
998 private: | 1010 private: |
999 PreParser* pre_parser_; | 1011 PreParser* pre_parser_; |
1000 }; | 1012 }; |
1001 | 1013 |
1002 | 1014 |
1003 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1015 // Preparsing checks a JavaScript program and emits preparse-data that helps |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1157 Statement ParseTryStatement(bool* ok); | 1169 Statement ParseTryStatement(bool* ok); |
1158 Statement ParseDebuggerStatement(bool* ok); | 1170 Statement ParseDebuggerStatement(bool* ok); |
1159 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1171 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
1160 Expression ParseObjectLiteral(bool* ok); | 1172 Expression ParseObjectLiteral(bool* ok); |
1161 Expression ParseV8Intrinsic(bool* ok); | 1173 Expression ParseV8Intrinsic(bool* ok); |
1162 | 1174 |
1163 Expression ParseFunctionLiteral( | 1175 Expression ParseFunctionLiteral( |
1164 Identifier name, | 1176 Identifier name, |
1165 Scanner::Location function_name_location, | 1177 Scanner::Location function_name_location, |
1166 bool name_is_strict_reserved, | 1178 bool name_is_strict_reserved, |
1167 bool is_generator, | 1179 FunctionParsingMode parsing_mode, |
1180 Expression params_ast, | |
1168 int function_token_pos, | 1181 int function_token_pos, |
1169 FunctionLiteral::FunctionType function_type, | 1182 FunctionLiteral::FunctionType function_type, |
1170 bool* ok); | 1183 bool* ok); |
1171 void ParseLazyFunctionLiteralBody(bool* ok); | 1184 void ParseLazyFunctionLiteralBody(bool* ok); |
1172 | 1185 |
1173 // Logs the currently parsed literal as a symbol in the preparser data. | 1186 // Logs the currently parsed literal as a symbol in the preparser data. |
1174 void LogSymbol(); | 1187 void LogSymbol(); |
1175 // Log the currently parsed string literal. | 1188 // Log the currently parsed string literal. |
1176 Expression GetStringSymbol(); | 1189 Expression GetStringSymbol(); |
1177 | 1190 |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1441 } | 1454 } |
1442 | 1455 |
1443 // Precedence = 1 | 1456 // Precedence = 1 |
1444 template <class Traits> | 1457 template <class Traits> |
1445 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1458 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
1446 bool accept_IN, bool* ok) { | 1459 bool accept_IN, bool* ok) { |
1447 // Expression :: | 1460 // Expression :: |
1448 // AssignmentExpression | 1461 // AssignmentExpression |
1449 // Expression ',' AssignmentExpression | 1462 // Expression ',' AssignmentExpression |
1450 | 1463 |
1464 if (allow_arrow_functions() && peek() == Token::RPAREN) { | |
marja
2014/03/24 09:04:06
This doesn't sound right. I guess the idea is that
aperez
2014/04/09 08:47:16
It was causing an unexpected token error most of t
| |
1465 // Empty argument list for arrow functions: () => ... | |
1466 return this->EmptyExpression(); | |
1467 } | |
1468 | |
1451 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 1469 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
1452 while (peek() == Token::COMMA) { | 1470 while (peek() == Token::COMMA) { |
1453 Expect(Token::COMMA, CHECK_OK); | 1471 Expect(Token::COMMA, CHECK_OK); |
1454 int pos = position(); | 1472 int pos = position(); |
1455 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 1473 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
1456 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 1474 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
1457 } | 1475 } |
1458 return result; | 1476 return result; |
1459 } | 1477 } |
1460 | 1478 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1543 return this->EmptyLiteral(); | 1561 return this->EmptyLiteral(); |
1544 } | 1562 } |
1545 // Validate the property. | 1563 // Validate the property. |
1546 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; | 1564 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; |
1547 checker.CheckProperty(next, type, CHECK_OK); | 1565 checker.CheckProperty(next, type, CHECK_OK); |
1548 IdentifierT name = this->GetSymbol(scanner_); | 1566 IdentifierT name = this->GetSymbol(scanner_); |
1549 typename Traits::Type::FunctionLiteral value = | 1567 typename Traits::Type::FunctionLiteral value = |
1550 this->ParseFunctionLiteral( | 1568 this->ParseFunctionLiteral( |
1551 name, scanner()->location(), | 1569 name, scanner()->location(), |
1552 false, // reserved words are allowed here | 1570 false, // reserved words are allowed here |
1553 false, // not a generator | 1571 kNormalFunction, |
1572 this->EmptyExpression(), | |
1554 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 1573 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
1555 CHECK_OK); | 1574 CHECK_OK); |
1556 // Allow any number of parameters for compatibilty with JSC. | 1575 // Allow any number of parameters for compatibilty with JSC. |
1557 // Specification only allows zero parameters for get and one for set. | 1576 // Specification only allows zero parameters for get and one for set. |
1558 typename Traits::Type::ObjectLiteralProperty property = | 1577 typename Traits::Type::ObjectLiteralProperty property = |
1559 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); | 1578 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); |
1560 if (this->IsBoilerplateProperty(property)) { | 1579 if (this->IsBoilerplateProperty(property)) { |
1561 number_of_boilerplate_properties++; | 1580 number_of_boilerplate_properties++; |
1562 } | 1581 } |
1563 properties->Add(property, zone()); | 1582 properties->Add(property, zone()); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1681 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1700 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1682 return result; | 1701 return result; |
1683 } | 1702 } |
1684 | 1703 |
1685 // Precedence = 2 | 1704 // Precedence = 2 |
1686 template <class Traits> | 1705 template <class Traits> |
1687 typename ParserBase<Traits>::ExpressionT | 1706 typename ParserBase<Traits>::ExpressionT |
1688 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 1707 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
1689 // AssignmentExpression :: | 1708 // AssignmentExpression :: |
1690 // ConditionalExpression | 1709 // ConditionalExpression |
1710 // ArrowFunction | |
1691 // YieldExpression | 1711 // YieldExpression |
1692 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 1712 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1693 | 1713 |
1694 Scanner::Location lhs_location = scanner()->peek_location(); | 1714 Scanner::Location lhs_location = scanner()->peek_location(); |
1695 | 1715 |
1696 if (peek() == Token::YIELD && is_generator()) { | 1716 if (peek() == Token::YIELD && is_generator()) { |
1697 return this->ParseYieldExpression(ok); | 1717 return this->ParseYieldExpression(ok); |
1698 } | 1718 } |
1699 | 1719 |
1700 if (fni_ != NULL) fni_->Enter(); | 1720 if (fni_ != NULL) fni_->Enter(); |
1701 ExpressionT expression = | 1721 ExpressionT expression = |
1702 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 1722 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
1703 | 1723 |
1724 if (allow_arrow_functions() && peek() == Token::ARROW) { | |
1725 return this->ParseFunctionLiteral(Traits::EmptyIdentifier(), | |
1726 Scanner::Location::invalid(), | |
1727 false, | |
1728 kArrowFunction, | |
1729 expression, | |
1730 lhs_location.beg_pos, | |
1731 FunctionLiteral::ANONYMOUS_EXPRESSION, | |
1732 CHECK_OK); | |
1733 } | |
1734 | |
1704 if (!Token::IsAssignmentOp(peek())) { | 1735 if (!Token::IsAssignmentOp(peek())) { |
1705 if (fni_ != NULL) fni_->Leave(); | 1736 if (fni_ != NULL) fni_->Leave(); |
1706 // Parsed conditional expression only (no assignment). | 1737 // Parsed conditional expression only (no assignment). |
1707 return expression; | 1738 return expression; |
1708 } | 1739 } |
1709 | 1740 |
1710 if (!expression->IsValidLeftHandSide()) { | 1741 if (!expression->IsValidLeftHandSide()) { |
1711 this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true); | 1742 this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true); |
1712 *ok = false; | 1743 *ok = false; |
1713 return this->EmptyExpression(); | 1744 return this->EmptyExpression(); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2055 | 2086 |
2056 // The '[' Expression ']' and '.' Identifier parts are parsed by | 2087 // The '[' Expression ']' and '.' Identifier parts are parsed by |
2057 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 2088 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
2058 // caller. | 2089 // caller. |
2059 | 2090 |
2060 // Parse the initial primary or function expression. | 2091 // Parse the initial primary or function expression. |
2061 ExpressionT result = this->EmptyExpression(); | 2092 ExpressionT result = this->EmptyExpression(); |
2062 if (peek() == Token::FUNCTION) { | 2093 if (peek() == Token::FUNCTION) { |
2063 Consume(Token::FUNCTION); | 2094 Consume(Token::FUNCTION); |
2064 int function_token_position = position(); | 2095 int function_token_position = position(); |
2065 bool is_generator = allow_generators() && Check(Token::MUL); | 2096 FunctionParsingMode parsing_mode = |
2097 (allow_generators() && Check(Token::MUL)) | |
2098 ? kGeneratorFunction | |
2099 : kNormalFunction; | |
2066 IdentifierT name; | 2100 IdentifierT name; |
2067 bool is_strict_reserved_name = false; | 2101 bool is_strict_reserved_name = false; |
2068 Scanner::Location function_name_location = Scanner::Location::invalid(); | 2102 Scanner::Location function_name_location = Scanner::Location::invalid(); |
2069 FunctionLiteral::FunctionType function_type = | 2103 FunctionLiteral::FunctionType function_type = |
2070 FunctionLiteral::ANONYMOUS_EXPRESSION; | 2104 FunctionLiteral::ANONYMOUS_EXPRESSION; |
2071 if (peek_any_identifier()) { | 2105 if (peek_any_identifier()) { |
2072 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 2106 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
2073 CHECK_OK); | 2107 CHECK_OK); |
2074 function_name_location = scanner()->location(); | 2108 function_name_location = scanner()->location(); |
2075 function_type = FunctionLiteral::NAMED_EXPRESSION; | 2109 function_type = FunctionLiteral::NAMED_EXPRESSION; |
2076 } | 2110 } |
2077 result = this->ParseFunctionLiteral(name, | 2111 result = this->ParseFunctionLiteral(name, |
2078 function_name_location, | 2112 function_name_location, |
2079 is_strict_reserved_name, | 2113 is_strict_reserved_name, |
2080 is_generator, | 2114 parsing_mode, |
2115 this->EmptyExpression(), | |
2081 function_token_position, | 2116 function_token_position, |
2082 function_type, | 2117 function_type, |
2083 CHECK_OK); | 2118 CHECK_OK); |
2084 } else { | 2119 } else { |
2085 result = ParsePrimaryExpression(CHECK_OK); | 2120 result = ParsePrimaryExpression(CHECK_OK); |
2086 } | 2121 } |
2087 | 2122 |
2088 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 2123 result = ParseMemberExpressionContinuation(result, CHECK_OK); |
2089 return result; | 2124 return result; |
2090 } | 2125 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2162 "accessor_get_set"); | 2197 "accessor_get_set"); |
2163 } | 2198 } |
2164 *ok = false; | 2199 *ok = false; |
2165 } | 2200 } |
2166 } | 2201 } |
2167 | 2202 |
2168 | 2203 |
2169 } } // v8::internal | 2204 } } // v8::internal |
2170 | 2205 |
2171 #endif // V8_PREPARSER_H | 2206 #endif // V8_PREPARSER_H |
OLD | NEW |