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 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 if (scanner()->HasAnyLineTerminatorBeforeNext() || | 329 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
330 tok == Token::RBRACE || | 330 tok == Token::RBRACE || |
331 tok == Token::EOS) { | 331 tok == Token::EOS) { |
332 return; | 332 return; |
333 } | 333 } |
334 Expect(Token::SEMICOLON, ok); | 334 Expect(Token::SEMICOLON, ok); |
335 } | 335 } |
336 | 336 |
337 bool peek_any_identifier() { | 337 bool peek_any_identifier() { |
338 Token::Value next = peek(); | 338 Token::Value next = peek(); |
339 return next == Token::IDENTIFIER || | 339 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || |
340 next == Token::FUTURE_RESERVED_WORD || | 340 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
341 next == Token::FUTURE_STRICT_RESERVED_WORD || | 341 next == Token::STATIC || next == Token::YIELD; |
342 next == Token::LET || | |
343 next == Token::YIELD; | |
344 } | 342 } |
345 | 343 |
346 bool CheckContextualKeyword(Vector<const char> keyword) { | 344 bool CheckContextualKeyword(Vector<const char> keyword) { |
347 if (PeekContextualKeyword(keyword)) { | 345 if (PeekContextualKeyword(keyword)) { |
348 Consume(Token::IDENTIFIER); | 346 Consume(Token::IDENTIFIER); |
349 return true; | 347 return true; |
350 } | 348 } |
351 return false; | 349 return false; |
352 } | 350 } |
353 | 351 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
599 } | 597 } |
600 static PreParserIdentifier FutureReserved() { | 598 static PreParserIdentifier FutureReserved() { |
601 return PreParserIdentifier(kFutureReservedIdentifier); | 599 return PreParserIdentifier(kFutureReservedIdentifier); |
602 } | 600 } |
603 static PreParserIdentifier FutureStrictReserved() { | 601 static PreParserIdentifier FutureStrictReserved() { |
604 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 602 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
605 } | 603 } |
606 static PreParserIdentifier Let() { | 604 static PreParserIdentifier Let() { |
607 return PreParserIdentifier(kLetIdentifier); | 605 return PreParserIdentifier(kLetIdentifier); |
608 } | 606 } |
607 static PreParserIdentifier Static() { | |
608 return PreParserIdentifier(kStaticIdentifier); | |
609 } | |
609 static PreParserIdentifier Yield() { | 610 static PreParserIdentifier Yield() { |
610 return PreParserIdentifier(kYieldIdentifier); | 611 return PreParserIdentifier(kYieldIdentifier); |
611 } | 612 } |
612 static PreParserIdentifier Prototype() { | 613 static PreParserIdentifier Prototype() { |
613 return PreParserIdentifier(kPrototypeIdentifier); | 614 return PreParserIdentifier(kPrototypeIdentifier); |
614 } | 615 } |
615 static PreParserIdentifier Constructor() { | 616 static PreParserIdentifier Constructor() { |
616 return PreParserIdentifier(kConstructorIdentifier); | 617 return PreParserIdentifier(kConstructorIdentifier); |
617 } | 618 } |
618 bool IsEval() const { return type_ == kEvalIdentifier; } | 619 bool IsEval() const { return type_ == kEvalIdentifier; } |
619 bool IsArguments(const AstValueFactory* = NULL) const { | 620 bool IsArguments(const AstValueFactory* = NULL) const { |
620 return type_ == kArgumentsIdentifier; | 621 return type_ == kArgumentsIdentifier; |
621 } | 622 } |
623 bool IsLet() const { return type_ == kLetIdentifier; } | |
624 bool IsStatic() const { return type_ == kStaticIdentifier; } | |
622 bool IsYield() const { return type_ == kYieldIdentifier; } | 625 bool IsYield() const { return type_ == kYieldIdentifier; } |
623 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } | 626 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } |
624 bool IsConstructor() const { return type_ == kConstructorIdentifier; } | 627 bool IsConstructor() const { return type_ == kConstructorIdentifier; } |
625 bool IsEvalOrArguments() const { | 628 bool IsEvalOrArguments() const { |
626 return type_ == kEvalIdentifier || type_ == kArgumentsIdentifier; | 629 return type_ == kEvalIdentifier || type_ == kArgumentsIdentifier; |
627 } | 630 } |
628 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } | 631 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
629 bool IsFutureStrictReserved() const { | 632 bool IsFutureStrictReserved() const { |
630 return type_ == kFutureStrictReservedIdentifier; | 633 return type_ == kFutureStrictReservedIdentifier || |
634 type_ == kLetIdentifier || type_ == kStaticIdentifier || | |
arv (Not doing code reviews)
2014/10/31 12:11:54
This is where the bug was. I had kEvalIdentifier i
| |
635 type_ == kYieldIdentifier; | |
631 } | 636 } |
632 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } | 637 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } |
633 V8_INLINE bool IsValidArrowParam() const { | 638 V8_INLINE bool IsValidArrowParam() const { |
634 // A valid identifier can be an arrow function parameter | 639 // A valid identifier can be an arrow function parameter |
635 // except for eval, arguments, yield, and reserved keywords. | 640 // except for eval, arguments, yield, and reserved keywords. |
636 return !(IsEval() || IsArguments() || IsYield() || | 641 return !(IsEval() || IsArguments() || IsFutureStrictReserved()); |
637 IsFutureStrictReserved()); | |
638 } | 642 } |
639 | 643 |
640 // Allow identifier->name()[->length()] to work. The preparser | 644 // Allow identifier->name()[->length()] to work. The preparser |
641 // does not need the actual positions/lengths of the identifiers. | 645 // does not need the actual positions/lengths of the identifiers. |
642 const PreParserIdentifier* operator->() const { return this; } | 646 const PreParserIdentifier* operator->() const { return this; } |
643 const PreParserIdentifier raw_name() const { return *this; } | 647 const PreParserIdentifier raw_name() const { return *this; } |
644 | 648 |
645 int position() const { return 0; } | 649 int position() const { return 0; } |
646 int length() const { return 0; } | 650 int length() const { return 0; } |
647 | 651 |
648 private: | 652 private: |
649 enum Type { | 653 enum Type { |
650 kUnknownIdentifier, | 654 kUnknownIdentifier, |
651 kFutureReservedIdentifier, | 655 kFutureReservedIdentifier, |
652 kFutureStrictReservedIdentifier, | 656 kFutureStrictReservedIdentifier, |
653 kLetIdentifier, | 657 kLetIdentifier, |
658 kStaticIdentifier, | |
654 kYieldIdentifier, | 659 kYieldIdentifier, |
655 kEvalIdentifier, | 660 kEvalIdentifier, |
656 kArgumentsIdentifier, | 661 kArgumentsIdentifier, |
657 kPrototypeIdentifier, | 662 kPrototypeIdentifier, |
658 kConstructorIdentifier | 663 kConstructorIdentifier |
659 }; | 664 }; |
660 explicit PreParserIdentifier(Type type) : type_(type) {} | 665 explicit PreParserIdentifier(Type type) : type_(type) {} |
661 Type type_; | 666 Type type_; |
662 | 667 |
663 friend class PreParserExpression; | 668 friend class PreParserExpression; |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1165 | 1170 |
1166 static bool IsIdentifier(PreParserExpression expression) { | 1171 static bool IsIdentifier(PreParserExpression expression) { |
1167 return expression.IsIdentifier(); | 1172 return expression.IsIdentifier(); |
1168 } | 1173 } |
1169 | 1174 |
1170 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { | 1175 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { |
1171 return expression.AsIdentifier(); | 1176 return expression.AsIdentifier(); |
1172 } | 1177 } |
1173 | 1178 |
1174 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { | 1179 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { |
1175 return identifier.IsYield() || identifier.IsFutureStrictReserved(); | 1180 return identifier.IsFutureStrictReserved(); |
1176 } | 1181 } |
1177 | 1182 |
1178 static bool IsBoilerplateProperty(PreParserExpression property) { | 1183 static bool IsBoilerplateProperty(PreParserExpression property) { |
1179 // PreParser doesn't count boilerplate properties. | 1184 // PreParser doesn't count boilerplate properties. |
1180 return false; | 1185 return false; |
1181 } | 1186 } |
1182 | 1187 |
1183 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1188 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
1184 return false; | 1189 return false; |
1185 } | 1190 } |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1586 return ReportMessageAt(source_location, "unexpected_eos"); | 1591 return ReportMessageAt(source_location, "unexpected_eos"); |
1587 case Token::NUMBER: | 1592 case Token::NUMBER: |
1588 return ReportMessageAt(source_location, "unexpected_token_number"); | 1593 return ReportMessageAt(source_location, "unexpected_token_number"); |
1589 case Token::STRING: | 1594 case Token::STRING: |
1590 return ReportMessageAt(source_location, "unexpected_token_string"); | 1595 return ReportMessageAt(source_location, "unexpected_token_string"); |
1591 case Token::IDENTIFIER: | 1596 case Token::IDENTIFIER: |
1592 return ReportMessageAt(source_location, "unexpected_token_identifier"); | 1597 return ReportMessageAt(source_location, "unexpected_token_identifier"); |
1593 case Token::FUTURE_RESERVED_WORD: | 1598 case Token::FUTURE_RESERVED_WORD: |
1594 return ReportMessageAt(source_location, "unexpected_reserved"); | 1599 return ReportMessageAt(source_location, "unexpected_reserved"); |
1595 case Token::LET: | 1600 case Token::LET: |
1601 case Token::STATIC: | |
1596 case Token::YIELD: | 1602 case Token::YIELD: |
1597 case Token::FUTURE_STRICT_RESERVED_WORD: | 1603 case Token::FUTURE_STRICT_RESERVED_WORD: |
1598 return ReportMessageAt(source_location, strict_mode() == SLOPPY | 1604 return ReportMessageAt(source_location, strict_mode() == SLOPPY |
1599 ? "unexpected_token_identifier" : "unexpected_strict_reserved"); | 1605 ? "unexpected_token_identifier" : "unexpected_strict_reserved"); |
1600 default: | 1606 default: |
1601 const char* name = Token::String(token); | 1607 const char* name = Token::String(token); |
1602 DCHECK(name != NULL); | 1608 DCHECK(name != NULL); |
1603 Traits::ReportMessageAt(source_location, "unexpected_token", name); | 1609 Traits::ReportMessageAt(source_location, "unexpected_token", name); |
1604 } | 1610 } |
1605 } | 1611 } |
1606 | 1612 |
1607 | 1613 |
1608 template<class Traits> | 1614 template<class Traits> |
1609 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( | 1615 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
1610 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, | 1616 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
1611 bool* ok) { | 1617 bool* ok) { |
1612 Token::Value next = Next(); | 1618 Token::Value next = Next(); |
1613 if (next == Token::IDENTIFIER) { | 1619 if (next == Token::IDENTIFIER) { |
1614 IdentifierT name = this->GetSymbol(scanner()); | 1620 IdentifierT name = this->GetSymbol(scanner()); |
1615 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && | 1621 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && |
1616 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { | 1622 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { |
1617 ReportMessage("strict_eval_arguments"); | 1623 ReportMessage("strict_eval_arguments"); |
1618 *ok = false; | 1624 *ok = false; |
1619 } | 1625 } |
1620 if (name->IsArguments(this->ast_value_factory())) | 1626 if (name->IsArguments(this->ast_value_factory())) |
1621 scope_->RecordArgumentsUsage(); | 1627 scope_->RecordArgumentsUsage(); |
1622 return name; | 1628 return name; |
1623 } else if (strict_mode() == SLOPPY && | 1629 } else if (strict_mode() == SLOPPY && |
1624 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1630 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
1625 (next == Token::LET) || | 1631 next == Token::LET || next == Token::STATIC || |
1626 (next == Token::YIELD && !is_generator()))) { | 1632 (next == Token::YIELD && !is_generator()))) { |
1627 return this->GetSymbol(scanner()); | 1633 return this->GetSymbol(scanner()); |
1628 } else { | 1634 } else { |
1629 this->ReportUnexpectedToken(next); | 1635 this->ReportUnexpectedToken(next); |
1630 *ok = false; | 1636 *ok = false; |
1631 return Traits::EmptyIdentifier(); | 1637 return Traits::EmptyIdentifier(); |
1632 } | 1638 } |
1633 } | 1639 } |
1634 | 1640 |
1635 | 1641 |
1636 template <class Traits> | 1642 template <class Traits> |
1637 typename ParserBase<Traits>::IdentifierT ParserBase< | 1643 typename ParserBase<Traits>::IdentifierT ParserBase< |
1638 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, | 1644 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, |
1639 bool* ok) { | 1645 bool* ok) { |
1640 Token::Value next = Next(); | 1646 Token::Value next = Next(); |
1641 if (next == Token::IDENTIFIER) { | 1647 if (next == Token::IDENTIFIER) { |
1642 *is_strict_reserved = false; | 1648 *is_strict_reserved = false; |
1643 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1649 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
1644 next == Token::LET || | 1650 next == Token::STATIC || |
1645 (next == Token::YIELD && !this->is_generator())) { | 1651 (next == Token::YIELD && !this->is_generator())) { |
1646 *is_strict_reserved = true; | 1652 *is_strict_reserved = true; |
1647 } else { | 1653 } else { |
1648 ReportUnexpectedToken(next); | 1654 ReportUnexpectedToken(next); |
1649 *ok = false; | 1655 *ok = false; |
1650 return Traits::EmptyIdentifier(); | 1656 return Traits::EmptyIdentifier(); |
1651 } | 1657 } |
1652 | 1658 |
1653 IdentifierT name = this->GetSymbol(scanner()); | 1659 IdentifierT name = this->GetSymbol(scanner()); |
1654 if (name->IsArguments(this->ast_value_factory())) | 1660 if (name->IsArguments(this->ast_value_factory())) |
1655 scope_->RecordArgumentsUsage(); | 1661 scope_->RecordArgumentsUsage(); |
1656 return name; | 1662 return name; |
1657 } | 1663 } |
1658 | 1664 |
1659 | 1665 |
1660 template <class Traits> | 1666 template <class Traits> |
1661 typename ParserBase<Traits>::IdentifierT | 1667 typename ParserBase<Traits>::IdentifierT |
1662 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1668 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
1663 Token::Value next = Next(); | 1669 Token::Value next = Next(); |
1664 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 1670 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && |
1665 next != Token::LET && next != Token::YIELD && | 1671 next != Token::LET && next != Token::STATIC && next != Token::YIELD && |
1666 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1672 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
1667 this->ReportUnexpectedToken(next); | 1673 this->ReportUnexpectedToken(next); |
1668 *ok = false; | 1674 *ok = false; |
1669 return Traits::EmptyIdentifier(); | 1675 return Traits::EmptyIdentifier(); |
1670 } | 1676 } |
1671 | 1677 |
1672 IdentifierT name = this->GetSymbol(scanner()); | 1678 IdentifierT name = this->GetSymbol(scanner()); |
1673 if (name->IsArguments(this->ast_value_factory())) | 1679 if (name->IsArguments(this->ast_value_factory())) |
1674 scope_->RecordArgumentsUsage(); | 1680 scope_->RecordArgumentsUsage(); |
1675 return name; | 1681 return name; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1758 case Token::NULL_LITERAL: | 1764 case Token::NULL_LITERAL: |
1759 case Token::TRUE_LITERAL: | 1765 case Token::TRUE_LITERAL: |
1760 case Token::FALSE_LITERAL: | 1766 case Token::FALSE_LITERAL: |
1761 case Token::NUMBER: | 1767 case Token::NUMBER: |
1762 Next(); | 1768 Next(); |
1763 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); | 1769 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); |
1764 break; | 1770 break; |
1765 | 1771 |
1766 case Token::IDENTIFIER: | 1772 case Token::IDENTIFIER: |
1767 case Token::LET: | 1773 case Token::LET: |
1774 case Token::STATIC: | |
1768 case Token::YIELD: | 1775 case Token::YIELD: |
1769 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1776 case Token::FUTURE_STRICT_RESERVED_WORD: { |
1770 // Using eval or arguments in this context is OK even in strict mode. | 1777 // Using eval or arguments in this context is OK even in strict mode. |
1771 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1778 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1772 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); | 1779 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); |
1773 break; | 1780 break; |
1774 } | 1781 } |
1775 | 1782 |
1776 case Token::STRING: { | 1783 case Token::STRING: { |
1777 Consume(Token::STRING); | 1784 Consume(Token::STRING); |
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2841 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2848 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
2842 // Both accessors of the same type. | 2849 // Both accessors of the same type. |
2843 parser()->ReportMessage("accessor_get_set"); | 2850 parser()->ReportMessage("accessor_get_set"); |
2844 } | 2851 } |
2845 *ok = false; | 2852 *ok = false; |
2846 } | 2853 } |
2847 } | 2854 } |
2848 } } // v8::internal | 2855 } } // v8::internal |
2849 | 2856 |
2850 #endif // V8_PREPARSER_H | 2857 #endif // V8_PREPARSER_H |
OLD | NEW |