Bug 802243 - WrapperCache DOMStringMap, r=bz
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Wed, 17 Oct 2012 04:09:42 +0300
changeset 110559 cf65ae722cbb7ac2d0be57b62fb760e8718b4f56
parent 110558 8f702f78a9292c364e06a74673cb634fdb4b1193
child 110560 62f61773ad4577a1f5bffdac7eb00ffbee5ca1fc
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersbz
bugs802243
milestone19.0a1
Bug 802243 - WrapperCache DOMStringMap, r=bz
content/html/content/src/nsDOMStringMap.cpp
content/html/content/src/nsDOMStringMap.h
dom/base/nsDOMClassInfo.cpp
--- a/content/html/content/src/nsDOMStringMap.cpp
+++ b/content/html/content/src/nsDOMStringMap.cpp
@@ -10,28 +10,35 @@
 #include "nsDOMClassInfoID.h"
 #include "nsGenericHTMLElement.h"
 #include "nsContentUtils.h"
 
 DOMCI_DATA(DOMStringMap, nsDOMStringMap)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMStringMap)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMStringMap)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mElement)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMStringMap)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   // Check that mElement exists in case the unlink code is run more than once.
   if (tmp->mElement) {
     // Call back to element to null out weak reference to this object.
     tmp->mElement->ClearDataset();
     tmp->mElement = nullptr;
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMStringMap)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMStringMap)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIDOMDOMStringMap)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMStringMap)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMStringMap)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMStringMap)
 
--- a/content/html/content/src/nsDOMStringMap.h
+++ b/content/html/content/src/nsDOMStringMap.h
@@ -8,26 +8,52 @@
 #define nsDOMStringMap_h
 
 #include "nsIDOMDOMStringMap.h"
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
+#include "nsWrapperCache.h"
+#include "nsGenericHTMLElement.h"
 
-class nsGenericHTMLElement;
-
-class nsDOMStringMap : public nsIDOMDOMStringMap
+class nsDOMStringMap : public nsIDOMDOMStringMap,
+                       public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIDOMDOMSTRINGMAP
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMStringMap)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMStringMap)
+
+  nsINode* GetParentObject()
+  {
+    return mElement;
+  }
 
+  static nsDOMStringMap* FromSupports(nsISupports* aSupports)
+  {
+    nsIDOMDOMStringMap* map =
+      static_cast<nsDOMStringMap*>(aSupports);
+#ifdef DEBUG
+    {
+      nsCOMPtr<nsIDOMDOMStringMap> map_qi =
+        do_QueryInterface(aSupports);
+
+      // If this assertion fires the QI implementation for the object in
+      // question doesn't use the nsIDOMDOMStringMap pointer as the
+      // nsISupports pointer. That must be fixed, or we'll crash...
+      NS_ASSERTION(map_qi == map, "Uh, fix QI!");
+    }
+#endif
+
+    return static_cast<nsDOMStringMap*>(map);
+  }
+
+  
   nsDOMStringMap(nsGenericHTMLElement* aElement);
 
   // GetDataPropList is not defined in IDL due to difficulty
   // of returning arrays in IDL. Instead, we cast to this
   // class if this method needs to be called.
   nsresult GetDataPropList(nsTArray<nsString>& aResult);
 
   nsresult RemovePropInternal(nsIAtom* aAttr);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -8477,23 +8477,23 @@ nsDOMStringMapSH::Enumerate(nsIXPConnect
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMStringMapSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
                             JSObject *globalObj, JSObject **parentObj)
 {
-  *parentObj = globalObj;
-
-  nsDOMStringMap* dataset = static_cast<nsDOMStringMap*>(nativeObj);
-
-  // Parent the string map to its element.
-  nsINode* element = dataset->GetElement();
-  return WrapNativeParent(cx, globalObj, element, element, parentObj);
+  nsDOMStringMap* map = nsDOMStringMap::FromSupports(nativeObj);
+  nsINode* native_parent = map->GetParentObject();
+  if (!native_parent) {
+    return nsDOMClassInfo::PreCreate(nativeObj, cx, globalObj, parentObj);
+  }
+
+  return WrapNativeParent(cx, globalObj, native_parent, parentObj);
 }
 
 NS_IMETHODIMP
 nsDOMStringMapSH::DelProperty(nsIXPConnectWrappedNative *wrapper,
                               JSContext *cx, JSObject *obj, jsid id,
                               jsval *vp, bool *_retval)
 {
   nsCOMPtr<nsIDOMDOMStringMap> dataset(do_QueryWrappedNative(wrapper, obj));