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 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 // whether it is strict mode future reserved. | 567 // whether it is strict mode future reserved. |
568 IdentifierT ParseIdentifierOrStrictReservedWord( | 568 IdentifierT ParseIdentifierOrStrictReservedWord( |
569 bool* is_strict_reserved, | 569 bool* is_strict_reserved, |
570 bool* ok); | 570 bool* ok); |
571 IdentifierT ParseIdentifierName(bool* ok); | 571 IdentifierT ParseIdentifierName(bool* ok); |
572 // Parses an identifier and determines whether or not it is 'get' or 'set'. | 572 // Parses an identifier and determines whether or not it is 'get' or 'set'. |
573 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, | 573 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, |
574 bool* is_set, | 574 bool* is_set, |
575 bool* ok); | 575 bool* ok); |
576 | 576 |
577 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); | |
578 | 577 |
579 ExpressionT ParsePrimaryExpression(bool* ok); | 578 class ExpressionClassifier { |
rossberg
2015/04/22 09:30:47
Don't we also want is_valid_arrow_parameter_list,
Dmitry Lomov (no reviews)
2015/04/22 09:36:55
Sounds good, but I'd prefer to do that in a separa
| |
579 public: | |
580 ExpressionClassifier() | |
581 : expression_error_(Scanner::Location::invalid()), | |
582 binding_pattern_error_(Scanner::Location::invalid()), | |
583 assignment_pattern_error_(Scanner::Location::invalid()) {} | |
584 | |
585 bool is_valid_expression() const { | |
586 return expression_error_ == Scanner::Location::invalid(); | |
587 } | |
588 | |
589 bool is_valid_binding_pattern() const { | |
590 return binding_pattern_error_ == Scanner::Location::invalid(); | |
591 } | |
592 | |
593 bool is_valid_assignmnent_pattern() const { | |
594 return assignment_pattern_error_ == Scanner::Location::invalid(); | |
595 } | |
596 | |
597 void RecordExpressionError(const Scanner::Location& loc) { | |
598 if (!is_valid_expression()) return; | |
599 expression_error_ = loc; | |
600 } | |
601 | |
602 void RecordBindingPatternError(const Scanner::Location& loc) { | |
603 if (!is_valid_binding_pattern()) return; | |
604 binding_pattern_error_ = loc; | |
605 } | |
606 | |
607 void RecordAssignmentPatternError(const Scanner::Location& loc) { | |
608 if (!is_valid_assignmnent_pattern()) return; | |
609 assignment_pattern_error_ = loc; | |
610 } | |
611 | |
612 private: | |
613 Scanner::Location expression_error_; | |
614 Scanner::Location binding_pattern_error_; | |
615 Scanner::Location assignment_pattern_error_; | |
616 }; | |
617 | |
618 ExpressionT ParseRegExpLiteral(bool seen_equal, | |
619 ExpressionClassifier* classifier, bool* ok); | |
620 | |
621 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | |
622 bool* ok); | |
580 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 623 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
581 ExpressionT ParseArrayLiteral(bool* ok); | 624 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
625 bool* ok); | |
626 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | |
582 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 627 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
583 bool* is_static, bool* is_computed_name, | 628 bool* is_static, bool* is_computed_name, |
584 bool* ok); | 629 ExpressionClassifier* classifier, bool* ok); |
585 ExpressionT ParseObjectLiteral(bool* ok); | 630 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
586 ObjectLiteralPropertyT ParsePropertyDefinition( | 631 ObjectLiteralPropertyT ParsePropertyDefinition( |
587 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 632 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
588 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 633 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
634 ExpressionClassifier* classifier, bool* ok); | |
635 typename Traits::Type::ExpressionList ParseArguments( | |
636 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | |
589 bool* ok); | 637 bool* ok); |
590 typename Traits::Type::ExpressionList ParseArguments( | 638 ExpressionT ParseAssignmentExpression(bool accept_IN, |
591 Scanner::Location* first_spread_pos, bool* ok); | 639 ExpressionClassifier* classifier, |
592 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 640 bool* ok); |
593 ExpressionT ParseYieldExpression(bool* ok); | 641 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
594 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 642 ExpressionT ParseConditionalExpression(bool accept_IN, |
595 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 643 ExpressionClassifier* classifier, |
596 ExpressionT ParseUnaryExpression(bool* ok); | 644 bool* ok); |
597 ExpressionT ParsePostfixExpression(bool* ok); | 645 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
598 ExpressionT ParseLeftHandSideExpression(bool* ok); | 646 ExpressionClassifier* classifier, bool* ok); |
599 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 647 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
600 ExpressionT ParseMemberExpression(bool* ok); | 648 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
601 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 649 bool* ok); |
602 bool* ok); | 650 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
651 bool* ok); | |
652 ExpressionT ParseMemberWithNewPrefixesExpression( | |
653 ExpressionClassifier* classifier, bool* ok); | |
654 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); | |
655 ExpressionT ParseMemberExpressionContinuation( | |
656 ExpressionT expression, ExpressionClassifier* classifier, bool* ok); | |
603 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 657 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
658 ExpressionClassifier* classifier, | |
604 bool* ok); | 659 bool* ok); |
605 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 660 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
661 ExpressionClassifier* classifier, bool* ok); | |
606 void AddTemplateExpression(ExpressionT); | 662 void AddTemplateExpression(ExpressionT); |
607 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 663 ExpressionT ParseSuperExpression(bool is_new, |
664 ExpressionClassifier* classifier, bool* ok); | |
608 | 665 |
609 // Checks if the expression is a valid reference expression (e.g., on the | 666 // Checks if the expression is a valid reference expression (e.g., on the |
610 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 667 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
611 // we allow calls for web compatibility and rewrite them to a runtime throw. | 668 // we allow calls for web compatibility and rewrite them to a runtime throw. |
612 ExpressionT CheckAndRewriteReferenceExpression( | 669 ExpressionT CheckAndRewriteReferenceExpression( |
613 ExpressionT expression, | 670 ExpressionT expression, |
614 Scanner::Location location, const char* message, bool* ok); | 671 Scanner::Location location, const char* message, bool* ok); |
615 | 672 |
616 // Used to validate property names in object literals and class literals | 673 // Used to validate property names in object literals and class literals |
617 enum PropertyKind { | 674 enum PropertyKind { |
(...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1923 bool* ok) { | 1980 bool* ok) { |
1924 IdentifierT result = ParseIdentifierName(ok); | 1981 IdentifierT result = ParseIdentifierName(ok); |
1925 if (!*ok) return Traits::EmptyIdentifier(); | 1982 if (!*ok) return Traits::EmptyIdentifier(); |
1926 scanner()->IsGetOrSet(is_get, is_set); | 1983 scanner()->IsGetOrSet(is_get, is_set); |
1927 return result; | 1984 return result; |
1928 } | 1985 } |
1929 | 1986 |
1930 | 1987 |
1931 template <class Traits> | 1988 template <class Traits> |
1932 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( | 1989 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( |
1933 bool seen_equal, bool* ok) { | 1990 bool seen_equal, ExpressionClassifier* classifier, bool* ok) { |
1934 int pos = peek_position(); | 1991 int pos = peek_position(); |
1935 if (!scanner()->ScanRegExpPattern(seen_equal)) { | 1992 if (!scanner()->ScanRegExpPattern(seen_equal)) { |
1936 Next(); | 1993 Next(); |
1937 ReportMessage("unterminated_regexp"); | 1994 ReportMessage("unterminated_regexp"); |
1938 *ok = false; | 1995 *ok = false; |
1939 return Traits::EmptyExpression(); | 1996 return Traits::EmptyExpression(); |
1940 } | 1997 } |
1941 | 1998 |
1942 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1999 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1943 | 2000 |
(...skipping 16 matching lines...) Expand all Loading... | |
1960 #define DUMMY ) // to make indentation work | 2017 #define DUMMY ) // to make indentation work |
1961 #undef DUMMY | 2018 #undef DUMMY |
1962 | 2019 |
1963 // Used in functions where the return type is not ExpressionT. | 2020 // Used in functions where the return type is not ExpressionT. |
1964 #define CHECK_OK_CUSTOM(x) ok); \ | 2021 #define CHECK_OK_CUSTOM(x) ok); \ |
1965 if (!*ok) return this->x(); \ | 2022 if (!*ok) return this->x(); \ |
1966 ((void)0 | 2023 ((void)0 |
1967 #define DUMMY ) // to make indentation work | 2024 #define DUMMY ) // to make indentation work |
1968 #undef DUMMY | 2025 #undef DUMMY |
1969 | 2026 |
2027 | |
2028 #define CHECK_CLASSIFIER_OK classifier, ok); \ | |
rossberg
2015/04/22 09:30:47
Don't think this macro is worth it. It saves a sin
Dmitry Lomov (no reviews)
2015/04/22 09:36:55
Yes, I think we should merge ok into a classifier
| |
2029 if (!*ok) return this->EmptyExpression(); \ | |
2030 ((void)0 | |
2031 #define DUMMY ) // to make indentation work | |
2032 #undef DUMMY | |
2033 | |
1970 template <class Traits> | 2034 template <class Traits> |
1971 typename ParserBase<Traits>::ExpressionT | 2035 typename ParserBase<Traits>::ExpressionT |
1972 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { | 2036 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
2037 bool* ok) { | |
1973 // PrimaryExpression :: | 2038 // PrimaryExpression :: |
1974 // 'this' | 2039 // 'this' |
1975 // 'null' | 2040 // 'null' |
1976 // 'true' | 2041 // 'true' |
1977 // 'false' | 2042 // 'false' |
1978 // Identifier | 2043 // Identifier |
1979 // Number | 2044 // Number |
1980 // String | 2045 // String |
1981 // ArrayLiteral | 2046 // ArrayLiteral |
1982 // ObjectLiteral | 2047 // ObjectLiteral |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2019 break; | 2084 break; |
2020 } | 2085 } |
2021 | 2086 |
2022 case Token::STRING: { | 2087 case Token::STRING: { |
2023 Consume(Token::STRING); | 2088 Consume(Token::STRING); |
2024 result = this->ExpressionFromString(beg_pos, scanner(), factory()); | 2089 result = this->ExpressionFromString(beg_pos, scanner(), factory()); |
2025 break; | 2090 break; |
2026 } | 2091 } |
2027 | 2092 |
2028 case Token::ASSIGN_DIV: | 2093 case Token::ASSIGN_DIV: |
2029 result = this->ParseRegExpLiteral(true, CHECK_OK); | 2094 result = this->ParseRegExpLiteral(true, CHECK_CLASSIFIER_OK); |
2030 break; | 2095 break; |
2031 | 2096 |
2032 case Token::DIV: | 2097 case Token::DIV: |
2033 result = this->ParseRegExpLiteral(false, CHECK_OK); | 2098 result = this->ParseRegExpLiteral(false, CHECK_CLASSIFIER_OK); |
2034 break; | 2099 break; |
2035 | 2100 |
2036 case Token::LBRACK: | 2101 case Token::LBRACK: |
2037 result = this->ParseArrayLiteral(CHECK_OK); | 2102 result = this->ParseArrayLiteral(CHECK_CLASSIFIER_OK); |
2038 break; | 2103 break; |
2039 | 2104 |
2040 case Token::LBRACE: | 2105 case Token::LBRACE: |
2041 result = this->ParseObjectLiteral(CHECK_OK); | 2106 result = this->ParseObjectLiteral(CHECK_CLASSIFIER_OK); |
2042 break; | 2107 break; |
2043 | 2108 |
2044 case Token::LPAREN: | 2109 case Token::LPAREN: |
2045 Consume(Token::LPAREN); | 2110 Consume(Token::LPAREN); |
2046 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { | 2111 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { |
2047 // Arrow functions are the only expression type constructions | 2112 // Arrow functions are the only expression type constructions |
2048 // for which an empty parameter list "()" is valid input. | 2113 // for which an empty parameter list "()" is valid input. |
2049 Consume(Token::RPAREN); | 2114 Consume(Token::RPAREN); |
2050 result = this->ParseArrowFunctionLiteral( | 2115 result = this->ParseArrowFunctionLiteral( |
2051 beg_pos, this->EmptyArrowParamList(), CHECK_OK); | 2116 beg_pos, this->EmptyArrowParamList(), CHECK_CLASSIFIER_OK); |
2052 } else { | 2117 } else { |
2053 // Heuristically try to detect immediately called functions before | 2118 // Heuristically try to detect immediately called functions before |
2054 // seeing the call parentheses. | 2119 // seeing the call parentheses. |
2055 parenthesized_function_ = (peek() == Token::FUNCTION); | 2120 parenthesized_function_ = (peek() == Token::FUNCTION); |
2056 result = this->ParseExpression(true, CHECK_OK); | 2121 result = this->ParseExpression(true, CHECK_CLASSIFIER_OK); |
2057 result->increase_parenthesization_level(); | 2122 result->increase_parenthesization_level(); |
2058 Expect(Token::RPAREN, CHECK_OK); | 2123 Expect(Token::RPAREN, CHECK_OK); |
2059 } | 2124 } |
2060 break; | 2125 break; |
2061 | 2126 |
2062 case Token::CLASS: { | 2127 case Token::CLASS: { |
2063 Consume(Token::CLASS); | 2128 Consume(Token::CLASS); |
2064 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2129 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2065 ReportMessage("sloppy_lexical", NULL); | 2130 ReportMessage("sloppy_lexical", NULL); |
2066 *ok = false; | 2131 *ok = false; |
(...skipping 10 matching lines...) Expand all Loading... | |
2077 } | 2142 } |
2078 result = this->ParseClassLiteral(name, class_name_location, | 2143 result = this->ParseClassLiteral(name, class_name_location, |
2079 is_strict_reserved_name, | 2144 is_strict_reserved_name, |
2080 class_token_position, CHECK_OK); | 2145 class_token_position, CHECK_OK); |
2081 break; | 2146 break; |
2082 } | 2147 } |
2083 | 2148 |
2084 case Token::TEMPLATE_SPAN: | 2149 case Token::TEMPLATE_SPAN: |
2085 case Token::TEMPLATE_TAIL: | 2150 case Token::TEMPLATE_TAIL: |
2086 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, | 2151 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, |
2087 CHECK_OK); | 2152 CHECK_CLASSIFIER_OK); |
2088 break; | 2153 break; |
2089 | 2154 |
2090 case Token::MOD: | 2155 case Token::MOD: |
2091 if (allow_natives() || extension_ != NULL) { | 2156 if (allow_natives() || extension_ != NULL) { |
2092 result = this->ParseV8Intrinsic(CHECK_OK); | 2157 result = this->ParseV8Intrinsic(CHECK_OK); |
2093 break; | 2158 break; |
2094 } | 2159 } |
2095 // If we're not allowing special syntax we fall-through to the | 2160 // If we're not allowing special syntax we fall-through to the |
2096 // default case. | 2161 // default case. |
2097 | 2162 |
2098 default: { | 2163 default: { |
2099 Next(); | 2164 Next(); |
2100 ReportUnexpectedToken(token); | 2165 ReportUnexpectedToken(token); |
2101 *ok = false; | 2166 *ok = false; |
2102 } | 2167 } |
2103 } | 2168 } |
2104 | 2169 |
2105 return result; | 2170 return result; |
2106 } | 2171 } |
2107 | 2172 |
2173 | |
2174 template <class Traits> | |
2175 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | |
2176 bool accept_IN, bool* ok) { | |
2177 ExpressionClassifier classifier; | |
2178 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | |
2179 // TODO(dslomov): report error if not a valid expression. | |
2180 return result; | |
2181 } | |
2182 | |
2183 | |
2108 // Precedence = 1 | 2184 // Precedence = 1 |
2109 template <class Traits> | 2185 template <class Traits> |
2110 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2186 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2111 bool accept_IN, bool* ok) { | 2187 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
2112 // Expression :: | 2188 // Expression :: |
2113 // AssignmentExpression | 2189 // AssignmentExpression |
2114 // Expression ',' AssignmentExpression | 2190 // Expression ',' AssignmentExpression |
2115 | 2191 |
2116 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2192 ExpressionT result = |
2193 this->ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); | |
2117 while (peek() == Token::COMMA) { | 2194 while (peek() == Token::COMMA) { |
2118 Expect(Token::COMMA, CHECK_OK); | 2195 Expect(Token::COMMA, CHECK_OK); |
2119 int pos = position(); | 2196 int pos = position(); |
2120 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2197 ExpressionT right = |
2198 this->ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); | |
2121 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2199 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
2122 } | 2200 } |
2123 return result; | 2201 return result; |
2124 } | 2202 } |
2125 | 2203 |
2126 | 2204 |
2127 template <class Traits> | 2205 template <class Traits> |
2128 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2206 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
2129 bool* ok) { | 2207 ExpressionClassifier* classifier, bool* ok) { |
2130 // ArrayLiteral :: | 2208 // ArrayLiteral :: |
2131 // '[' Expression? (',' Expression?)* ']' | 2209 // '[' Expression? (',' Expression?)* ']' |
2132 | 2210 |
2133 int pos = peek_position(); | 2211 int pos = peek_position(); |
2134 typename Traits::Type::ExpressionList values = | 2212 typename Traits::Type::ExpressionList values = |
2135 this->NewExpressionList(4, zone_); | 2213 this->NewExpressionList(4, zone_); |
2136 Expect(Token::LBRACK, CHECK_OK); | 2214 Expect(Token::LBRACK, CHECK_OK); |
2137 while (peek() != Token::RBRACK) { | 2215 while (peek() != Token::RBRACK) { |
2138 ExpressionT elem = this->EmptyExpression(); | 2216 ExpressionT elem = this->EmptyExpression(); |
2139 if (peek() == Token::COMMA) { | 2217 if (peek() == Token::COMMA) { |
2140 if (is_strong(language_mode())) { | 2218 if (is_strong(language_mode())) { |
2141 ReportMessageAt(scanner()->peek_location(), "strong_ellision"); | 2219 ReportMessageAt(scanner()->peek_location(), "strong_ellision"); |
2142 *ok = false; | 2220 *ok = false; |
2143 return this->EmptyExpression(); | 2221 return this->EmptyExpression(); |
2144 } | 2222 } |
2145 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2223 elem = this->GetLiteralTheHole(peek_position(), factory()); |
2146 } else { | 2224 } else { |
2147 elem = this->ParseAssignmentExpression(true, CHECK_OK); | 2225 elem = this->ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); |
2148 } | 2226 } |
2149 values->Add(elem, zone_); | 2227 values->Add(elem, zone_); |
2150 if (peek() != Token::RBRACK) { | 2228 if (peek() != Token::RBRACK) { |
2151 Expect(Token::COMMA, CHECK_OK); | 2229 Expect(Token::COMMA, CHECK_OK); |
2152 } | 2230 } |
2153 } | 2231 } |
2154 Expect(Token::RBRACK, CHECK_OK); | 2232 Expect(Token::RBRACK, CHECK_OK); |
2155 | 2233 |
2156 // Update the scope information before the pre-parsing bailout. | 2234 // Update the scope information before the pre-parsing bailout. |
2157 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2235 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
2158 | 2236 |
2159 return factory()->NewArrayLiteral(values, literal_index, pos); | 2237 return factory()->NewArrayLiteral(values, literal_index, pos); |
2160 } | 2238 } |
2161 | 2239 |
2162 | 2240 |
2163 template <class Traits> | 2241 template <class Traits> |
2164 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 2242 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
2165 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, | 2243 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, |
2166 bool* is_computed_name, bool* ok) { | 2244 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { |
2167 Token::Value token = peek(); | 2245 Token::Value token = peek(); |
2168 int pos = peek_position(); | 2246 int pos = peek_position(); |
2169 | 2247 |
2170 // For non computed property names we normalize the name a bit: | 2248 // For non computed property names we normalize the name a bit: |
2171 // | 2249 // |
2172 // "12" -> 12 | 2250 // "12" -> 12 |
2173 // 12.3 -> "12.3" | 2251 // 12.3 -> "12.3" |
2174 // 12.30 -> "12.3" | 2252 // 12.30 -> "12.3" |
2175 // identifier -> "identifier" | 2253 // identifier -> "identifier" |
2176 // | 2254 // |
(...skipping 12 matching lines...) Expand all Loading... | |
2189 | 2267 |
2190 case Token::NUMBER: | 2268 case Token::NUMBER: |
2191 Consume(Token::NUMBER); | 2269 Consume(Token::NUMBER); |
2192 *name = this->GetNumberAsSymbol(scanner()); | 2270 *name = this->GetNumberAsSymbol(scanner()); |
2193 break; | 2271 break; |
2194 | 2272 |
2195 case Token::LBRACK: | 2273 case Token::LBRACK: |
2196 if (allow_harmony_computed_property_names_) { | 2274 if (allow_harmony_computed_property_names_) { |
2197 *is_computed_name = true; | 2275 *is_computed_name = true; |
2198 Consume(Token::LBRACK); | 2276 Consume(Token::LBRACK); |
2199 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 2277 ExpressionT expression = |
2278 ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); | |
2200 Expect(Token::RBRACK, CHECK_OK); | 2279 Expect(Token::RBRACK, CHECK_OK); |
2201 return expression; | 2280 return expression; |
2202 } | 2281 } |
2203 | 2282 |
2204 // Fall through. | 2283 // Fall through. |
2205 case Token::STATIC: | 2284 case Token::STATIC: |
2206 *is_static = true; | 2285 *is_static = true; |
2207 | 2286 |
2208 // Fall through. | 2287 // Fall through. |
2209 default: | 2288 default: |
2210 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); | 2289 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); |
2211 break; | 2290 break; |
2212 } | 2291 } |
2213 | 2292 |
2214 uint32_t index; | 2293 uint32_t index; |
2215 return this->IsArrayIndex(*name, &index) | 2294 return this->IsArrayIndex(*name, &index) |
2216 ? factory()->NewNumberLiteral(index, pos) | 2295 ? factory()->NewNumberLiteral(index, pos) |
2217 : factory()->NewStringLiteral(*name, pos); | 2296 : factory()->NewStringLiteral(*name, pos); |
2218 } | 2297 } |
2219 | 2298 |
2220 | 2299 |
2221 template <class Traits> | 2300 template <class Traits> |
2222 typename ParserBase<Traits>::ObjectLiteralPropertyT | 2301 typename ParserBase<Traits>::ObjectLiteralPropertyT |
2223 ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, | 2302 ParserBase<Traits>::ParsePropertyDefinition( |
2224 bool in_class, bool has_extends, | 2303 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
2225 bool is_static, | 2304 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
2226 bool* is_computed_name, | 2305 ExpressionClassifier* classifier, bool* ok) { |
2227 bool* has_seen_constructor, | |
2228 bool* ok) { | |
2229 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 2306 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
2230 ExpressionT value = this->EmptyExpression(); | 2307 ExpressionT value = this->EmptyExpression(); |
2231 IdentifierT name = this->EmptyIdentifier(); | 2308 IdentifierT name = this->EmptyIdentifier(); |
2232 bool is_get = false; | 2309 bool is_get = false; |
2233 bool is_set = false; | 2310 bool is_set = false; |
2234 bool name_is_static = false; | 2311 bool name_is_static = false; |
2235 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); | 2312 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); |
2236 | 2313 |
2237 Token::Value name_token = peek(); | 2314 Token::Value name_token = peek(); |
2238 int next_beg_pos = scanner()->peek_location().beg_pos; | 2315 int next_beg_pos = scanner()->peek_location().beg_pos; |
2239 int next_end_pos = scanner()->peek_location().end_pos; | 2316 int next_end_pos = scanner()->peek_location().end_pos; |
2240 ExpressionT name_expression = ParsePropertyName( | 2317 ExpressionT name_expression = ParsePropertyName( |
2241 &name, &is_get, &is_set, &name_is_static, is_computed_name, | 2318 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, |
2242 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2319 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2243 | 2320 |
2244 if (fni_ != nullptr && !*is_computed_name) { | 2321 if (fni_ != nullptr && !*is_computed_name) { |
2245 this->PushLiteralName(fni_, name); | 2322 this->PushLiteralName(fni_, name); |
2246 } | 2323 } |
2247 | 2324 |
2248 if (!in_class && !is_generator && peek() == Token::COLON) { | 2325 if (!in_class && !is_generator && peek() == Token::COLON) { |
2249 // PropertyDefinition : PropertyName ':' AssignmentExpression | 2326 // PropertyDefinition : PropertyName ':' AssignmentExpression |
2250 if (!*is_computed_name) { | 2327 if (!*is_computed_name) { |
2251 checker->CheckProperty(name_token, kValueProperty, is_static, | 2328 checker->CheckProperty(name_token, kValueProperty, is_static, |
2252 is_generator, | 2329 is_generator, |
2253 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2330 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2254 } | 2331 } |
2255 Consume(Token::COLON); | 2332 Consume(Token::COLON); |
2256 value = this->ParseAssignmentExpression( | 2333 value = this->ParseAssignmentExpression( |
2257 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2334 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2258 | 2335 |
2259 } else if (is_generator || | 2336 } else if (is_generator || |
2260 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 2337 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
2261 // Concise Method | 2338 // Concise Method |
2262 if (!*is_computed_name) { | 2339 if (!*is_computed_name) { |
2263 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2340 checker->CheckProperty(name_token, kMethodProperty, is_static, |
2264 is_generator, | 2341 is_generator, |
2265 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2342 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2266 } | 2343 } |
2267 | 2344 |
(...skipping 15 matching lines...) Expand all Loading... | |
2283 FunctionLiteral::NORMAL_ARITY, | 2360 FunctionLiteral::NORMAL_ARITY, |
2284 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2361 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2285 | 2362 |
2286 return factory()->NewObjectLiteralProperty(name_expression, value, | 2363 return factory()->NewObjectLiteralProperty(name_expression, value, |
2287 ObjectLiteralProperty::COMPUTED, | 2364 ObjectLiteralProperty::COMPUTED, |
2288 is_static, *is_computed_name); | 2365 is_static, *is_computed_name); |
2289 | 2366 |
2290 } else if (in_class && name_is_static && !is_static) { | 2367 } else if (in_class && name_is_static && !is_static) { |
2291 // static MethodDefinition | 2368 // static MethodDefinition |
2292 return ParsePropertyDefinition(checker, true, has_extends, true, | 2369 return ParsePropertyDefinition(checker, true, has_extends, true, |
2293 is_computed_name, nullptr, ok); | 2370 is_computed_name, nullptr, classifier, ok); |
2294 } else if (is_get || is_set) { | 2371 } else if (is_get || is_set) { |
2295 // Accessor | 2372 // Accessor |
2296 name = this->EmptyIdentifier(); | 2373 name = this->EmptyIdentifier(); |
2297 bool dont_care = false; | 2374 bool dont_care = false; |
2298 name_token = peek(); | 2375 name_token = peek(); |
2299 | 2376 |
2300 name_expression = ParsePropertyName( | 2377 name_expression = ParsePropertyName( |
2301 &name, &dont_care, &dont_care, &dont_care, is_computed_name, | 2378 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
2302 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2379 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2303 | 2380 |
2304 if (!*is_computed_name) { | 2381 if (!*is_computed_name) { |
2305 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 2382 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
2306 is_generator, | 2383 is_generator, |
2307 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2384 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2308 } | 2385 } |
2309 | 2386 |
2310 FunctionKind kind = FunctionKind::kAccessorFunction; | 2387 FunctionKind kind = FunctionKind::kAccessorFunction; |
2311 if (!in_class) kind = WithObjectLiteralBit(kind); | 2388 if (!in_class) kind = WithObjectLiteralBit(kind); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2346 return this->EmptyObjectLiteralProperty(); | 2423 return this->EmptyObjectLiteralProperty(); |
2347 } | 2424 } |
2348 | 2425 |
2349 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, | 2426 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, |
2350 *is_computed_name); | 2427 *is_computed_name); |
2351 } | 2428 } |
2352 | 2429 |
2353 | 2430 |
2354 template <class Traits> | 2431 template <class Traits> |
2355 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 2432 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
2356 bool* ok) { | 2433 ExpressionClassifier* classifier, bool* ok) { |
2357 // ObjectLiteral :: | 2434 // ObjectLiteral :: |
2358 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2435 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2359 | 2436 |
2360 int pos = peek_position(); | 2437 int pos = peek_position(); |
2361 typename Traits::Type::PropertyList properties = | 2438 typename Traits::Type::PropertyList properties = |
2362 this->NewPropertyList(4, zone_); | 2439 this->NewPropertyList(4, zone_); |
2363 int number_of_boilerplate_properties = 0; | 2440 int number_of_boilerplate_properties = 0; |
2364 bool has_function = false; | 2441 bool has_function = false; |
2365 bool has_computed_names = false; | 2442 bool has_computed_names = false; |
2366 ObjectLiteralChecker checker(this); | 2443 ObjectLiteralChecker checker(this); |
2367 | 2444 |
2368 Expect(Token::LBRACE, CHECK_OK); | 2445 Expect(Token::LBRACE, CHECK_OK); |
2369 | 2446 |
2370 while (peek() != Token::RBRACE) { | 2447 while (peek() != Token::RBRACE) { |
2371 if (fni_ != nullptr) fni_->Enter(); | 2448 if (fni_ != nullptr) fni_->Enter(); |
2372 | 2449 |
2373 const bool in_class = false; | 2450 const bool in_class = false; |
2374 const bool is_static = false; | 2451 const bool is_static = false; |
2375 const bool has_extends = false; | 2452 const bool has_extends = false; |
2376 bool is_computed_name = false; | 2453 bool is_computed_name = false; |
2377 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 2454 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
2378 &checker, in_class, has_extends, is_static, &is_computed_name, NULL, | 2455 &checker, in_class, has_extends, is_static, &is_computed_name, NULL, |
2379 CHECK_OK); | 2456 CHECK_CLASSIFIER_OK); |
2380 | 2457 |
2381 if (is_computed_name) { | 2458 if (is_computed_name) { |
2382 has_computed_names = true; | 2459 has_computed_names = true; |
2383 } | 2460 } |
2384 | 2461 |
2385 // Mark top-level object literals that contain function literals and | 2462 // Mark top-level object literals that contain function literals and |
2386 // pretenure the literal so it can be added as a constant function | 2463 // pretenure the literal so it can be added as a constant function |
2387 // property. (Parser only.) | 2464 // property. (Parser only.) |
2388 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, | 2465 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, |
2389 &has_function); | 2466 &has_function); |
(...skipping 22 matching lines...) Expand all Loading... | |
2412 return factory()->NewObjectLiteral(properties, | 2489 return factory()->NewObjectLiteral(properties, |
2413 literal_index, | 2490 literal_index, |
2414 number_of_boilerplate_properties, | 2491 number_of_boilerplate_properties, |
2415 has_function, | 2492 has_function, |
2416 pos); | 2493 pos); |
2417 } | 2494 } |
2418 | 2495 |
2419 | 2496 |
2420 template <class Traits> | 2497 template <class Traits> |
2421 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2498 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
2422 Scanner::Location* first_spread_arg_loc, bool* ok) { | 2499 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier, |
2500 bool* ok) { | |
2423 // Arguments :: | 2501 // Arguments :: |
2424 // '(' (AssignmentExpression)*[','] ')' | 2502 // '(' (AssignmentExpression)*[','] ')' |
2425 | 2503 |
2426 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2504 Scanner::Location spread_arg = Scanner::Location::invalid(); |
2427 typename Traits::Type::ExpressionList result = | 2505 typename Traits::Type::ExpressionList result = |
2428 this->NewExpressionList(4, zone_); | 2506 this->NewExpressionList(4, zone_); |
2429 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2507 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2430 bool done = (peek() == Token::RPAREN); | 2508 bool done = (peek() == Token::RPAREN); |
2431 bool was_unspread = false; | 2509 bool was_unspread = false; |
2432 int unspread_sequences_count = 0; | 2510 int unspread_sequences_count = 0; |
2433 while (!done) { | 2511 while (!done) { |
2434 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); | 2512 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); |
2435 int start_pos = peek_position(); | 2513 int start_pos = peek_position(); |
2436 if (is_spread) Consume(Token::ELLIPSIS); | 2514 if (is_spread) Consume(Token::ELLIPSIS); |
2437 | 2515 |
2438 ExpressionT argument = this->ParseAssignmentExpression( | 2516 ExpressionT argument = this->ParseAssignmentExpression( |
2439 true, CHECK_OK_CUSTOM(NullExpressionList)); | 2517 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
2440 if (is_spread) { | 2518 if (is_spread) { |
2441 if (!spread_arg.IsValid()) { | 2519 if (!spread_arg.IsValid()) { |
2442 spread_arg.beg_pos = start_pos; | 2520 spread_arg.beg_pos = start_pos; |
2443 spread_arg.end_pos = peek_position(); | 2521 spread_arg.end_pos = peek_position(); |
2444 } | 2522 } |
2445 argument = factory()->NewSpread(argument, start_pos); | 2523 argument = factory()->NewSpread(argument, start_pos); |
2446 } | 2524 } |
2447 result->Add(argument, zone_); | 2525 result->Add(argument, zone_); |
2448 | 2526 |
2449 // unspread_sequences_count is the number of sequences of parameters which | 2527 // unspread_sequences_count is the number of sequences of parameters which |
(...skipping 29 matching lines...) Expand all Loading... | |
2479 // the parser and preparser | 2557 // the parser and preparser |
2480 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2558 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
2481 } | 2559 } |
2482 | 2560 |
2483 return result; | 2561 return result; |
2484 } | 2562 } |
2485 | 2563 |
2486 // Precedence = 2 | 2564 // Precedence = 2 |
2487 template <class Traits> | 2565 template <class Traits> |
2488 typename ParserBase<Traits>::ExpressionT | 2566 typename ParserBase<Traits>::ExpressionT |
2489 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2567 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
2568 ExpressionClassifier* classifier, | |
2569 bool* ok) { | |
2490 // AssignmentExpression :: | 2570 // AssignmentExpression :: |
2491 // ConditionalExpression | 2571 // ConditionalExpression |
2492 // ArrowFunction | 2572 // ArrowFunction |
2493 // YieldExpression | 2573 // YieldExpression |
2494 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2574 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2495 | 2575 |
2496 Scanner::Location lhs_location = scanner()->peek_location(); | 2576 Scanner::Location lhs_location = scanner()->peek_location(); |
2497 | 2577 |
2498 if (peek() == Token::YIELD && is_generator()) { | 2578 if (peek() == Token::YIELD && is_generator()) { |
2499 return this->ParseYieldExpression(ok); | 2579 return this->ParseYieldExpression(classifier, ok); |
2500 } | 2580 } |
2501 | 2581 |
2502 if (fni_ != NULL) fni_->Enter(); | 2582 if (fni_ != NULL) fni_->Enter(); |
2503 ParserBase<Traits>::Checkpoint checkpoint(this); | 2583 ParserBase<Traits>::Checkpoint checkpoint(this); |
2504 ExpressionT expression = | 2584 ExpressionT expression = |
2505 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2585 this->ParseConditionalExpression(accept_IN, CHECK_CLASSIFIER_OK); |
2506 | 2586 |
2507 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2587 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
2508 checkpoint.Restore(); | 2588 checkpoint.Restore(); |
2509 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | 2589 expression = this->ParseArrowFunctionLiteral( |
2510 expression, CHECK_OK); | 2590 lhs_location.beg_pos, expression, CHECK_CLASSIFIER_OK); |
2511 return expression; | 2591 return expression; |
2512 } | 2592 } |
2513 | 2593 |
2514 if (!Token::IsAssignmentOp(peek())) { | 2594 if (!Token::IsAssignmentOp(peek())) { |
2515 if (fni_ != NULL) fni_->Leave(); | 2595 if (fni_ != NULL) fni_->Leave(); |
2516 // Parsed conditional expression only (no assignment). | 2596 // Parsed conditional expression only (no assignment). |
2517 return expression; | 2597 return expression; |
2518 } | 2598 } |
2519 | 2599 |
2520 expression = this->CheckAndRewriteReferenceExpression( | 2600 expression = this->CheckAndRewriteReferenceExpression( |
2521 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2601 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
2522 expression = this->MarkExpressionAsAssigned(expression); | 2602 expression = this->MarkExpressionAsAssigned(expression); |
2523 | 2603 |
2524 Token::Value op = Next(); // Get assignment operator. | 2604 Token::Value op = Next(); // Get assignment operator. |
2525 int pos = position(); | 2605 int pos = position(); |
2526 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2606 ExpressionT right = |
2607 this->ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); | |
2527 | 2608 |
2528 // TODO(1231235): We try to estimate the set of properties set by | 2609 // TODO(1231235): We try to estimate the set of properties set by |
2529 // constructors. We define a new property whenever there is an | 2610 // constructors. We define a new property whenever there is an |
2530 // assignment to a property of 'this'. We should probably only add | 2611 // assignment to a property of 'this'. We should probably only add |
2531 // properties if we haven't seen them before. Otherwise we'll | 2612 // properties if we haven't seen them before. Otherwise we'll |
2532 // probably overestimate the number of properties. | 2613 // probably overestimate the number of properties. |
2533 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 2614 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
2534 function_state_->AddProperty(); | 2615 function_state_->AddProperty(); |
2535 } | 2616 } |
2536 | 2617 |
(...skipping 12 matching lines...) Expand all Loading... | |
2549 fni_->RemoveLastFunction(); | 2630 fni_->RemoveLastFunction(); |
2550 } | 2631 } |
2551 fni_->Leave(); | 2632 fni_->Leave(); |
2552 } | 2633 } |
2553 | 2634 |
2554 return factory()->NewAssignment(op, expression, right, pos); | 2635 return factory()->NewAssignment(op, expression, right, pos); |
2555 } | 2636 } |
2556 | 2637 |
2557 template <class Traits> | 2638 template <class Traits> |
2558 typename ParserBase<Traits>::ExpressionT | 2639 typename ParserBase<Traits>::ExpressionT |
2559 ParserBase<Traits>::ParseYieldExpression(bool* ok) { | 2640 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
2641 bool* ok) { | |
2560 // YieldExpression :: | 2642 // YieldExpression :: |
2561 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2643 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
2562 int pos = peek_position(); | 2644 int pos = peek_position(); |
2563 Expect(Token::YIELD, CHECK_OK); | 2645 Expect(Token::YIELD, CHECK_OK); |
2564 ExpressionT generator_object = | 2646 ExpressionT generator_object = |
2565 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 2647 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
2566 ExpressionT expression = Traits::EmptyExpression(); | 2648 ExpressionT expression = Traits::EmptyExpression(); |
2567 Yield::Kind kind = Yield::kSuspend; | 2649 Yield::Kind kind = Yield::kSuspend; |
2568 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | 2650 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { |
2569 if (Check(Token::MUL)) kind = Yield::kDelegating; | 2651 if (Check(Token::MUL)) kind = Yield::kDelegating; |
2570 switch (peek()) { | 2652 switch (peek()) { |
2571 case Token::EOS: | 2653 case Token::EOS: |
2572 case Token::SEMICOLON: | 2654 case Token::SEMICOLON: |
2573 case Token::RBRACE: | 2655 case Token::RBRACE: |
2574 case Token::RBRACK: | 2656 case Token::RBRACK: |
2575 case Token::RPAREN: | 2657 case Token::RPAREN: |
2576 case Token::COLON: | 2658 case Token::COLON: |
2577 case Token::COMMA: | 2659 case Token::COMMA: |
2578 // The above set of tokens is the complete set of tokens that can appear | 2660 // The above set of tokens is the complete set of tokens that can appear |
2579 // after an AssignmentExpression, and none of them can start an | 2661 // after an AssignmentExpression, and none of them can start an |
2580 // AssignmentExpression. This allows us to avoid looking for an RHS for | 2662 // AssignmentExpression. This allows us to avoid looking for an RHS for |
2581 // a Yield::kSuspend operation, given only one look-ahead token. | 2663 // a Yield::kSuspend operation, given only one look-ahead token. |
2582 if (kind == Yield::kSuspend) | 2664 if (kind == Yield::kSuspend) |
2583 break; | 2665 break; |
2584 DCHECK_EQ(Yield::kDelegating, kind); | 2666 DCHECK_EQ(Yield::kDelegating, kind); |
2585 // Delegating yields require an RHS; fall through. | 2667 // Delegating yields require an RHS; fall through. |
2586 default: | 2668 default: |
2587 expression = ParseAssignmentExpression(false, CHECK_OK); | 2669 expression = ParseAssignmentExpression(false, CHECK_CLASSIFIER_OK); |
2588 break; | 2670 break; |
2589 } | 2671 } |
2590 } | 2672 } |
2591 if (kind == Yield::kDelegating) { | 2673 if (kind == Yield::kDelegating) { |
2592 // var iterator = subject[Symbol.iterator](); | 2674 // var iterator = subject[Symbol.iterator](); |
2593 expression = this->GetIterator(expression, factory()); | 2675 expression = this->GetIterator(expression, factory()); |
2594 } | 2676 } |
2595 typename Traits::Type::YieldExpression yield = | 2677 typename Traits::Type::YieldExpression yield = |
2596 factory()->NewYield(generator_object, expression, kind, pos); | 2678 factory()->NewYield(generator_object, expression, kind, pos); |
2597 if (kind == Yield::kDelegating) { | 2679 if (kind == Yield::kDelegating) { |
2598 yield->set_index(function_state_->NextHandlerIndex()); | 2680 yield->set_index(function_state_->NextHandlerIndex()); |
2599 } | 2681 } |
2600 return yield; | 2682 return yield; |
2601 } | 2683 } |
2602 | 2684 |
2603 | 2685 |
2604 // Precedence = 3 | 2686 // Precedence = 3 |
2605 template <class Traits> | 2687 template <class Traits> |
2606 typename ParserBase<Traits>::ExpressionT | 2688 typename ParserBase<Traits>::ExpressionT |
2607 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2689 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, |
2690 ExpressionClassifier* classifier, | |
2691 bool* ok) { | |
2608 // ConditionalExpression :: | 2692 // ConditionalExpression :: |
2609 // LogicalOrExpression | 2693 // LogicalOrExpression |
2610 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2694 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
2611 | 2695 |
2612 int pos = peek_position(); | 2696 int pos = peek_position(); |
2613 // We start using the binary expression parser for prec >= 4 only! | 2697 // We start using the binary expression parser for prec >= 4 only! |
2614 ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK); | 2698 ExpressionT expression = |
2699 this->ParseBinaryExpression(4, accept_IN, CHECK_CLASSIFIER_OK); | |
2615 if (peek() != Token::CONDITIONAL) return expression; | 2700 if (peek() != Token::CONDITIONAL) return expression; |
2616 Consume(Token::CONDITIONAL); | 2701 Consume(Token::CONDITIONAL); |
2617 // In parsing the first assignment expression in conditional | 2702 // In parsing the first assignment expression in conditional |
2618 // expressions we always accept the 'in' keyword; see ECMA-262, | 2703 // expressions we always accept the 'in' keyword; see ECMA-262, |
2619 // section 11.12, page 58. | 2704 // section 11.12, page 58. |
2620 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); | 2705 ExpressionT left = ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); |
2621 Expect(Token::COLON, CHECK_OK); | 2706 Expect(Token::COLON, CHECK_OK); |
2622 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2707 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); |
2623 return factory()->NewConditional(expression, left, right, pos); | 2708 return factory()->NewConditional(expression, left, right, pos); |
2624 } | 2709 } |
2625 | 2710 |
2626 | 2711 |
2627 // Precedence >= 4 | 2712 // Precedence >= 4 |
2628 template <class Traits> | 2713 template <class Traits> |
2629 typename ParserBase<Traits>::ExpressionT | 2714 typename ParserBase<Traits>::ExpressionT |
2630 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 2715 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
2716 ExpressionClassifier* classifier, | |
2717 bool* ok) { | |
2631 DCHECK(prec >= 4); | 2718 DCHECK(prec >= 4); |
2632 ExpressionT x = this->ParseUnaryExpression(CHECK_OK); | 2719 ExpressionT x = this->ParseUnaryExpression(CHECK_CLASSIFIER_OK); |
2633 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2720 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2634 // prec1 >= 4 | 2721 // prec1 >= 4 |
2635 while (Precedence(peek(), accept_IN) == prec1) { | 2722 while (Precedence(peek(), accept_IN) == prec1) { |
2636 Token::Value op = Next(); | 2723 Token::Value op = Next(); |
2637 Scanner::Location op_location = scanner()->location(); | 2724 Scanner::Location op_location = scanner()->location(); |
2638 int pos = position(); | 2725 int pos = position(); |
2639 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 2726 ExpressionT y = |
2727 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_CLASSIFIER_OK); | |
2640 | 2728 |
2641 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2729 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
2642 factory())) { | 2730 factory())) { |
2643 continue; | 2731 continue; |
2644 } | 2732 } |
2645 | 2733 |
2646 // For now we distinguish between comparisons and other binary | 2734 // For now we distinguish between comparisons and other binary |
2647 // operations. (We could combine the two and get rid of this | 2735 // operations. (We could combine the two and get rid of this |
2648 // code and AST node eventually.) | 2736 // code and AST node eventually.) |
2649 if (Token::IsCompareOp(op)) { | 2737 if (Token::IsCompareOp(op)) { |
(...skipping 20 matching lines...) Expand all Loading... | |
2670 x = factory()->NewBinaryOperation(op, x, y, pos); | 2758 x = factory()->NewBinaryOperation(op, x, y, pos); |
2671 } | 2759 } |
2672 } | 2760 } |
2673 } | 2761 } |
2674 return x; | 2762 return x; |
2675 } | 2763 } |
2676 | 2764 |
2677 | 2765 |
2678 template <class Traits> | 2766 template <class Traits> |
2679 typename ParserBase<Traits>::ExpressionT | 2767 typename ParserBase<Traits>::ExpressionT |
2680 ParserBase<Traits>::ParseUnaryExpression(bool* ok) { | 2768 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, |
2769 bool* ok) { | |
2681 // UnaryExpression :: | 2770 // UnaryExpression :: |
2682 // PostfixExpression | 2771 // PostfixExpression |
2683 // 'delete' UnaryExpression | 2772 // 'delete' UnaryExpression |
2684 // 'void' UnaryExpression | 2773 // 'void' UnaryExpression |
2685 // 'typeof' UnaryExpression | 2774 // 'typeof' UnaryExpression |
2686 // '++' UnaryExpression | 2775 // '++' UnaryExpression |
2687 // '--' UnaryExpression | 2776 // '--' UnaryExpression |
2688 // '+' UnaryExpression | 2777 // '+' UnaryExpression |
2689 // '-' UnaryExpression | 2778 // '-' UnaryExpression |
2690 // '~' UnaryExpression | 2779 // '~' UnaryExpression |
2691 // '!' UnaryExpression | 2780 // '!' UnaryExpression |
2692 | 2781 |
2693 Token::Value op = peek(); | 2782 Token::Value op = peek(); |
2694 if (Token::IsUnaryOp(op)) { | 2783 if (Token::IsUnaryOp(op)) { |
2695 op = Next(); | 2784 op = Next(); |
2696 int pos = position(); | 2785 int pos = position(); |
2697 ExpressionT expression = ParseUnaryExpression(CHECK_OK); | 2786 ExpressionT expression = ParseUnaryExpression(CHECK_CLASSIFIER_OK); |
2698 | 2787 |
2699 if (op == Token::DELETE && is_strict(language_mode())) { | 2788 if (op == Token::DELETE && is_strict(language_mode())) { |
2700 if (is_strong(language_mode())) { | 2789 if (is_strong(language_mode())) { |
2701 ReportMessage("strong_delete"); | 2790 ReportMessage("strong_delete"); |
2702 *ok = false; | 2791 *ok = false; |
2703 return this->EmptyExpression(); | 2792 return this->EmptyExpression(); |
2704 } else if (this->IsIdentifier(expression)) { | 2793 } else if (this->IsIdentifier(expression)) { |
2705 // "delete identifier" is a syntax error in strict mode. | 2794 // "delete identifier" is a syntax error in strict mode. |
2706 ReportMessage("strict_delete"); | 2795 ReportMessage("strict_delete"); |
2707 *ok = false; | 2796 *ok = false; |
2708 return this->EmptyExpression(); | 2797 return this->EmptyExpression(); |
2709 } | 2798 } |
2710 } | 2799 } |
2711 | 2800 |
2712 // Allow Traits do rewrite the expression. | 2801 // Allow Traits do rewrite the expression. |
2713 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2802 return this->BuildUnaryExpression(expression, op, pos, factory()); |
2714 } else if (Token::IsCountOp(op)) { | 2803 } else if (Token::IsCountOp(op)) { |
2715 op = Next(); | 2804 op = Next(); |
2716 Scanner::Location lhs_location = scanner()->peek_location(); | 2805 Scanner::Location lhs_location = scanner()->peek_location(); |
2717 ExpressionT expression = this->ParseUnaryExpression(CHECK_OK); | 2806 ExpressionT expression = this->ParseUnaryExpression(CHECK_CLASSIFIER_OK); |
2718 expression = this->CheckAndRewriteReferenceExpression( | 2807 expression = this->CheckAndRewriteReferenceExpression( |
2719 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); | 2808 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); |
2720 this->MarkExpressionAsAssigned(expression); | 2809 this->MarkExpressionAsAssigned(expression); |
2721 | 2810 |
2722 return factory()->NewCountOperation(op, | 2811 return factory()->NewCountOperation(op, |
2723 true /* prefix */, | 2812 true /* prefix */, |
2724 expression, | 2813 expression, |
2725 position()); | 2814 position()); |
2726 | 2815 |
2727 } else { | 2816 } else { |
2728 return this->ParsePostfixExpression(ok); | 2817 return this->ParsePostfixExpression(classifier, ok); |
2729 } | 2818 } |
2730 } | 2819 } |
2731 | 2820 |
2732 | 2821 |
2733 template <class Traits> | 2822 template <class Traits> |
2734 typename ParserBase<Traits>::ExpressionT | 2823 typename ParserBase<Traits>::ExpressionT |
2735 ParserBase<Traits>::ParsePostfixExpression(bool* ok) { | 2824 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
2825 bool* ok) { | |
2736 // PostfixExpression :: | 2826 // PostfixExpression :: |
2737 // LeftHandSideExpression ('++' | '--')? | 2827 // LeftHandSideExpression ('++' | '--')? |
2738 | 2828 |
2739 Scanner::Location lhs_location = scanner()->peek_location(); | 2829 Scanner::Location lhs_location = scanner()->peek_location(); |
2740 ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK); | 2830 ExpressionT expression = |
2831 this->ParseLeftHandSideExpression(CHECK_CLASSIFIER_OK); | |
2741 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2832 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2742 Token::IsCountOp(peek())) { | 2833 Token::IsCountOp(peek())) { |
2743 expression = this->CheckAndRewriteReferenceExpression( | 2834 expression = this->CheckAndRewriteReferenceExpression( |
2744 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); | 2835 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); |
2745 expression = this->MarkExpressionAsAssigned(expression); | 2836 expression = this->MarkExpressionAsAssigned(expression); |
2746 | 2837 |
2747 Token::Value next = Next(); | 2838 Token::Value next = Next(); |
2748 expression = | 2839 expression = |
2749 factory()->NewCountOperation(next, | 2840 factory()->NewCountOperation(next, |
2750 false /* postfix */, | 2841 false /* postfix */, |
2751 expression, | 2842 expression, |
2752 position()); | 2843 position()); |
2753 } | 2844 } |
2754 return expression; | 2845 return expression; |
2755 } | 2846 } |
2756 | 2847 |
2757 | 2848 |
2758 template <class Traits> | 2849 template <class Traits> |
2759 typename ParserBase<Traits>::ExpressionT | 2850 typename ParserBase<Traits>::ExpressionT |
2760 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) { | 2851 ParserBase<Traits>::ParseLeftHandSideExpression( |
2852 ExpressionClassifier* classifier, bool* ok) { | |
2761 // LeftHandSideExpression :: | 2853 // LeftHandSideExpression :: |
2762 // (NewExpression | MemberExpression) ... | 2854 // (NewExpression | MemberExpression) ... |
2763 | 2855 |
2764 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2856 ExpressionT result = |
2857 this->ParseMemberWithNewPrefixesExpression(CHECK_CLASSIFIER_OK); | |
2765 | 2858 |
2766 while (true) { | 2859 while (true) { |
2767 switch (peek()) { | 2860 switch (peek()) { |
2768 case Token::LBRACK: { | 2861 case Token::LBRACK: { |
2769 Consume(Token::LBRACK); | 2862 Consume(Token::LBRACK); |
2770 int pos = position(); | 2863 int pos = position(); |
2771 ExpressionT index = ParseExpression(true, CHECK_OK); | 2864 ExpressionT index = ParseExpression(true, CHECK_CLASSIFIER_OK); |
2772 result = factory()->NewProperty(result, index, pos); | 2865 result = factory()->NewProperty(result, index, pos); |
2773 Expect(Token::RBRACK, CHECK_OK); | 2866 Expect(Token::RBRACK, CHECK_OK); |
2774 break; | 2867 break; |
2775 } | 2868 } |
2776 | 2869 |
2777 case Token::LPAREN: { | 2870 case Token::LPAREN: { |
2778 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 2871 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
2779 this->IsEval(this->AsIdentifier(result))) { | 2872 this->IsEval(this->AsIdentifier(result))) { |
2780 ReportMessage("strong_direct_eval"); | 2873 ReportMessage("strong_direct_eval"); |
2781 *ok = false; | 2874 *ok = false; |
(...skipping 13 matching lines...) Expand all Loading... | |
2795 pos = peek_position(); | 2888 pos = peek_position(); |
2796 // Also the trailing parenthesis are a hint that the function will | 2889 // Also the trailing parenthesis are a hint that the function will |
2797 // be called immediately. If we happen to have parsed a preceding | 2890 // be called immediately. If we happen to have parsed a preceding |
2798 // function literal eagerly, we can also compile it eagerly. | 2891 // function literal eagerly, we can also compile it eagerly. |
2799 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2892 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
2800 result->AsFunctionLiteral()->set_parenthesized(); | 2893 result->AsFunctionLiteral()->set_parenthesized(); |
2801 } | 2894 } |
2802 } | 2895 } |
2803 Scanner::Location spread_pos; | 2896 Scanner::Location spread_pos; |
2804 typename Traits::Type::ExpressionList args = | 2897 typename Traits::Type::ExpressionList args = |
2805 ParseArguments(&spread_pos, CHECK_OK); | 2898 ParseArguments(&spread_pos, CHECK_CLASSIFIER_OK); |
2806 | 2899 |
2807 // Keep track of eval() calls since they disable all local variable | 2900 // Keep track of eval() calls since they disable all local variable |
2808 // optimizations. | 2901 // optimizations. |
2809 // The calls that need special treatment are the | 2902 // The calls that need special treatment are the |
2810 // direct eval calls. These calls are all of the form eval(...), with | 2903 // direct eval calls. These calls are all of the form eval(...), with |
2811 // no explicit receiver. | 2904 // no explicit receiver. |
2812 // These calls are marked as potentially direct eval calls. Whether | 2905 // These calls are marked as potentially direct eval calls. Whether |
2813 // they are actually direct calls to eval is determined at run time. | 2906 // they are actually direct calls to eval is determined at run time. |
2814 this->CheckPossibleEvalCall(result, scope_); | 2907 this->CheckPossibleEvalCall(result, scope_); |
2815 | 2908 |
(...skipping 19 matching lines...) Expand all Loading... | |
2835 | 2928 |
2836 default: | 2929 default: |
2837 return result; | 2930 return result; |
2838 } | 2931 } |
2839 } | 2932 } |
2840 } | 2933 } |
2841 | 2934 |
2842 | 2935 |
2843 template <class Traits> | 2936 template <class Traits> |
2844 typename ParserBase<Traits>::ExpressionT | 2937 typename ParserBase<Traits>::ExpressionT |
2845 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { | 2938 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( |
2939 ExpressionClassifier* classifier, bool* ok) { | |
2846 // NewExpression :: | 2940 // NewExpression :: |
2847 // ('new')+ MemberExpression | 2941 // ('new')+ MemberExpression |
2848 | 2942 |
2849 // The grammar for new expressions is pretty warped. We can have several 'new' | 2943 // The grammar for new expressions is pretty warped. We can have several 'new' |
2850 // keywords following each other, and then a MemberExpression. When we see '(' | 2944 // keywords following each other, and then a MemberExpression. When we see '(' |
2851 // after the MemberExpression, it's associated with the rightmost unassociated | 2945 // after the MemberExpression, it's associated with the rightmost unassociated |
2852 // 'new' to create a NewExpression with arguments. However, a NewExpression | 2946 // 'new' to create a NewExpression with arguments. However, a NewExpression |
2853 // can also occur without arguments. | 2947 // can also occur without arguments. |
2854 | 2948 |
2855 // Examples of new expression: | 2949 // Examples of new expression: |
2856 // new foo.bar().baz means (new (foo.bar)()).baz | 2950 // new foo.bar().baz means (new (foo.bar)()).baz |
2857 // new foo()() means (new foo())() | 2951 // new foo()() means (new foo())() |
2858 // new new foo()() means (new (new foo())()) | 2952 // new new foo()() means (new (new foo())()) |
2859 // new new foo means new (new foo) | 2953 // new new foo means new (new foo) |
2860 // new new foo() means new (new foo()) | 2954 // new new foo() means new (new foo()) |
2861 // new new foo().bar().baz means (new (new foo()).bar()).baz | 2955 // new new foo().bar().baz means (new (new foo()).bar()).baz |
2862 | 2956 |
2863 if (peek() == Token::NEW) { | 2957 if (peek() == Token::NEW) { |
2864 Consume(Token::NEW); | 2958 Consume(Token::NEW); |
2865 int new_pos = position(); | 2959 int new_pos = position(); |
2866 ExpressionT result = this->EmptyExpression(); | 2960 ExpressionT result = this->EmptyExpression(); |
2867 if (peek() == Token::SUPER) { | 2961 if (peek() == Token::SUPER) { |
2868 const bool is_new = true; | 2962 const bool is_new = true; |
2869 result = ParseSuperExpression(is_new, CHECK_OK); | 2963 result = ParseSuperExpression(is_new, CHECK_CLASSIFIER_OK); |
2870 } else { | 2964 } else { |
2871 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2965 result = this->ParseMemberWithNewPrefixesExpression(CHECK_CLASSIFIER_OK); |
2872 } | 2966 } |
2873 if (peek() == Token::LPAREN) { | 2967 if (peek() == Token::LPAREN) { |
2874 // NewExpression with arguments. | 2968 // NewExpression with arguments. |
2875 Scanner::Location spread_pos; | 2969 Scanner::Location spread_pos; |
2876 typename Traits::Type::ExpressionList args = | 2970 typename Traits::Type::ExpressionList args = |
2877 this->ParseArguments(&spread_pos, CHECK_OK); | 2971 this->ParseArguments(&spread_pos, CHECK_CLASSIFIER_OK); |
2878 | 2972 |
2879 if (spread_pos.IsValid()) { | 2973 if (spread_pos.IsValid()) { |
2880 args = Traits::PrepareSpreadArguments(args); | 2974 args = Traits::PrepareSpreadArguments(args); |
2881 result = Traits::SpreadCallNew(result, args, new_pos); | 2975 result = Traits::SpreadCallNew(result, args, new_pos); |
2882 } else { | 2976 } else { |
2883 result = factory()->NewCallNew(result, args, new_pos); | 2977 result = factory()->NewCallNew(result, args, new_pos); |
2884 } | 2978 } |
2885 // The expression can still continue with . or [ after the arguments. | 2979 // The expression can still continue with . or [ after the arguments. |
2886 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2980 result = |
2981 this->ParseMemberExpressionContinuation(result, CHECK_CLASSIFIER_OK); | |
2887 return result; | 2982 return result; |
2888 } | 2983 } |
2889 // NewExpression without arguments. | 2984 // NewExpression without arguments. |
2890 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2985 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
2891 new_pos); | 2986 new_pos); |
2892 } | 2987 } |
2893 // No 'new' or 'super' keyword. | 2988 // No 'new' or 'super' keyword. |
2894 return this->ParseMemberExpression(ok); | 2989 return this->ParseMemberExpression(classifier, ok); |
2895 } | 2990 } |
2896 | 2991 |
2897 | 2992 |
2898 template <class Traits> | 2993 template <class Traits> |
2899 typename ParserBase<Traits>::ExpressionT | 2994 typename ParserBase<Traits>::ExpressionT |
2900 ParserBase<Traits>::ParseMemberExpression(bool* ok) { | 2995 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, |
2996 bool* ok) { | |
2901 // MemberExpression :: | 2997 // MemberExpression :: |
2902 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 2998 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
2903 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 2999 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
2904 | 3000 |
2905 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3001 // The '[' Expression ']' and '.' Identifier parts are parsed by |
2906 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3002 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
2907 // caller. | 3003 // caller. |
2908 | 3004 |
2909 // Parse the initial primary or function expression. | 3005 // Parse the initial primary or function expression. |
2910 ExpressionT result = this->EmptyExpression(); | 3006 ExpressionT result = this->EmptyExpression(); |
(...skipping 13 matching lines...) Expand all Loading... | |
2924 function_type = FunctionLiteral::NAMED_EXPRESSION; | 3020 function_type = FunctionLiteral::NAMED_EXPRESSION; |
2925 } | 3021 } |
2926 result = this->ParseFunctionLiteral( | 3022 result = this->ParseFunctionLiteral( |
2927 name, function_name_location, is_strict_reserved_name, | 3023 name, function_name_location, is_strict_reserved_name, |
2928 is_generator ? FunctionKind::kGeneratorFunction | 3024 is_generator ? FunctionKind::kGeneratorFunction |
2929 : FunctionKind::kNormalFunction, | 3025 : FunctionKind::kNormalFunction, |
2930 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, | 3026 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, |
2931 CHECK_OK); | 3027 CHECK_OK); |
2932 } else if (peek() == Token::SUPER) { | 3028 } else if (peek() == Token::SUPER) { |
2933 const bool is_new = false; | 3029 const bool is_new = false; |
2934 result = ParseSuperExpression(is_new, CHECK_OK); | 3030 result = ParseSuperExpression(is_new, CHECK_CLASSIFIER_OK); |
2935 } else { | 3031 } else { |
2936 result = ParsePrimaryExpression(CHECK_OK); | 3032 result = ParsePrimaryExpression(CHECK_CLASSIFIER_OK); |
2937 } | 3033 } |
2938 | 3034 |
2939 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 3035 result = ParseMemberExpressionContinuation(result, CHECK_CLASSIFIER_OK); |
2940 return result; | 3036 return result; |
2941 } | 3037 } |
2942 | 3038 |
2943 | 3039 |
2944 template <class Traits> | 3040 template <class Traits> |
2945 typename ParserBase<Traits>::ExpressionT | 3041 typename ParserBase<Traits>::ExpressionT |
2946 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { | 3042 ParserBase<Traits>::ParseSuperExpression(bool is_new, |
3043 ExpressionClassifier* classifier, | |
3044 bool* ok) { | |
2947 Expect(Token::SUPER, CHECK_OK); | 3045 Expect(Token::SUPER, CHECK_OK); |
2948 | 3046 |
2949 FunctionState* function_state = function_state_; | 3047 FunctionState* function_state = function_state_; |
2950 while (IsArrowFunction(function_state->kind())) { | 3048 while (IsArrowFunction(function_state->kind())) { |
2951 function_state = function_state->outer(); | 3049 function_state = function_state->outer(); |
2952 } | 3050 } |
2953 // TODO(arv): Handle eval scopes similarly. | 3051 // TODO(arv): Handle eval scopes similarly. |
2954 | 3052 |
2955 FunctionKind kind = function_state->kind(); | 3053 FunctionKind kind = function_state->kind(); |
2956 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 3054 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
(...skipping 23 matching lines...) Expand all Loading... | |
2980 } | 3078 } |
2981 | 3079 |
2982 ReportMessageAt(scanner()->location(), "unexpected_super"); | 3080 ReportMessageAt(scanner()->location(), "unexpected_super"); |
2983 *ok = false; | 3081 *ok = false; |
2984 return this->EmptyExpression(); | 3082 return this->EmptyExpression(); |
2985 } | 3083 } |
2986 | 3084 |
2987 | 3085 |
2988 template <class Traits> | 3086 template <class Traits> |
2989 typename ParserBase<Traits>::ExpressionT | 3087 typename ParserBase<Traits>::ExpressionT |
2990 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, | 3088 ParserBase<Traits>::ParseMemberExpressionContinuation( |
2991 bool* ok) { | 3089 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
2992 // Parses this part of MemberExpression: | 3090 // Parses this part of MemberExpression: |
2993 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3091 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
2994 while (true) { | 3092 while (true) { |
2995 switch (peek()) { | 3093 switch (peek()) { |
2996 case Token::LBRACK: { | 3094 case Token::LBRACK: { |
2997 Consume(Token::LBRACK); | 3095 Consume(Token::LBRACK); |
2998 int pos = position(); | 3096 int pos = position(); |
2999 ExpressionT index = this->ParseExpression(true, CHECK_OK); | 3097 ExpressionT index = this->ParseExpression(true, CHECK_CLASSIFIER_OK); |
3000 expression = factory()->NewProperty(expression, index, pos); | 3098 expression = factory()->NewProperty(expression, index, pos); |
3001 if (fni_ != NULL) { | 3099 if (fni_ != NULL) { |
3002 this->PushPropertyName(fni_, index); | 3100 this->PushPropertyName(fni_, index); |
3003 } | 3101 } |
3004 Expect(Token::RBRACK, CHECK_OK); | 3102 Expect(Token::RBRACK, CHECK_OK); |
3005 break; | 3103 break; |
3006 } | 3104 } |
3007 case Token::PERIOD: { | 3105 case Token::PERIOD: { |
3008 Consume(Token::PERIOD); | 3106 Consume(Token::PERIOD); |
3009 int pos = position(); | 3107 int pos = position(); |
(...skipping 11 matching lines...) Expand all Loading... | |
3021 if (scanner()->current_token() == Token::IDENTIFIER) { | 3119 if (scanner()->current_token() == Token::IDENTIFIER) { |
3022 pos = position(); | 3120 pos = position(); |
3023 } else { | 3121 } else { |
3024 pos = peek_position(); | 3122 pos = peek_position(); |
3025 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3123 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
3026 // If the tag function looks like an IIFE, set_parenthesized() to | 3124 // If the tag function looks like an IIFE, set_parenthesized() to |
3027 // force eager compilation. | 3125 // force eager compilation. |
3028 expression->AsFunctionLiteral()->set_parenthesized(); | 3126 expression->AsFunctionLiteral()->set_parenthesized(); |
3029 } | 3127 } |
3030 } | 3128 } |
3031 expression = ParseTemplateLiteral(expression, pos, CHECK_OK); | 3129 expression = ParseTemplateLiteral(expression, pos, CHECK_CLASSIFIER_OK); |
3032 break; | 3130 break; |
3033 } | 3131 } |
3034 default: | 3132 default: |
3035 return expression; | 3133 return expression; |
3036 } | 3134 } |
3037 } | 3135 } |
3038 DCHECK(false); | 3136 DCHECK(false); |
3039 return this->EmptyExpression(); | 3137 return this->EmptyExpression(); |
3040 } | 3138 } |
3041 | 3139 |
3042 | 3140 |
3043 template <class Traits> | 3141 template <class Traits> |
3044 typename ParserBase<Traits>::ExpressionT | 3142 typename ParserBase<Traits>::ExpressionT |
3045 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | 3143 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
3046 ExpressionT params_ast, | 3144 ExpressionT params_ast, |
3145 ExpressionClassifier* classifier, | |
3047 bool* ok) { | 3146 bool* ok) { |
3048 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3147 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3049 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3148 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3050 // `=> ...` is never a valid expression, so report as syntax error. | 3149 // `=> ...` is never a valid expression, so report as syntax error. |
3051 // If next token is not `=>`, it's a syntax error anyways. | 3150 // If next token is not `=>`, it's a syntax error anyways. |
3052 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3151 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3053 *ok = false; | 3152 *ok = false; |
3054 return this->EmptyExpression(); | 3153 return this->EmptyExpression(); |
3055 } | 3154 } |
3056 | 3155 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3108 Token::INIT_VAR, kArrowFunction, CHECK_OK); | 3207 Token::INIT_VAR, kArrowFunction, CHECK_OK); |
3109 materialized_literal_count = | 3208 materialized_literal_count = |
3110 function_state.materialized_literal_count(); | 3209 function_state.materialized_literal_count(); |
3111 expected_property_count = function_state.expected_property_count(); | 3210 expected_property_count = function_state.expected_property_count(); |
3112 handler_count = function_state.handler_count(); | 3211 handler_count = function_state.handler_count(); |
3113 } | 3212 } |
3114 } else { | 3213 } else { |
3115 // Single-expression body | 3214 // Single-expression body |
3116 int pos = position(); | 3215 int pos = position(); |
3117 parenthesized_function_ = false; | 3216 parenthesized_function_ = false; |
3118 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 3217 ExpressionT expression = |
3218 ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); | |
3119 body = this->NewStatementList(1, zone()); | 3219 body = this->NewStatementList(1, zone()); |
3120 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3220 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3121 materialized_literal_count = function_state.materialized_literal_count(); | 3221 materialized_literal_count = function_state.materialized_literal_count(); |
3122 expected_property_count = function_state.expected_property_count(); | 3222 expected_property_count = function_state.expected_property_count(); |
3123 handler_count = function_state.handler_count(); | 3223 handler_count = function_state.handler_count(); |
3124 } | 3224 } |
3125 super_loc = function_state.super_call_location(); | 3225 super_loc = function_state.super_call_location(); |
3126 | 3226 |
3127 scope->set_start_position(start_pos); | 3227 scope->set_start_position(start_pos); |
3128 scope->set_end_position(scanner()->location().end_pos); | 3228 scope->set_end_position(scanner()->location().end_pos); |
(...skipping 28 matching lines...) Expand all Loading... | |
3157 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); | 3257 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); |
3158 | 3258 |
3159 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3259 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
3160 | 3260 |
3161 return function_literal; | 3261 return function_literal; |
3162 } | 3262 } |
3163 | 3263 |
3164 | 3264 |
3165 template <typename Traits> | 3265 template <typename Traits> |
3166 typename ParserBase<Traits>::ExpressionT | 3266 typename ParserBase<Traits>::ExpressionT |
3167 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { | 3267 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, |
3268 ExpressionClassifier* classifier, | |
3269 bool* ok) { | |
3168 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 3270 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
3169 // text followed by a substitution expression), finalized by a single | 3271 // text followed by a substitution expression), finalized by a single |
3170 // TEMPLATE_TAIL. | 3272 // TEMPLATE_TAIL. |
3171 // | 3273 // |
3172 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or | 3274 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or |
3173 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or | 3275 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or |
3174 // NoSubstitutionTemplate. | 3276 // NoSubstitutionTemplate. |
3175 // | 3277 // |
3176 // When parsing a TemplateLiteral, we must have scanned either an initial | 3278 // When parsing a TemplateLiteral, we must have scanned either an initial |
3177 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. | 3279 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3209 return Traits::EmptyExpression(); | 3311 return Traits::EmptyExpression(); |
3210 } else if (next == Token::ILLEGAL) { | 3312 } else if (next == Token::ILLEGAL) { |
3211 Traits::ReportMessageAt( | 3313 Traits::ReportMessageAt( |
3212 Scanner::Location(position() + 1, peek_position()), | 3314 Scanner::Location(position() + 1, peek_position()), |
3213 "unexpected_token", "ILLEGAL", kSyntaxError); | 3315 "unexpected_token", "ILLEGAL", kSyntaxError); |
3214 *ok = false; | 3316 *ok = false; |
3215 return Traits::EmptyExpression(); | 3317 return Traits::EmptyExpression(); |
3216 } | 3318 } |
3217 | 3319 |
3218 int expr_pos = peek_position(); | 3320 int expr_pos = peek_position(); |
3219 ExpressionT expression = this->ParseExpression(true, CHECK_OK); | 3321 ExpressionT expression = this->ParseExpression(true, CHECK_CLASSIFIER_OK); |
3220 Traits::AddTemplateExpression(&ts, expression); | 3322 Traits::AddTemplateExpression(&ts, expression); |
3221 | 3323 |
3222 if (peek() != Token::RBRACE) { | 3324 if (peek() != Token::RBRACE) { |
3223 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3325 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
3224 "unterminated_template_expr"); | 3326 "unterminated_template_expr"); |
3225 *ok = false; | 3327 *ok = false; |
3226 return Traits::EmptyExpression(); | 3328 return Traits::EmptyExpression(); |
3227 } | 3329 } |
3228 | 3330 |
3229 // If we didn't die parsing that expression, our next token should be a | 3331 // If we didn't die parsing that expression, our next token should be a |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3341 *ok = false; | 3443 *ok = false; |
3342 return; | 3444 return; |
3343 } | 3445 } |
3344 has_seen_constructor_ = true; | 3446 has_seen_constructor_ = true; |
3345 return; | 3447 return; |
3346 } | 3448 } |
3347 } | 3449 } |
3348 } } // v8::internal | 3450 } } // v8::internal |
3349 | 3451 |
3350 #endif // V8_PREPARSER_H | 3452 #endif // V8_PREPARSER_H |
OLD | NEW |