Revision: 6341
Author: [email protected]
Date: Mon Jan 17 01:36:10 2011
Log: Make invalid break/continue statements an early syntax error.
Previously we delayed the throwing of syntax errors until runtime, so
unreachable errors didn't get reported.
To match a change in JSC, we now stop parsing and report the error
immediately.
BUG=69736
TEST=
Review URL: http://codereview.chromium.org/6355006
http://code.google.com/p/v8/source/detail?r=6341
Modified:
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/parser.h
/branches/bleeding_edge/test/mjsunit/delay-syntax-error.js
/branches/bleeding_edge/test/mjsunit/regress/regress-1036894.js
/branches/bleeding_edge/test/mjsunit/regress/regress-990205.js
=======================================
--- /branches/bleeding_edge/src/parser.cc Fri Jan 14 02:50:13 2011
+++ /branches/bleeding_edge/src/parser.cc Mon Jan 17 01:36:10 2011
@@ -778,7 +778,8 @@
const char* type,
Vector<const char*> args) {
MessageLocation location(script_,
- source_location.beg_pos,
source_location.end_pos);
+ source_location.beg_pos,
+ source_location.end_pos);
Handle<JSArray> array = Factory::NewJSArray(args.length());
for (int i = 0; i < args.length(); i++) {
SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i])));
@@ -786,6 +787,21 @@
Handle<Object> result = Factory::NewSyntaxError(type, array);
Top::Throw(*result, &location);
}
+
+
+void Parser::ReportMessageAt(Scanner::Location source_location,
+ const char* type,
+ Vector<Handle<String> > args) {
+ MessageLocation location(script_,
+ source_location.beg_pos,
+ source_location.end_pos);
+ Handle<JSArray> array = Factory::NewJSArray(args.length());
+ for (int i = 0; i < args.length(); i++) {
+ SetElement(array, i, args[i]);
+ }
+ Handle<Object> result = Factory::NewSyntaxError(type, array);
+ Top::Throw(*result, &location);
+}
// Base class containing common code for the different finder classes used
by
@@ -1693,12 +1709,16 @@
IterationStatement* target = NULL;
target = LookupContinueTarget(label, CHECK_OK);
if (target == NULL) {
- // Illegal continue statement. To be consistent with KJS we delay
- // reporting of the syntax error until runtime.
- Handle<String> error_type = Factory::illegal_continue_symbol();
- if (!label.is_null()) error_type = Factory::unknown_label_symbol();
- Expression* throw_error = NewThrowSyntaxError(error_type, label);
- return new ExpressionStatement(throw_error);
+ // Illegal continue statement.
+ const char* message = "illegal_continue";
+ Vector<Handle<String> > args;
+ if (!label.is_null()) {
+ message = "unknown_label";
+ args = Vector<Handle<String> >(&label, 1);
+ }
+ ReportMessageAt(scanner().location(), message, args);
+ *ok = false;
+ return NULL;
}
ExpectSemicolon(CHECK_OK);
return new ContinueStatement(target);
@@ -1724,12 +1744,16 @@
BreakableStatement* target = NULL;
target = LookupBreakTarget(label, CHECK_OK);
if (target == NULL) {
- // Illegal break statement. To be consistent with KJS we delay
- // reporting of the syntax error until runtime.
- Handle<String> error_type = Factory::illegal_break_symbol();
- if (!label.is_null()) error_type = Factory::unknown_label_symbol();
- Expression* throw_error = NewThrowSyntaxError(error_type, label);
- return new ExpressionStatement(throw_error);
+ // Illegal break statement.
+ const char* message = "illegal_break";
+ Vector<Handle<String> > args;
+ if (!label.is_null()) {
+ message = "unknown_label";
+ args = Vector<Handle<String> >(&label, 1);
+ }
+ ReportMessageAt(scanner().location(), message, args);
+ *ok = false;
+ return NULL;
}
ExpectSemicolon(CHECK_OK);
return new BreakStatement(target);
=======================================
--- /branches/bleeding_edge/src/parser.h Fri Jan 14 02:50:13 2011
+++ /branches/bleeding_edge/src/parser.h Mon Jan 17 01:36:10 2011
@@ -430,6 +430,9 @@
void ReportMessageAt(Scanner::Location loc,
const char* message,
Vector<const char*> args);
+ void ReportMessageAt(Scanner::Location loc,
+ const char* message,
+ Vector<Handle<String> > args);
protected:
FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info,
=======================================
--- /branches/bleeding_edge/test/mjsunit/delay-syntax-error.js Tue Dec 7
03:01:02 2010
+++ /branches/bleeding_edge/test/mjsunit/delay-syntax-error.js Mon Jan 17
01:36:10 2011
@@ -25,17 +25,18 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// To be compatible with KJS syntax errors for illegal return, break
-// and continue should be delayed to runtime.
-
-// Do not throw syntax errors for illegal return, break and continue
-// at compile time.
+// To be compatible with JSC syntax errors for illegal returns should be
delayed
+// to runtime.
+// Invalid continue and break statements are caught at compile time.
+
+// Do not throw syntax errors for illegal return at compile time.
assertDoesNotThrow("if (false) return;");
-assertDoesNotThrow("if (false) break;");
-assertDoesNotThrow("if (false) continue;");
-
-// Throw syntax errors for illegal return, break and continue at
-// compile time.
+
+// Throw syntax errors for illegal break and continue at compile time.
+assertThrows("if (false) break;");
+assertThrows("if (false) continue;");
+
+// Throw syntax errors for illegal return, break and continue at runtime.
assertThrows("return;");
assertThrows("break;");
assertThrows("continue;");
=======================================
--- /branches/bleeding_edge/test/mjsunit/regress/regress-1036894.js Tue
Dec 7 03:01:02 2010
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-1036894.js Mon Jan
17 01:36:10 2011
@@ -25,14 +25,14 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-xeval = function(s) { eval(s); }
-xeval("$=function anonymous() { /*noex*/do {} while(({ get x(x) { break ;
}, set x() { (undefined);} })); }");
-
-foo = function() { eval("$=function anonymous() { /*noex*/do {} while(({
get x(x) { break ; }, set x() { (undefined);} })); }"); }
+assertThrows("$=function anonymous() { /*noex*/do {} while(({ get x(x) {
break ; }, set x() { (undefined);} })); }");
+
+function foo() {
+ assertThrows("$=function anonymous() { /*noex*/do {} while(({ get x(x) {
break ; }, set x() { (undefined);} })); }");
+}
foo();
-xeval = function(s) { eval(s); }
-eval("$=function anonymous() { /*noex*/do {} while(({ get x(x) { break ;
}, set x() { (undefined);} })); }");
+assertThrows("$=function anonymous() { /*noex*/do {} while(({ get x(x) {
break ; }, set x() { (undefined);} })); }");
xeval = function(s) { eval(s); }
xeval('$=function(){L: {break L;break L;}};');
=======================================
--- /branches/bleeding_edge/test/mjsunit/regress/regress-990205.js Tue Dec
7 03:01:02 2010
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-990205.js Mon Jan
17 01:36:10 2011
@@ -25,11 +25,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// We throw syntax errors early for invalid break and continue statements.
+// (Notice that the example isn't valid ECMAScript due to the
+// function declaration that is not at top level.)
+
function f() {
// Force eager compilation of x through the use of eval. The break
// in function x should not try to break out of the enclosing while.
return eval("while(0) function x() { break; }; 42");
};
-assertEquals(42, f());
-
+assertThrows("f()");
+
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev