Bug 1459384 - Make getStringOrTemplateToken handle calling badToken() itself if needed. r=arai
authorJeff Walden <jwalden@mit.edu>
Thu, 03 May 2018 22:02:32 -0700
changeset 417662 1a6282d1c64e470781962dd02e773ece36883d6f
parent 417661 1eb9f57d3bf8a07745c80f91f0c9c0c27b3d7a05
child 417663 1d16428bd8828013c40859d66215ce07c321412f
push id33977
push userncsoregi@mozilla.com
push dateThu, 10 May 2018 16:43:24 +0000
treeherdermozilla-central@17db33b6a124 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1459384
milestone62.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 1459384 - Make getStringOrTemplateToken handle calling badToken() itself if needed. r=arai
js/src/frontend/TokenStream.cpp
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -1646,17 +1646,17 @@ TokenStreamSpecific<CharT, AnyCharsAcces
         *ttp = tp->type;
     };
 
     // Check if in the middle of a template string. Have to get this out of
     // the way first.
     if (MOZ_UNLIKELY(modifier == TemplateTail)) {
         Token* tp;
         if (!getStringOrTemplateToken('`', &tp))
-            return badToken();
+            return false;
 
         FinishToken(tp);
         return true;
     }
 
     // This loop runs more than once only when whitespace or comments are
     // encountered.
     do {
@@ -1795,17 +1795,17 @@ TokenStreamSpecific<CharT, AnyCharsAcces
             return true;
         }
 
         // Look for a string or a template string.
         //
         if (c1kind == String) {
             Token* tp;
             if (!getStringOrTemplateToken(static_cast<char>(c), &tp))
-                return badToken();
+                return false;
 
             FinishToken(tp);
             return true;
         }
 
         // Skip over EOL chars, updating line state along the way.
         //
         if (c1kind == EOL) {
@@ -2120,17 +2120,17 @@ TokenStreamSpecific<CharT, AnyCharsAcces
 
             // Look for a multi-line comment.
             if (matchChar('*')) {
                 TokenStreamAnyChars& anyChars = anyCharsAccess();
                 unsigned linenoBefore = anyChars.lineno;
 
                 do {
                     if (!getChar(&c))
-                        return false;
+                        return badToken();
 
                     if (c == EOF) {
                         reportError(JSMSG_UNTERMINATED_COMMENT);
                         return badToken();
                     }
 
                     if (c == '*' && matchChar('/'))
                         break;
@@ -2249,18 +2249,19 @@ TokenStreamSpecific<CharT, AnyCharsAcces
             // We consumed a bad character/code point.  Put it back so the
             // error location is the bad character.
             ungetCodePointIgnoreEOL(c);
             error(JSMSG_ILLEGAL_CHARACTER);
             return badToken();
         }
 
         MOZ_CRASH("should either have called |FinishToken()| and returned "
-                  "true, returned |badToken()|, or continued following "
-                  "whitespace or a comment");
+                  "true, returned |badToken()|, returned false after failure "
+                  "of a function that would have called |badToken()|, or "
+                  "continued following whitespace or a comment");
     } while (true);
 }
 
 template<typename CharT, class AnyCharsAccess>
 bool
 TokenStreamSpecific<CharT, AnyCharsAccess>::getStringOrTemplateToken(char untilChar, Token** tp)
 {
     MOZ_ASSERT(untilChar == '\'' || untilChar == '"' || untilChar == '`',
@@ -2270,16 +2271,22 @@ TokenStreamSpecific<CharT, AnyCharsAcces
 
     bool parsingTemplate = (untilChar == '`');
     bool templateHead = false;
 
     TokenStart start(sourceUnits, -1);
     *tp = newToken(start);
     tokenbuf.clear();
 
+    // Run the bad-token code for every path out of this function except the
+    // one success-case.
+    auto noteBadToken = MakeScopeExit([this]() {
+        this->badToken();
+    });
+
     // We need to detect any of these chars:  " or ', \n (or its
     // equivalents), \\, EOF.  Because we detect EOL sequences here and
     // put them back immediately, we can use getCharIgnoreEOL().
     while ((c = getCharIgnoreEOL()) != untilChar) {
         if (c == EOF) {
             ungetCharIgnoreEOL(c);
             const char delimiters[] = { untilChar, untilChar, '\0' };
             error(JSMSG_EOF_BEFORE_END_OF_LITERAL, delimiters);
@@ -2518,16 +2525,17 @@ TokenStreamSpecific<CharT, AnyCharsAcces
         (*tp)->type = TokenKind::String;
     } else {
         if (templateHead)
             (*tp)->type = TokenKind::TemplateHead;
         else
             (*tp)->type = TokenKind::NoSubsTemplate;
     }
 
+    noteBadToken.release();
     (*tp)->setAtom(atom);
     return true;
 }
 
 const char*
 TokenKindToDesc(TokenKind tt)
 {
     switch (tt) {