Bug 1524965 - Part 2: Handle break/continue outside the loop properly. r=Yoric
authorTooru Fujisawa <arai_a@mac.com>
Tue, 05 Feb 2019 00:34:07 +0900
changeset 516094 30e403f80bfd23dae0b7e416f7772fe72157e01f
parent 516093 7fce2598a3de8f3372ae4d7baba5f05b3ed36e5a
child 516095 1143fee910c70ae6ea25e325b7908f38c8cfeba6
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 2: Handle break/continue outside the loop properly. r=Yoric
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");
     }