Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Side by Side Diff: src/parser.cc

Issue 6355006: Make invalid break/continue statements an early syntax error. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build-ia32
Patch Set: Address review comments. Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | test/mjsunit/delay-syntax-error.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 void Parser::ReportMessage(const char* type, Vector<const char*> args) { 771 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
772 Scanner::Location source_location = scanner().location(); 772 Scanner::Location source_location = scanner().location();
773 ReportMessageAt(source_location, type, args); 773 ReportMessageAt(source_location, type, args);
774 } 774 }
775 775
776 776
777 void Parser::ReportMessageAt(Scanner::Location source_location, 777 void Parser::ReportMessageAt(Scanner::Location source_location,
778 const char* type, 778 const char* type,
779 Vector<const char*> args) { 779 Vector<const char*> args) {
780 MessageLocation location(script_, 780 MessageLocation location(script_,
781 source_location.beg_pos, source_location.end_pos); 781 source_location.beg_pos,
782 source_location.end_pos);
782 Handle<JSArray> array = Factory::NewJSArray(args.length()); 783 Handle<JSArray> array = Factory::NewJSArray(args.length());
783 for (int i = 0; i < args.length(); i++) { 784 for (int i = 0; i < args.length(); i++) {
784 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i]))); 785 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i])));
785 } 786 }
786 Handle<Object> result = Factory::NewSyntaxError(type, array); 787 Handle<Object> result = Factory::NewSyntaxError(type, array);
787 Top::Throw(*result, &location); 788 Top::Throw(*result, &location);
788 } 789 }
789 790
790 791
792 void Parser::ReportMessageAt(Scanner::Location source_location,
793 const char* type,
794 Vector<Handle<String> > args) {
795 MessageLocation location(script_,
796 source_location.beg_pos,
797 source_location.end_pos);
798 Handle<JSArray> array = Factory::NewJSArray(args.length());
799 for (int i = 0; i < args.length(); i++) {
800 SetElement(array, i, args[i]);
801 }
802 Handle<Object> result = Factory::NewSyntaxError(type, array);
803 Top::Throw(*result, &location);
804 }
805
806
791 // Base class containing common code for the different finder classes used by 807 // Base class containing common code for the different finder classes used by
792 // the parser. 808 // the parser.
793 class ParserFinder { 809 class ParserFinder {
794 protected: 810 protected:
795 ParserFinder() {} 811 ParserFinder() {}
796 static Assignment* AsAssignment(Statement* stat) { 812 static Assignment* AsAssignment(Statement* stat) {
797 if (stat == NULL) return NULL; 813 if (stat == NULL) return NULL;
798 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); 814 ExpressionStatement* exp_stat = stat->AsExpressionStatement();
799 if (exp_stat == NULL) return NULL; 815 if (exp_stat == NULL) return NULL;
800 return exp_stat->expression()->AsAssignment(); 816 return exp_stat->expression()->AsAssignment();
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 Expect(Token::CONTINUE, CHECK_OK); 1702 Expect(Token::CONTINUE, CHECK_OK);
1687 Handle<String> label = Handle<String>::null(); 1703 Handle<String> label = Handle<String>::null();
1688 Token::Value tok = peek(); 1704 Token::Value tok = peek();
1689 if (!scanner().has_line_terminator_before_next() && 1705 if (!scanner().has_line_terminator_before_next() &&
1690 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 1706 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
1691 label = ParseIdentifier(CHECK_OK); 1707 label = ParseIdentifier(CHECK_OK);
1692 } 1708 }
1693 IterationStatement* target = NULL; 1709 IterationStatement* target = NULL;
1694 target = LookupContinueTarget(label, CHECK_OK); 1710 target = LookupContinueTarget(label, CHECK_OK);
1695 if (target == NULL) { 1711 if (target == NULL) {
1696 // Illegal continue statement. To be consistent with KJS we delay 1712 // Illegal continue statement.
1697 // reporting of the syntax error until runtime. 1713 const char* message = "illegal_continue";
1698 Handle<String> error_type = Factory::illegal_continue_symbol(); 1714 Vector<Handle<String> > args;
1699 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); 1715 if (!label.is_null()) {
1700 Expression* throw_error = NewThrowSyntaxError(error_type, label); 1716 message = "unknown_label";
1701 return new ExpressionStatement(throw_error); 1717 args = Vector<Handle<String> >(&label, 1);
1718 }
1719 ReportMessageAt(scanner().location(), message, args);
1720 *ok = false;
1721 return NULL;
1702 } 1722 }
1703 ExpectSemicolon(CHECK_OK); 1723 ExpectSemicolon(CHECK_OK);
1704 return new ContinueStatement(target); 1724 return new ContinueStatement(target);
1705 } 1725 }
1706 1726
1707 1727
1708 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { 1728 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
1709 // BreakStatement :: 1729 // BreakStatement ::
1710 // 'break' Identifier? ';' 1730 // 'break' Identifier? ';'
1711 1731
1712 Expect(Token::BREAK, CHECK_OK); 1732 Expect(Token::BREAK, CHECK_OK);
1713 Handle<String> label; 1733 Handle<String> label;
1714 Token::Value tok = peek(); 1734 Token::Value tok = peek();
1715 if (!scanner().has_line_terminator_before_next() && 1735 if (!scanner().has_line_terminator_before_next() &&
1716 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 1736 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
1717 label = ParseIdentifier(CHECK_OK); 1737 label = ParseIdentifier(CHECK_OK);
1718 } 1738 }
1719 // Parse labeled break statements that target themselves into 1739 // Parse labeled break statements that target themselves into
1720 // empty statements, e.g. 'l1: l2: l3: break l2;' 1740 // empty statements, e.g. 'l1: l2: l3: break l2;'
1721 if (!label.is_null() && ContainsLabel(labels, label)) { 1741 if (!label.is_null() && ContainsLabel(labels, label)) {
1722 return EmptyStatement(); 1742 return EmptyStatement();
1723 } 1743 }
1724 BreakableStatement* target = NULL; 1744 BreakableStatement* target = NULL;
1725 target = LookupBreakTarget(label, CHECK_OK); 1745 target = LookupBreakTarget(label, CHECK_OK);
1726 if (target == NULL) { 1746 if (target == NULL) {
1727 // Illegal break statement. To be consistent with KJS we delay 1747 // Illegal break statement.
1728 // reporting of the syntax error until runtime. 1748 const char* message = "illegal_break";
1729 Handle<String> error_type = Factory::illegal_break_symbol(); 1749 Vector<Handle<String> > args;
1730 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); 1750 if (!label.is_null()) {
1731 Expression* throw_error = NewThrowSyntaxError(error_type, label); 1751 message = "unknown_label";
1732 return new ExpressionStatement(throw_error); 1752 args = Vector<Handle<String> >(&label, 1);
1753 }
1754 ReportMessageAt(scanner().location(), message, args);
1755 *ok = false;
1756 return NULL;
1733 } 1757 }
1734 ExpectSemicolon(CHECK_OK); 1758 ExpectSemicolon(CHECK_OK);
1735 return new BreakStatement(target); 1759 return new BreakStatement(target);
1736 } 1760 }
1737 1761
1738 1762
1739 Statement* Parser::ParseReturnStatement(bool* ok) { 1763 Statement* Parser::ParseReturnStatement(bool* ok) {
1740 // ReturnStatement :: 1764 // ReturnStatement ::
1741 // 'return' Expression? ';' 1765 // 'return' Expression? ';'
1742 1766
(...skipping 2963 matching lines...) Expand 10 before | Expand all | Expand 10 after
4706 Handle<String> source = Handle<String>(String::cast(script->source())); 4730 Handle<String> source = Handle<String>(String::cast(script->source()));
4707 result = parser.ParseProgram(source, info->is_global()); 4731 result = parser.ParseProgram(source, info->is_global());
4708 } 4732 }
4709 } 4733 }
4710 4734
4711 info->SetFunction(result); 4735 info->SetFunction(result);
4712 return (result != NULL); 4736 return (result != NULL);
4713 } 4737 }
4714 4738
4715 } } // namespace v8::internal 4739 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | test/mjsunit/delay-syntax-error.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698