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

Reply via email to