Bug 1166351 - Add an assertion to make sure that we use the correct cached XBL binding prototypes. r?bholley draft
authorMike Conley <mconley@mozilla.com>
Fri, 29 Apr 2016 14:54:12 -0400
changeset 368390 999e489461931506ef888c61891cd71de2f3d034
parent 367838 3780a3a6b83aeda143f9562829c830410a0c961e
child 368391 e529bd929a2d7bd8024c1da874734ac5aa2561d1
child 368570 29756024260ab416b5d1723e33311c4a7f4c6aa3
push id18524
push usermconley@mozilla.com
push dateWed, 18 May 2016 17:56:04 +0000
reviewersbholley
bugs1166351
milestone49.0a1
Bug 1166351 - Add an assertion to make sure that we use the correct cached XBL binding prototypes. r?bholley MozReview-Commit-ID: 7MfslXmortQ
dom/xbl/nsXBLBinding.cpp
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -952,16 +952,25 @@ GetOrCreateMapEntryForPrototype(JSContex
   if (!JS::SetWeakMapEntry(cx, map, wrappedProto, entryVal)) {
     NS_WARNING("SetWeakMapEntry failed, probably due to non-preservable WeakMap "
                "key. XBL binding will fail for this element.");
     return nullptr;
   }
   return entry;
 }
 
+static
+nsXBLPrototypeBinding*
+GetProtoBindingFromClassObject(JSObject* obj)
+{
+  MOZ_ASSERT(JS_GetClass(obj) == &gPrototypeJSClass);
+  return static_cast<nsXBLPrototypeBinding*>(::JS_GetReservedSlot(obj, 0).toPrivate());
+}
+
+
 // static
 nsresult
 nsXBLBinding::DoInitJSClass(JSContext *cx,
                             JS::Handle<JSObject*> obj,
                             const nsAFlatString& aClassName,
                             nsXBLPrototypeBinding* aProtoBinding,
                             JS::MutableHandle<JSObject*> aClassObject,
                             bool* aNew)
@@ -1007,17 +1016,19 @@ nsXBLBinding::DoInitJSClass(JSContext *c
   JS::Rooted<JSObject*> proto(cx);
   JS::Rooted<JS::PropertyDescriptor> desc(cx);
   if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(), &desc)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   *aNew = !desc.object();
   if (desc.object()) {
     proto = &desc.value().toObject();
-    MOZ_ASSERT(JS_GetClass(js::UncheckedUnwrap(proto)) == &gPrototypeJSClass);
+    DebugOnly<nsXBLPrototypeBinding*> cachedBinding =
+      GetProtoBindingFromClassObject(js::UncheckedUnwrap(proto));
+    MOZ_ASSERT(cachedBinding == aProtoBinding);
   } else {
 
     // We need to create the prototype. First, enter the compartment where it's
     // going to live, and create it.
     JSAutoCompartment ac2(cx, global);
     proto = JS_NewObjectWithGivenProto(cx, &gPrototypeJSClass, parent_proto);
     if (!proto) {
       return NS_ERROR_OUT_OF_MEMORY;