Bug 1633468 - Make dom/bindings/Codegen.py compare against JSID_VOID to detect uninitialized jsid members r=mccr8
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 28 Apr 2020 18:12:12 +0000
changeset 526534 d32836d92400529c65fff52690b71e9c8d8ef151
parent 526533 9647b3d42c393b606b74cf1562ef0f19aa05b7ac
child 526535 20630fb87f8254888ad16a1a176749edde388729
push id37358
push useropoprus@mozilla.com
push dateWed, 29 Apr 2020 03:05:14 +0000
treeherdermozilla-central@6bb8423186c1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1633468
milestone77.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 1633468 - Make dom/bindings/Codegen.py compare against JSID_VOID to detect uninitialized jsid members r=mccr8 Differential Revision: https://phabricator.services.mozilla.com/D72701
dom/bindings/Codegen.py
xpcom/base/CycleCollectedJSContext.cpp
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -14054,17 +14054,17 @@ class CGNamespacedEnum(CGThing):
 def initIdsClassMethod(identifiers, atomCacheName):
     idinit = ['!atomsCache->%s.init(cx, "%s")' %
               (CGDictionary.makeIdName(id),
                id)
               for id in identifiers]
     idinit.reverse()
     body = fill(
         """
-        MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
+        MOZ_ASSERT(JSID_IS_VOID(*reinterpret_cast<jsid*>(atomsCache)));
 
         // Initialize these in reverse order so that any failure leaves the first one
         // uninitialized.
         if (${idinit}) {
           return false;
         }
         return true;
         """,
@@ -14144,17 +14144,18 @@ class CGDictionary(CGThing):
             """)
 
         if self.needToInitIds:
             body += fill(
                 """
                 ${dictName}Atoms* atomsCache = nullptr;
                 if (cx) {
                   atomsCache = GetAtomCache<${dictName}Atoms>(cx);
-                  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
+                  if (JSID_IS_VOID(*reinterpret_cast<jsid*>(atomsCache)) &&
+                      !InitIds(cx, atomsCache)) {
                     return false;
                   }
                 }
 
                 """,
                 dictName=self.makeClassName(self.dictionary))
 
         if self.dictionary.parent:
@@ -14327,17 +14328,18 @@ class CGDictionary(CGThing):
             """), const=True)
 
     def toObjectInternalMethod(self):
         body = ""
         if self.needToInitIds:
             body += fill(
                 """
                 ${dictName}Atoms* atomsCache = GetAtomCache<${dictName}Atoms>(cx);
-                if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
+                if (JSID_IS_VOID(*reinterpret_cast<jsid*>(atomsCache)) &&
+                    !InitIds(cx, atomsCache)) {
                   return false;
                 }
 
                 """,
                 dictName=self.makeClassName(self.dictionary))
 
         if self.dictionary.parent:
             body += fill(
@@ -17707,17 +17709,18 @@ class CallbackOperationBase(CallbackMeth
 
     def getThisVal(self):
         return "thisValue"
 
     def getCallableDecl(self):
         getCallableFromProp = fill(
             """
             ${atomCacheName}* atomsCache = GetAtomCache<${atomCacheName}>(cx);
-            if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
+            if ((JSID_IS_VOID(*reinterpret_cast<jsid*>(atomsCache)) &&
+                 !InitIds(cx, atomsCache)) ||
                 !GetCallableProperty(cx, atomsCache->${methodAtomName}, &callable)) {
               aRv.Throw(NS_ERROR_UNEXPECTED);
               return${errorReturn};
             }
             """,
             methodAtomName=CGDictionary.makeIdName(self.methodName),
             atomCacheName=self.descriptorProvider.interface.identifier.name + "Atoms",
             errorReturn=self.getDefaultRetval())
@@ -17789,17 +17792,18 @@ class CallbackGetter(CallbackAccessor):
     def getRvalDecl(self):
         return "JS::Rooted<JS::Value> rval(cx);\n"
 
     def getCall(self):
         return fill(
             """
             JS::Rooted<JSObject *> callback(cx, mCallback);
             ${atomCacheName}* atomsCache = GetAtomCache<${atomCacheName}>(cx);
-            if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
+            if ((JSID_IS_VOID(*reinterpret_cast<jsid*>(atomsCache))
+                 && !InitIds(cx, atomsCache)) ||
                 !JS_GetPropertyById(cx, callback, atomsCache->${attrAtomName}, &rval)) {
               aRv.Throw(NS_ERROR_UNEXPECTED);
               return${errorReturn};
             }
             """,
             atomCacheName=self.descriptorProvider.interface.identifier.name + "Atoms",
             attrAtomName=CGDictionary.makeIdName(self.descriptorProvider.binaryNameFor(self.attrName)),
             errorReturn=self.getDefaultRetval())
@@ -17817,17 +17821,18 @@ class CallbackSetter(CallbackAccessor):
         # We don't need an rval
         return ""
 
     def getCall(self):
         return fill(
             """
             MOZ_ASSERT(argv.length() == 1);
             ${atomCacheName}* atomsCache = GetAtomCache<${atomCacheName}>(cx);
-            if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
+            if ((JSID_IS_VOID(*reinterpret_cast<jsid*>(atomsCache)) &&
+                 !InitIds(cx, atomsCache)) ||
                 !JS_SetPropertyById(cx, CallbackKnownNotGray(), atomsCache->${attrAtomName}, argv[0])) {
               aRv.Throw(NS_ERROR_UNEXPECTED);
               return${errorReturn};
             }
             """,
             atomCacheName=self.descriptorProvider.interface.identifier.name + "Atoms",
             attrAtomName=CGDictionary.makeIdName(self.descriptorProvider.binaryNameFor(self.attrName)),
             errorReturn=self.getDefaultRetval())
--- a/xpcom/base/CycleCollectedJSContext.cpp
+++ b/xpcom/base/CycleCollectedJSContext.cpp
@@ -57,20 +57,16 @@ CycleCollectedJSContext::CycleCollectedJ
       mJSContext(nullptr),
       mDoingStableStates(false),
       mTargetedMicroTaskRecursionDepth(0),
       mMicroTaskLevel(0),
       mDebuggerRecursionDepth(0),
       mMicroTaskRecursionDepth(0) {
   MOZ_COUNT_CTOR(CycleCollectedJSContext);
 
-  // Reinitialize PerThreadAtomCache because dom/bindings/Codegen.py compares
-  // against zero rather than JSID_VOID to detect uninitialized jsid members.
-  memset(static_cast<PerThreadAtomCache*>(this), 0, sizeof(PerThreadAtomCache));
-
   nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
   mOwningThread = thread.forget().downcast<nsThread>().take();
   MOZ_RELEASE_ASSERT(mOwningThread);
 }
 
 CycleCollectedJSContext::~CycleCollectedJSContext() {
   MOZ_COUNT_DTOR(CycleCollectedJSContext);
   // If the allocation failed, here we are.