Bug 1736552 - Do not read Token.type field after TokenStreamSpecific::advance. r=tcampbell
authorTooru Fujisawa <arai_a@mac.com>
Mon, 25 Oct 2021 20:37:37 +0000
changeset 596914 0379d29570946dcaa2e52b7b8f7b50f8983f63d5
parent 596913 ba194f73b75bae2d6a70c6a9f09ba2b874dc2ab6
child 596915 3364ef8828e756ed15d4563eaa23da47b2ee4d24
push id152118
push userarai_a@mac.com
push dateMon, 25 Oct 2021 20:40:02 +0000
treeherderautoland@0379d2957094 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1736552
milestone95.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 1736552 - Do not read Token.type field after TokenStreamSpecific::advance. r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D128890
js/src/frontend/Parser.cpp
js/src/frontend/TokenStream.cpp
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -3476,18 +3476,44 @@ FunctionNode* Parser<FullParseHandler, U
     }
   }
   funNode = &node->as<FunctionNode>();
 
   return funNode;
 }
 
 void ParserBase::setFunctionEndFromCurrentToken(FunctionBox* funbox) const {
-  MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof);
-  funbox->setEnd(anyChars.currentToken().pos.end);
+  if (compilationState_.isInitialStencil()) {
+    MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof);
+    MOZ_ASSERT(anyChars.currentToken().type < TokenKind::Limit);
+    funbox->setEnd(anyChars.currentToken().pos.end);
+  } else {
+    // If we're delazifying an arrow function with expression body and
+    // the expression is also a function, we arrive here immediately after
+    // skipping the function by Parser::skipLazyInnerFunction.
+    //
+    //   a => b => c
+    //              ^
+    //              |
+    //              we're here
+    //
+    // In that case, the current token's type field is either Limit or
+    // poisoned.
+    // We shouldn't read the value if it's poisoned.
+    // See TokenStreamSpecific<Unit, AnyCharsAccess>::advance and
+    // mfbt/MemoryChecking.h for more details.
+    //
+    // Also, in delazification, the FunctionBox should already have the
+    // correct extent, and we shouldn't overwrite it here.
+    // See ScriptStencil variant of PerHandlerParser::newFunctionBox.
+#if !defined(MOZ_ASAN) && !defined(MOZ_MSAN) && !defined(MOZ_VALGRIND)
+    MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof);
+#endif
+    MOZ_ASSERT(funbox->extent().sourceEnd == anyChars.currentToken().pos.end);
+  }
 }
 
 template <class ParseHandler, typename Unit>
 bool GeneralParser<ParseHandler, Unit>::functionFormalParametersAndBody(
     InHandling inHandling, YieldHandling yieldHandling,
     FunctionNodeType* funNode, FunctionSyntaxKind kind,
     const Maybe<uint32_t>& parameterListEnd /* = Nothing() */,
     bool isStandaloneFunction /* = false */) {
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -1552,16 +1552,19 @@ bool TokenStreamSpecific<Unit, AnyCharsA
       return false;
     }
   }
 
   TokenStreamAnyChars& anyChars = anyCharsAccess();
   Token* cur = const_cast<Token*>(&anyChars.currentToken());
   cur->pos.begin = this->sourceUnits.offset();
   cur->pos.end = cur->pos.begin;
+#ifdef DEBUG
+  cur->type = TokenKind::Limit;
+#endif
   MOZ_MAKE_MEM_UNDEFINED(&cur->type, sizeof(cur->type));
   anyChars.lookahead = 0;
   return true;
 }
 
 template <typename Unit, class AnyCharsAccess>
 void TokenStreamSpecific<Unit, AnyCharsAccess>::seekTo(const Position& pos) {
   TokenStreamAnyChars& anyChars = anyCharsAccess();