Bug 857417. Trigger a fatal assertion when wrapping a wrappercached and nsISupports WebIDL object which has the wrapper cache before the nsISupports in its object layout. r=khuey
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 08 Apr 2013 17:04:21 -0400
changeset 128167 ef9509eb9a4c5fa2065bdb3ea4dd51b516748f27
parent 128166 4547d76ad82858608d9474217b39de105d576d6a
child 128168 3146a645d19e00c8c5a8c258c86e746bd4a19e32
push id26176
push userbzbarsky@mozilla.com
push dateTue, 09 Apr 2013 16:26:52 +0000
treeherdermozilla-inbound@ef9509eb9a4c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs857417
milestone23.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 857417. Trigger a fatal assertion when wrapping a wrappercached and nsISupports WebIDL object which has the wrapper cache before the nsISupports in its object layout. r=khuey
content/xslt/src/xpath/nsXPathEvaluator.h
dom/bindings/Codegen.py
--- a/content/xslt/src/xpath/nsXPathEvaluator.h
+++ b/content/xslt/src/xpath/nsXPathEvaluator.h
@@ -72,13 +72,19 @@ private:
                               nsTArray<nsCString> *aContractIDs,
                               nsCOMArray<nsISupports> *aState,
                               nsIDOMXPathExpression **aResult);
 
     nsWeakPtr mDocument;
     nsRefPtr<txResultRecycler> mRecycler;
 };
 
+inline nsISupports*
+ToSupports(nsXPathEvaluator* e)
+{
+    return static_cast<nsIDOMXPathEvaluator*>(e);
+}
+
 /* d0a75e02-b5e7-11d5-a7f2-df109fb8a1fc */
 #define TRANSFORMIIX_XPATH_EVALUATOR_CID   \
 { 0xd0a75e02, 0xb5e7, 0x11d5, { 0xa7, 0xf2, 0xdf, 0x10, 0x9f, 0xb8, 0xa1, 0xfc } }
 
 #endif
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1905,16 +1905,20 @@ def AssertInheritanceChain(descriptor):
     iface = descriptor.interface
     while iface:
         desc = descriptor.getDescriptor(iface.identifier.name)
         asserts += (
             "  MOZ_ASSERT(static_cast<%s*>(aObject) == \n"
             "             reinterpret_cast<%s*>(aObject));\n" %
             (desc.nativeType, desc.nativeType))
         iface = iface.parent
+    if descriptor.nativeOwnership == 'nsisupports':
+        asserts += (
+            "  MOZ_ASSERT(ToSupports(aObject) == \n"
+            "             reinterpret_cast<nsISupports*>(aObject));\n")
     return asserts
 
 class CGWrapWithCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that implements nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
@@ -1925,18 +1929,24 @@ class CGWrapWithCacheMethod(CGAbstractMe
                 Argument('nsWrapperCache*', 'aCache')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
         self.properties = properties
 
     def definition_body(self):
         if self.descriptor.workers:
             return """  return aObject->GetJSObject();"""
 
+        if self.descriptor.nativeOwnership == 'nsisupports':
+            assertISupportsInheritance = (
+                '  MOZ_ASSERT(reinterpret_cast<nsWrapperCache*>(aObject) != aCache,\n'
+                '             "nsISupports must be on our primary inheritance chain");\n')
+        else:
+            assertISupportsInheritance = ""
         return """%s
-
+%s
   JSObject* parent = WrapNativeParent(aCx, aScope, aObject->GetParentObject());
   if (!parent) {
     return NULL;
   }
 
   // That might have ended up wrapping us already, due to the wonders
   // of XBL.  Check for that, and bail out as needed.  Scope so we don't
   // collide with the "obj" we declare in CreateBindingJSObject.
@@ -1954,16 +1964,17 @@ class CGWrapWithCacheMethod(CGAbstractMe
     return NULL;
   }
 
 %s
 %s
   aCache->SetWrapper(obj);
 
   return obj;""" % (AssertInheritanceChain(self.descriptor),
+                    assertISupportsInheritance,
                     CreateBindingJSObject(self.descriptor, "parent"),
                     InitUnforgeableProperties(self.descriptor, self.properties))
 
 class CGWrapMethod(CGAbstractMethod):
     def __init__(self, descriptor):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),