Chromium Code Reviews| 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 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 bool stack_overflow() const { return stack_overflow_; } | 331 bool stack_overflow() const { return stack_overflow_; } |
| 332 void set_stack_overflow() { stack_overflow_ = true; } | 332 void set_stack_overflow() { stack_overflow_ = true; } |
| 333 Mode mode() const { return mode_; } | 333 Mode mode() const { return mode_; } |
| 334 Zone* zone() const { return zone_; } | 334 Zone* zone() const { return zone_; } |
| 335 | 335 |
| 336 INLINE(Token::Value peek()) { | 336 INLINE(Token::Value peek()) { |
| 337 if (stack_overflow_) return Token::ILLEGAL; | 337 if (stack_overflow_) return Token::ILLEGAL; |
| 338 return scanner()->peek(); | 338 return scanner()->peek(); |
| 339 } | 339 } |
| 340 | 340 |
| 341 INLINE(Token::Value peek(int n)) { | |
| 342 if (stack_overflow_) return Token::ILLEGAL; | |
| 343 return scanner()->peek(n); | |
| 344 } | |
| 345 | |
| 341 INLINE(Token::Value Next()) { | 346 INLINE(Token::Value Next()) { |
| 342 if (stack_overflow_) return Token::ILLEGAL; | 347 if (stack_overflow_) return Token::ILLEGAL; |
| 343 { | 348 { |
| 344 if (GetCurrentStackPosition() < stack_limit_) { | 349 if (GetCurrentStackPosition() < stack_limit_) { |
| 345 // Any further calls to Next or peek will return the illegal token. | 350 // Any further calls to Next or peek will return the illegal token. |
| 346 // The current call must return the next token, which might already | 351 // The current call must return the next token, which might already |
| 347 // have been peek'ed. | 352 // have been peek'ed. |
| 348 stack_overflow_ = true; | 353 stack_overflow_ = true; |
| 349 } | 354 } |
| 350 } | 355 } |
| 351 return scanner()->Next(); | 356 return scanner()->Next(); |
| 352 } | 357 } |
| 353 | 358 |
| 359 void PeekScan(int until); | |
| 360 | |
| 354 void Consume(Token::Value token) { | 361 void Consume(Token::Value token) { |
| 355 Token::Value next = Next(); | 362 Token::Value next = Next(); |
| 356 USE(next); | 363 USE(next); |
| 357 USE(token); | 364 USE(token); |
| 358 DCHECK(next == token); | 365 DCHECK(next == token); |
| 359 } | 366 } |
| 360 | 367 |
| 361 bool Check(Token::Value token) { | 368 bool Check(Token::Value token) { |
| 362 Token::Value next = peek(); | 369 Token::Value next = peek(); |
| 363 if (next == token) { | 370 if (next == token) { |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 Traits::ReportMessageAt(source_location, message, arg, error_type); | 539 Traits::ReportMessageAt(source_location, message, arg, error_type); |
| 533 } | 540 } |
| 534 | 541 |
| 535 void ReportMessageAt(Scanner::Location location, const char* message, | 542 void ReportMessageAt(Scanner::Location location, const char* message, |
| 536 ParseErrorType error_type = kSyntaxError) { | 543 ParseErrorType error_type = kSyntaxError) { |
| 537 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), | 544 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), |
| 538 error_type); | 545 error_type); |
| 539 } | 546 } |
| 540 | 547 |
| 541 void ReportUnexpectedToken(Token::Value token); | 548 void ReportUnexpectedToken(Token::Value token); |
| 549 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); | |
| 542 | 550 |
| 543 // Recursive descent functions: | 551 // Recursive descent functions: |
| 544 | 552 |
| 545 // Parses an identifier that is valid for the current scope, in particular it | 553 // Parses an identifier that is valid for the current scope, in particular it |
| 546 // fails on strict mode future reserved keywords in a strict scope. If | 554 // fails on strict mode future reserved keywords in a strict scope. If |
| 547 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 555 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
| 548 // "arguments" as identifier even in strict mode (this is needed in cases like | 556 // "arguments" as identifier even in strict mode (this is needed in cases like |
| 549 // "var foo = eval;"). | 557 // "var foo = eval;"). |
| 550 IdentifierT ParseIdentifier( | 558 IdentifierT ParseIdentifier( |
| 551 AllowEvalOrArgumentsAsIdentifier, | 559 AllowEvalOrArgumentsAsIdentifier, |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 776 public: | 784 public: |
| 777 static PreParserExpression Default() { | 785 static PreParserExpression Default() { |
| 778 return PreParserExpression(TypeField::encode(kExpression)); | 786 return PreParserExpression(TypeField::encode(kExpression)); |
| 779 } | 787 } |
| 780 | 788 |
| 781 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 789 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
| 782 return PreParserExpression(TypeField::encode(kIdentifierExpression) | | 790 return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
| 783 IdentifierTypeField::encode(id.type_)); | 791 IdentifierTypeField::encode(id.type_)); |
| 784 } | 792 } |
| 785 | 793 |
| 794 static PreParserExpression SpreadOperation(PreParserExpression expr) { | |
| 795 return PreParserExpression(TypeField::encode( | |
| 796 kSpreadExpression) | expr.code_); | |
| 797 } | |
| 798 | |
| 786 static PreParserExpression BinaryOperation(PreParserExpression left, | 799 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 787 Token::Value op, | 800 Token::Value op, |
| 788 PreParserExpression right) { | 801 PreParserExpression right) { |
| 789 bool valid_arrow_param_list = | 802 bool valid_arrow_param_list = |
| 790 op == Token::COMMA && !left.is_parenthesized() && | 803 op == Token::COMMA && !left.is_parenthesized() && |
| 791 !right.is_parenthesized() && left.IsValidArrowParams() && | 804 !right.is_parenthesized() && left.IsValidArrowParams() && |
| 792 right.IsValidArrowParams(); | 805 right.IsValidArrowParams(); |
| 793 return PreParserExpression( | 806 return PreParserExpression( |
| 794 TypeField::encode(kBinaryOperationExpression) | | 807 TypeField::encode(kBinaryOperationExpression) | |
| 795 IsValidArrowParamListField::encode(valid_arrow_param_list)); | 808 IsValidArrowParamListField::encode(valid_arrow_param_list)); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 890 bool IsValidReferenceExpression() const { | 903 bool IsValidReferenceExpression() const { |
| 891 return IsIdentifier() || IsProperty(); | 904 return IsIdentifier() || IsProperty(); |
| 892 } | 905 } |
| 893 | 906 |
| 894 bool IsValidArrowParamList() const { | 907 bool IsValidArrowParamList() const { |
| 895 return IsValidArrowParams() && | 908 return IsValidArrowParams() && |
| 896 ParenthesizationField::decode(code_) != | 909 ParenthesizationField::decode(code_) != |
| 897 kMultiParenthesizedExpression; | 910 kMultiParenthesizedExpression; |
| 898 } | 911 } |
| 899 | 912 |
| 913 bool IsSpreadOperation() const { | |
| 914 return TypeField::decode(code_) & kSpreadExpression; | |
|
marja
2015/03/10 09:11:19
Hmm... so this works because kSpreadExpression hap
| |
| 915 } | |
| 916 | |
| 917 PreParserExpression SpreadExpression() const { | |
| 918 DCHECK(IsSpreadOperation()); | |
| 919 return PreParserExpression(TypeField::decode(code_) & ~kSpreadExpression); | |
| 920 } | |
| 921 | |
| 900 // At the moment PreParser doesn't track these expression types. | 922 // At the moment PreParser doesn't track these expression types. |
| 901 bool IsFunctionLiteral() const { return false; } | 923 bool IsFunctionLiteral() const { return false; } |
| 902 bool IsCallNew() const { return false; } | 924 bool IsCallNew() const { return false; } |
| 903 | 925 |
| 904 bool IsNoTemplateTag() const { | 926 bool IsNoTemplateTag() const { |
| 905 return TypeField::decode(code_) == kExpression && | 927 return TypeField::decode(code_) == kExpression && |
| 906 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 928 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
| 907 } | 929 } |
| 908 | 930 |
| 909 PreParserExpression AsFunctionLiteral() { return *this; } | 931 PreParserExpression AsFunctionLiteral() { return *this; } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 931 void set_parenthesized() {} | 953 void set_parenthesized() {} |
| 932 | 954 |
| 933 int position() const { return RelocInfo::kNoPosition; } | 955 int position() const { return RelocInfo::kNoPosition; } |
| 934 void set_function_token_position(int position) {} | 956 void set_function_token_position(int position) {} |
| 935 | 957 |
| 936 private: | 958 private: |
| 937 enum Type { | 959 enum Type { |
| 938 kExpression, | 960 kExpression, |
| 939 kIdentifierExpression, | 961 kIdentifierExpression, |
| 940 kStringLiteralExpression, | 962 kStringLiteralExpression, |
| 941 kBinaryOperationExpression | 963 kBinaryOperationExpression, |
| 964 kSpreadExpression | |
|
marja
2015/03/10 09:11:19
So maybe add "= 1 << 3 " here to hint that kSpread
| |
| 942 }; | 965 }; |
| 943 | 966 |
| 944 enum Parenthesization { | 967 enum Parenthesization { |
| 945 kNotParenthesized, | 968 kNotParenthesized, |
| 946 kParanthesizedExpression, | 969 kParanthesizedExpression, |
| 947 kMultiParenthesizedExpression | 970 kMultiParenthesizedExpression |
| 948 }; | 971 }; |
| 949 | 972 |
| 950 enum ExpressionType { | 973 enum ExpressionType { |
|
marja
2015/03/10 09:11:19
(Huh, why do we have Type and ExpressionType? Urgh
| |
| 951 kThisExpression, | 974 kThisExpression, |
| 952 kThisPropertyExpression, | 975 kThisPropertyExpression, |
| 953 kPropertyExpression, | 976 kPropertyExpression, |
| 954 kCallExpression, | 977 kCallExpression, |
| 955 kNoTemplateTagExpression | 978 kNoTemplateTagExpression |
| 956 }; | 979 }; |
| 957 | 980 |
| 958 explicit PreParserExpression(uint32_t expression_code) | 981 explicit PreParserExpression(uint32_t expression_code) |
| 959 : code_(expression_code) {} | 982 : code_(expression_code) {} |
| 960 | 983 |
| 961 V8_INLINE bool IsValidArrowParams() const { | 984 V8_INLINE bool IsValidArrowParams() const { |
| 985 if (IsSpreadOperation()) { | |
| 986 return SpreadExpression().IsValidArrowParams(); | |
| 987 } | |
| 962 return IsBinaryOperation() | 988 return IsBinaryOperation() |
| 963 ? IsValidArrowParamListField::decode(code_) | 989 ? IsValidArrowParamListField::decode(code_) |
| 964 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | 990 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); |
| 965 } | 991 } |
| 966 | 992 |
| 967 // The first four bits are for the Type and Parenthesization. | 993 // The first four bits are for the Type and Parenthesization. |
| 968 typedef BitField<Type, 0, 2> TypeField; | 994 typedef BitField<Type, 0, 3> TypeField; |
| 969 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 995 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
| 970 | 996 |
| 971 // The rest of the bits are interpreted depending on the value | 997 // The rest of the bits are interpreted depending on the value |
| 972 // of the Type field, so they can share the storage. | 998 // of the Type field, so they can share the storage. |
| 973 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 999 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
| 974 ExpressionTypeField; | 1000 ExpressionTypeField; |
| 975 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 1001 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
| 976 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1002 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
| 977 typedef BitField<bool, ParenthesizationField::kNext, 1> | 1003 typedef BitField<bool, ParenthesizationField::kNext, 1> |
| 978 IsValidArrowParamListField; | 1004 IsValidArrowParamListField; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1174 PreParserIdentifier name, AstValueFactory* ast_value_factory, | 1200 PreParserIdentifier name, AstValueFactory* ast_value_factory, |
| 1175 Scope* scope, PreParserStatementList body, int materialized_literal_count, | 1201 Scope* scope, PreParserStatementList body, int materialized_literal_count, |
| 1176 int expected_property_count, int handler_count, int parameter_count, | 1202 int expected_property_count, int handler_count, int parameter_count, |
| 1177 FunctionLiteral::ParameterFlag has_duplicate_parameters, | 1203 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
| 1178 FunctionLiteral::FunctionType function_type, | 1204 FunctionLiteral::FunctionType function_type, |
| 1179 FunctionLiteral::IsFunctionFlag is_function, | 1205 FunctionLiteral::IsFunctionFlag is_function, |
| 1180 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, | 1206 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, |
| 1181 int position) { | 1207 int position) { |
| 1182 return PreParserExpression::Default(); | 1208 return PreParserExpression::Default(); |
| 1183 } | 1209 } |
| 1210 PreParserExpression NewSpreadOperation(PreParserExpression expr, int pos) { | |
| 1211 return PreParserExpression::SpreadOperation(expr); | |
| 1212 } | |
| 1184 | 1213 |
| 1185 // Return the object itself as AstVisitor and implement the needed | 1214 // Return the object itself as AstVisitor and implement the needed |
| 1186 // dummy method right in this class. | 1215 // dummy method right in this class. |
| 1187 PreParserFactory* visitor() { return this; } | 1216 PreParserFactory* visitor() { return this; } |
| 1188 int* ast_properties() { | 1217 int* ast_properties() { |
| 1189 static int dummy = 42; | 1218 static int dummy = 42; |
| 1190 return &dummy; | 1219 return &dummy; |
| 1191 } | 1220 } |
| 1192 }; | 1221 }; |
| 1193 | 1222 |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1675 | 1704 |
| 1676 template <class Traits> | 1705 template <class Traits> |
| 1677 ParserBase<Traits>::FunctionState::~FunctionState() { | 1706 ParserBase<Traits>::FunctionState::~FunctionState() { |
| 1678 *scope_stack_ = outer_scope_; | 1707 *scope_stack_ = outer_scope_; |
| 1679 *function_state_stack_ = outer_function_state_; | 1708 *function_state_stack_ = outer_function_state_; |
| 1680 } | 1709 } |
| 1681 | 1710 |
| 1682 | 1711 |
| 1683 template<class Traits> | 1712 template<class Traits> |
| 1684 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1713 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
| 1685 Scanner::Location source_location = scanner()->location(); | 1714 return ReportUnexpectedTokenAt(scanner()->location(), token); |
| 1715 } | |
| 1686 | 1716 |
| 1717 | |
| 1718 template <class Traits> | |
| 1719 void ParserBase<Traits>::ReportUnexpectedTokenAt(Scanner::Location location, | |
| 1720 Token::Value token) { | |
| 1687 // Four of the tokens are treated specially | 1721 // Four of the tokens are treated specially |
| 1688 switch (token) { | 1722 switch (token) { |
| 1689 case Token::EOS: | 1723 case Token::EOS: |
| 1690 return ReportMessageAt(source_location, "unexpected_eos"); | 1724 return ReportMessageAt(location, "unexpected_eos"); |
| 1691 case Token::SMI: | 1725 case Token::SMI: |
| 1692 case Token::NUMBER: | 1726 case Token::NUMBER: |
| 1693 return ReportMessageAt(source_location, "unexpected_token_number"); | 1727 return ReportMessageAt(location, "unexpected_token_number"); |
| 1694 case Token::STRING: | 1728 case Token::STRING: |
| 1695 return ReportMessageAt(source_location, "unexpected_token_string"); | 1729 return ReportMessageAt(location, "unexpected_token_string"); |
| 1696 case Token::IDENTIFIER: | 1730 case Token::IDENTIFIER: |
| 1697 return ReportMessageAt(source_location, "unexpected_token_identifier"); | 1731 return ReportMessageAt(location, "unexpected_token_identifier"); |
| 1698 case Token::FUTURE_RESERVED_WORD: | 1732 case Token::FUTURE_RESERVED_WORD: |
| 1699 return ReportMessageAt(source_location, "unexpected_reserved"); | 1733 return ReportMessageAt(location, "unexpected_reserved"); |
| 1700 case Token::LET: | 1734 case Token::LET: |
| 1701 case Token::STATIC: | 1735 case Token::STATIC: |
| 1702 case Token::YIELD: | 1736 case Token::YIELD: |
| 1703 case Token::FUTURE_STRICT_RESERVED_WORD: | 1737 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 1704 return ReportMessageAt(source_location, | 1738 return ReportMessageAt(location, is_strict(language_mode()) |
| 1705 is_strict(language_mode()) | 1739 ? "unexpected_strict_reserved" |
| 1706 ? "unexpected_strict_reserved" | 1740 : "unexpected_token_identifier"); |
| 1707 : "unexpected_token_identifier"); | |
| 1708 case Token::TEMPLATE_SPAN: | 1741 case Token::TEMPLATE_SPAN: |
| 1709 case Token::TEMPLATE_TAIL: | 1742 case Token::TEMPLATE_TAIL: |
| 1710 return Traits::ReportMessageAt(source_location, | 1743 return Traits::ReportMessageAt(location, "unexpected_template_string"); |
| 1711 "unexpected_template_string"); | |
| 1712 default: | 1744 default: |
| 1713 const char* name = Token::String(token); | 1745 const char* name = Token::String(token); |
| 1714 DCHECK(name != NULL); | 1746 DCHECK(name != NULL); |
| 1715 Traits::ReportMessageAt(source_location, "unexpected_token", name); | 1747 Traits::ReportMessageAt(location, "unexpected_token", name); |
| 1716 } | 1748 } |
| 1717 } | 1749 } |
| 1718 | 1750 |
| 1719 | 1751 |
| 1720 template<class Traits> | 1752 template<class Traits> |
| 1721 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( | 1753 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
| 1722 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, | 1754 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
| 1723 bool* ok) { | 1755 bool* ok) { |
| 1724 Token::Value next = Next(); | 1756 Token::Value next = Next(); |
| 1725 if (next == Token::IDENTIFIER) { | 1757 if (next == Token::IDENTIFIER) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1852 // 'false' | 1884 // 'false' |
| 1853 // Identifier | 1885 // Identifier |
| 1854 // Number | 1886 // Number |
| 1855 // String | 1887 // String |
| 1856 // ArrayLiteral | 1888 // ArrayLiteral |
| 1857 // ObjectLiteral | 1889 // ObjectLiteral |
| 1858 // RegExpLiteral | 1890 // RegExpLiteral |
| 1859 // ClassLiteral | 1891 // ClassLiteral |
| 1860 // '(' Expression ')' | 1892 // '(' Expression ')' |
| 1861 // TemplateLiteral | 1893 // TemplateLiteral |
| 1894 // ... Identifier ')' '=>' | |
|
arv (Not doing code reviews)
2015/03/10 13:44:02
Why ')' '=>'?
caitp (gmail)
2015/03/10 14:47:51
So, you're right that we can just check for the `)
| |
| 1862 | 1895 |
| 1863 int beg_pos = scanner()->peek_location().beg_pos; | 1896 int beg_pos = scanner()->peek_location().beg_pos; |
| 1864 int end_pos = scanner()->peek_location().end_pos; | 1897 int end_pos = scanner()->peek_location().end_pos; |
| 1865 ExpressionT result = this->EmptyExpression(); | 1898 ExpressionT result = this->EmptyExpression(); |
| 1866 Token::Value token = peek(); | 1899 Token::Value token = peek(); |
| 1867 switch (token) { | 1900 switch (token) { |
| 1868 case Token::THIS: { | 1901 case Token::THIS: { |
| 1869 Consume(Token::THIS); | 1902 Consume(Token::THIS); |
| 1870 scope_->RecordThisUsage(); | 1903 scope_->RecordThisUsage(); |
| 1871 result = this->ThisExpression(scope_, factory(), beg_pos); | 1904 result = this->ThisExpression(scope_, factory(), beg_pos); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1924 Consume(Token::RPAREN); | 1957 Consume(Token::RPAREN); |
| 1925 result = this->ParseArrowFunctionLiteral( | 1958 result = this->ParseArrowFunctionLiteral( |
| 1926 beg_pos, this->EmptyArrowParamList(), CHECK_OK); | 1959 beg_pos, this->EmptyArrowParamList(), CHECK_OK); |
| 1927 } else { | 1960 } else { |
| 1928 // Heuristically try to detect immediately called functions before | 1961 // Heuristically try to detect immediately called functions before |
| 1929 // seeing the call parentheses. | 1962 // seeing the call parentheses. |
| 1930 parenthesized_function_ = (peek() == Token::FUNCTION); | 1963 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 1931 result = this->ParseExpression(true, CHECK_OK); | 1964 result = this->ParseExpression(true, CHECK_OK); |
| 1932 result->increase_parenthesization_level(); | 1965 result->increase_parenthesization_level(); |
| 1933 Expect(Token::RPAREN, CHECK_OK); | 1966 Expect(Token::RPAREN, CHECK_OK); |
| 1967 if (peek() == Token::ARROW) { | |
| 1968 int x = 5; | |
|
marja
2015/03/10 09:11:19
?
arv (Not doing code reviews)
2015/03/10 13:44:02
Looks like debug code... remove?
caitp (gmail)
2015/03/10 14:47:51
Hah, yeah --- I'll get rid of that =)
| |
| 1969 USE(x); | |
| 1970 } | |
| 1934 } | 1971 } |
| 1935 break; | 1972 break; |
| 1936 | 1973 |
| 1937 case Token::CLASS: { | 1974 case Token::CLASS: { |
| 1938 Consume(Token::CLASS); | 1975 Consume(Token::CLASS); |
| 1939 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 1976 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 1940 ReportMessage("sloppy_lexical", NULL); | 1977 ReportMessage("sloppy_lexical", NULL); |
| 1941 *ok = false; | 1978 *ok = false; |
| 1942 break; | 1979 break; |
| 1943 } | 1980 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1963 break; | 2000 break; |
| 1964 | 2001 |
| 1965 case Token::MOD: | 2002 case Token::MOD: |
| 1966 if (allow_natives() || extension_ != NULL) { | 2003 if (allow_natives() || extension_ != NULL) { |
| 1967 result = this->ParseV8Intrinsic(CHECK_OK); | 2004 result = this->ParseV8Intrinsic(CHECK_OK); |
| 1968 break; | 2005 break; |
| 1969 } | 2006 } |
| 1970 // If we're not allowing special syntax we fall-through to the | 2007 // If we're not allowing special syntax we fall-through to the |
| 1971 // default case. | 2008 // default case. |
| 1972 | 2009 |
| 2010 case Token::ELLIPSIS: | |
| 2011 // Not a valid primary expression, but valid in parenthesized arrow | |
| 2012 // function. | |
| 2013 // | |
| 2014 // Fail if name, closing parenthesis and arrow token are not found. | |
| 2015 if (allow_harmony_rest_params() && allow_harmony_arrow_functions()) { | |
| 2016 Consume(Token::ELLIPSIS); | |
| 2017 bool is_strict_reserved_name = false; | |
| 2018 IdentifierT name = ParseIdentifierOrStrictReservedWord( | |
| 2019 &is_strict_reserved_name, CHECK_OK); | |
|
arv (Not doing code reviews)
2015/03/10 13:44:03
I don't see where is_strict_reserved_name is being
caitp (gmail)
2015/03/10 14:47:51
to match the function signature... pretty much jus
| |
| 2020 if (peek() == Token::COMMA) { | |
| 2021 *ok = false; | |
| 2022 ReportMessageAt(scanner_->peek_location(), "param_after_rest"); | |
| 2023 break; | |
| 2024 } else if (peek() != Token::RPAREN) { | |
| 2025 ReportUnexpectedTokenAt(scanner_->peek_location(), peek()); | |
| 2026 *ok = false; | |
| 2027 break; | |
| 2028 } | |
| 2029 | |
| 2030 if (peek(1) != Token::ARROW) { | |
| 2031 ReportUnexpectedTokenAt(scanner_->peek_location(1), peek(1)); | |
|
arv (Not doing code reviews)
2015/03/10 13:44:03
Another option here is to report the invalid `...`
| |
| 2032 *ok = false; | |
| 2033 break; | |
| 2034 } | |
| 2035 | |
| 2036 Scanner::Location name_pos = scanner_->location(); | |
| 2037 result = this->ExpressionFromIdentifier( | |
| 2038 name, name_pos.beg_pos, name_pos.end_pos, scope_, factory()); | |
| 2039 | |
| 2040 return factory()->NewSpreadOperation(result, beg_pos); | |
| 2041 } | |
| 2042 | |
| 1973 default: { | 2043 default: { |
| 1974 Next(); | 2044 Next(); |
| 1975 ReportUnexpectedToken(token); | 2045 ReportUnexpectedToken(token); |
| 1976 *ok = false; | 2046 *ok = false; |
| 1977 } | 2047 } |
| 1978 } | 2048 } |
| 1979 | 2049 |
| 1980 return result; | 2050 return result; |
| 1981 } | 2051 } |
| 1982 | 2052 |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2758 name, function_name_location, is_strict_reserved_name, | 2828 name, function_name_location, is_strict_reserved_name, |
| 2759 is_generator ? FunctionKind::kGeneratorFunction | 2829 is_generator ? FunctionKind::kGeneratorFunction |
| 2760 : FunctionKind::kNormalFunction, | 2830 : FunctionKind::kNormalFunction, |
| 2761 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, | 2831 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, |
| 2762 CHECK_OK); | 2832 CHECK_OK); |
| 2763 } else if (peek() == Token::SUPER) { | 2833 } else if (peek() == Token::SUPER) { |
| 2764 const bool is_new = false; | 2834 const bool is_new = false; |
| 2765 result = ParseSuperExpression(is_new, CHECK_OK); | 2835 result = ParseSuperExpression(is_new, CHECK_OK); |
| 2766 } else { | 2836 } else { |
| 2767 result = ParsePrimaryExpression(CHECK_OK); | 2837 result = ParsePrimaryExpression(CHECK_OK); |
| 2838 if (result->IsSpreadOperation()) { | |
| 2839 // SpreadOperation is only parsed here as the last parameter of an | |
| 2840 // arrow function. It's not a valid MemberExpression, and there is no | |
| 2841 // continuation. | |
| 2842 return result; | |
| 2843 } | |
| 2768 } | 2844 } |
| 2769 | 2845 |
| 2770 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 2846 result = ParseMemberExpressionContinuation(result, CHECK_OK); |
| 2771 return result; | 2847 return result; |
| 2772 } | 2848 } |
| 2773 | 2849 |
| 2774 | 2850 |
| 2775 template <class Traits> | 2851 template <class Traits> |
| 2776 typename ParserBase<Traits>::ExpressionT | 2852 typename ParserBase<Traits>::ExpressionT |
| 2777 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { | 2853 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3117 *ok = false; | 3193 *ok = false; |
| 3118 return; | 3194 return; |
| 3119 } | 3195 } |
| 3120 has_seen_constructor_ = true; | 3196 has_seen_constructor_ = true; |
| 3121 return; | 3197 return; |
| 3122 } | 3198 } |
| 3123 } | 3199 } |
| 3124 } } // v8::internal | 3200 } } // v8::internal |
| 3125 | 3201 |
| 3126 #endif // V8_PREPARSER_H | 3202 #endif // V8_PREPARSER_H |
| OLD | NEW |