Bug 1524965 - Part 1: Handle break/continue outside the loop properly. r=Yoric
☠☠ backed out by 2175133dd323 ☠ ☠
authorTooru Fujisawa <arai_a@mac.com>
Tue, 05 Feb 2019 00:34:07 +0900
changeset 515376 69c5e07b7aaed0f5b6230ab37ece564f4cd6f715
parent 515375 614dba865475b0d1266b12c8ba2ef6600c877508
child 515377 45203e397c4a9342c90ab3f0d542119d122f3415
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersYoric
bugs1524965
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1524965 - Part 1: Handle break/continue outside the loop properly. r=Yoric Differential Revision: https://phabricator.services.mozilla.com/D18559
js/src/frontend/BinASTParser.cpp
js/src/frontend/BinSource.yaml
--- a/js/src/frontend/BinASTParser.cpp
+++ b/js/src/frontend/BinASTParser.cpp
@@ -2032,28 +2032,31 @@ JS::Result<ParseNode*> BinASTParser<Tok>
 #endif  // defined(DEBUG)
   RootedAtom label(cx_);
   MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom());
 
   if (label) {
     if (!IsIdentifier(label)) {
       return raiseError("Invalid identifier");
     }
-
-    auto validity = parseContext_->checkBreakStatement(label->asPropertyName());
-
-    if (validity.isErr()) {
-      switch (validity.unwrapErr()) {
-        case ParseContext::BreakStatementError::ToughBreak:
-          return raiseError(kind, "Not in a loop");
-        case ParseContext::BreakStatementError::LabelNotFound:
-          return raiseError(kind, "Label not found");
-      }
+  }
+
+  auto validity = parseContext_->checkBreakStatement(
+      label ? label->asPropertyName() : nullptr);
+  if (validity.isErr()) {
+    switch (validity.unwrapErr()) {
+      case ParseContext::BreakStatementError::ToughBreak:
+        this->error(JSMSG_TOUGH_BREAK);
+        return cx_->alreadyReportedError();
+      case ParseContext::BreakStatementError::LabelNotFound:
+        this->error(JSMSG_LABEL_NOT_FOUND);
+        return cx_->alreadyReportedError();
     }
   }
+
   BINJS_TRY_DECL(result, factory_.newBreakStatement(
                              label ? label->asPropertyName() : nullptr,
                              tokenizer_->pos(start)));
   return result;
 }
 
 template <typename Tok>
 JS::Result<ParseNode*> BinASTParser<Tok>::parseInterfaceCallExpression(
@@ -2317,26 +2320,28 @@ JS::Result<ParseNode*> BinASTParser<Tok>
 #endif  // defined(DEBUG)
   RootedAtom label(cx_);
   MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom());
 
   if (label) {
     if (!IsIdentifier(label)) {
       return raiseError("ContinueStatement - Label MUST be an identifier");
     }
-
-    auto validity = parseContext_->checkContinueStatement(
-        label ? label->asPropertyName() : nullptr);
-    if (validity.isErr()) {
-      switch (validity.unwrapErr()) {
-        case ParseContext::ContinueStatementError::NotInALoop:
-          return raiseError(kind, "Not in a loop");
-        case ParseContext::ContinueStatementError::LabelNotFound:
-          return raiseError(kind, "Label not found");
-      }
+  }
+
+  auto validity = parseContext_->checkContinueStatement(
+      label ? label->asPropertyName() : nullptr);
+  if (validity.isErr()) {
+    switch (validity.unwrapErr()) {
+      case ParseContext::ContinueStatementError::NotInALoop:
+        this->error(JSMSG_BAD_CONTINUE);
+        return cx_->alreadyReportedError();
+      case ParseContext::ContinueStatementError::LabelNotFound:
+        this->error(JSMSG_LABEL_NOT_FOUND);
+        return cx_->alreadyReportedError();
     }
   }
 
   BINJS_TRY_DECL(result, factory_.newContinueStatement(
                              label ? label->asPropertyName() : nullptr,
                              tokenizer_->pos(start)));
   return result;
 }
--- a/js/src/frontend/BinSource.yaml
+++ b/js/src/frontend/BinSource.yaml
@@ -632,29 +632,32 @@ BreakStatement:
           RootedAtom label(cx_);
           MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom());
 
   build: |
     if (label) {
       if (!IsIdentifier(label)) {
         return raiseError("Invalid identifier");
       }
-
-      auto validity
-          = parseContext_->checkBreakStatement(label->asPropertyName());
+    }
 
-      if (validity.isErr()) {
-        switch (validity.unwrapErr()) {
-          case ParseContext::BreakStatementError::ToughBreak:
-            return raiseError(kind, "Not in a loop");
-          case ParseContext::BreakStatementError::LabelNotFound:
-            return raiseError(kind, "Label not found");
-        }
+    auto validity
+        = parseContext_->checkBreakStatement(label ? label->asPropertyName()
+                                                    : nullptr);
+    if (validity.isErr()) {
+      switch (validity.unwrapErr()) {
+        case ParseContext::BreakStatementError::ToughBreak:
+          this->error(JSMSG_TOUGH_BREAK);
+          return cx_->alreadyReportedError();
+        case ParseContext::BreakStatementError::LabelNotFound:
+          this->error(JSMSG_LABEL_NOT_FOUND);
+          return cx_->alreadyReportedError();
       }
     }
+
     BINJS_TRY_DECL(result,
                    factory_.newBreakStatement(label ? label->asPropertyName()
                                                     : nullptr,
                                               tokenizer_->pos(start)));
 
 CallExpression:
   build: |
     auto op = JSOP_CALL;
@@ -770,32 +773,35 @@ ContinueStatement:
           RootedAtom label(cx_);
           MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom());
 
   build: |
     if (label) {
       if (!IsIdentifier(label)) {
         return raiseError("ContinueStatement - Label MUST be an identifier");
       }
+    }
 
-      auto validity
-          = parseContext_->checkContinueStatement(label ? label->asPropertyName()
-                                                        : nullptr);
-      if (validity.isErr()) {
-        switch (validity.unwrapErr()) {
-          case ParseContext::ContinueStatementError::NotInALoop:
-            return raiseError(kind, "Not in a loop");
-          case ParseContext::ContinueStatementError::LabelNotFound:
-            return raiseError(kind, "Label not found");
-        }
+    auto validity
+        = parseContext_->checkContinueStatement(label ? label->asPropertyName()
+                                                      : nullptr);
+    if (validity.isErr()) {
+      switch (validity.unwrapErr()) {
+        case ParseContext::ContinueStatementError::NotInALoop:
+          this->error(JSMSG_BAD_CONTINUE);
+          return cx_->alreadyReportedError();
+        case ParseContext::ContinueStatementError::LabelNotFound:
+          this->error(JSMSG_LABEL_NOT_FOUND);
+          return cx_->alreadyReportedError();
       }
     }
 
     BINJS_TRY_DECL(result,
-                   factory_.newContinueStatement(label ? label->asPropertyName() : nullptr,
+                   factory_.newContinueStatement(label ? label->asPropertyName()
+                                                       : nullptr,
                                                  tokenizer_->pos(start)));
 
 DataProperty:
   build: |
     if (!factory_.isUsableAsObjectPropertyName(name)) {
       return raiseError("DataProperty key kind");
     }