Bug 761695 - Move wrapper preservation stuff into a virtual trap. r=peterv

I'm not sure this stuff is correct for non-WN objects. Hopefully that will
come out in review.

Anyway, with this change, the expando infrastructure in XrayTraits is now
fully generic and non-WN-specific. To make things work for other objects,
we now need to implement the virtual traps and hoist the code that calls the
expando machinery out of XPCWrappedNativeXrayTraits.
This commit is contained in:
Bobby Holley 2012-10-05 18:59:23 +02:00
Родитель e5b93a88c9
Коммит 6894d29805
1 изменённых файлов: 34 добавлений и 11 удалений

Просмотреть файл

@ -13,6 +13,7 @@
#include "nsINode.h" #include "nsINode.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsContentUtils.h"
#include "XPCWrapper.h" #include "XPCWrapper.h"
#include "xpcprivate.h" #include "xpcprivate.h"
@ -143,6 +144,8 @@ public:
MOZ_NOT_REACHED("Call trap currently implemented only for XPCWNs"); MOZ_NOT_REACHED("Call trap currently implemented only for XPCWNs");
} }
virtual void preserveWrapper(JSObject *target) = 0;
JSObject* getExpandoObject(JSContext *cx, JSObject *target, JSObject* getExpandoObject(JSContext *cx, JSObject *target,
JSObject *consumer); JSObject *consumer);
JSObject* ensureExpandoObject(JSContext *cx, JSObject *wrapper, JSObject* ensureExpandoObject(JSContext *cx, JSObject *wrapper,
@ -194,6 +197,8 @@ public:
return GetWrappedNative(getTargetObject(wrapper)); return GetWrappedNative(getTargetObject(wrapper));
} }
virtual void preserveWrapper(JSObject *target);
typedef ResolvingId ResolvingIdImpl; typedef ResolvingId ResolvingIdImpl;
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper); virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper);
@ -226,6 +231,8 @@ public:
return false; return false;
} }
virtual void preserveWrapper(JSObject *target) { };
typedef ResolvingIdDummy ResolvingIdImpl; typedef ResolvingIdDummy ResolvingIdImpl;
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper); virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper);
@ -262,6 +269,8 @@ public:
typedef ResolvingIdDummy ResolvingIdImpl; typedef ResolvingIdDummy ResolvingIdImpl;
virtual void preserveWrapper(JSObject *target);
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper); virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper);
virtual JSObject* getExpandoChain(JSObject *obj) { virtual JSObject* getExpandoChain(JSObject *obj) {
@ -419,9 +428,6 @@ XrayTraits::attachExpandoObject(JSContext *cx, JSObject *target,
MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx)); MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx));
MOZ_ASSERT(!exclusiveGlobal || js::IsObjectInContextCompartment(exclusiveGlobal, cx)); MOZ_ASSERT(!exclusiveGlobal || js::IsObjectInContextCompartment(exclusiveGlobal, cx));
// We should only be used for WNs.
MOZ_ASSERT(IS_WN_WRAPPER(target));
// No duplicates allowed. // No duplicates allowed.
MOZ_ASSERT(!getExpandoObjectInternal(cx, target, origin, exclusiveGlobal)); MOZ_ASSERT(!getExpandoObjectInternal(cx, target, origin, exclusiveGlobal));
@ -443,14 +449,8 @@ XrayTraits::attachExpandoObject(JSContext *cx, JSObject *target,
// the wrapper. This keeps our expandos alive even if the Xray wrapper gets // the wrapper. This keeps our expandos alive even if the Xray wrapper gets
// collected. // collected.
JSObject *chain = getExpandoChain(target); JSObject *chain = getExpandoChain(target);
if (!chain) { if (!chain)
XPCWrappedNative *wn = preserveWrapper(target);
static_cast<XPCWrappedNative *>(xpc_GetJSPrivate(target));
nsRefPtr<nsXPCClassInfo> ci;
CallQueryInterface(wn->Native(), getter_AddRefs(ci));
if (ci)
ci->PreserveWrapper(wn->Native());
}
// Insert it at the front of the chain. // Insert it at the front of the chain.
JS_SetReservedSlot(expandoObject, JSSLOT_EXPANDO_NEXT, OBJECT_TO_JSVAL(chain)); JS_SetReservedSlot(expandoObject, JSSLOT_EXPANDO_NEXT, OBJECT_TO_JSVAL(chain));
@ -750,6 +750,17 @@ mozMatchesSelectorStub(JSContext *cx, unsigned argc, jsval *vp)
return true; return true;
} }
void
XPCWrappedNativeXrayTraits::preserveWrapper(JSObject *target)
{
XPCWrappedNative *wn =
static_cast<XPCWrappedNative *>(xpc_GetJSPrivate(target));
nsRefPtr<nsXPCClassInfo> ci;
CallQueryInterface(wn->Native(), getter_AddRefs(ci));
if (ci)
ci->PreserveWrapper(wn->Native());
}
bool bool
XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, JSObject *wrapper, XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, JSObject *wrapper,
JSObject *holder, jsid id, bool set, JSObject *holder, jsid id, bool set,
@ -1358,6 +1369,18 @@ DOMXrayTraits::enumerateNames(JSContext *cx, JSObject *wrapper, unsigned flags,
return true; return true;
} }
void
DOMXrayTraits::preserveWrapper(JSObject *target)
{
nsISupports *identity;
if (!mozilla::dom::UnwrapDOMObjectToISupports(target, identity))
return;
nsWrapperCache* cache = nullptr;
CallQueryInterface(identity, &cache);
if (cache)
nsContentUtils::PreserveWrapper(identity, cache);
}
JSObject* JSObject*
DOMXrayTraits::createHolder(JSContext *cx, JSObject *wrapper) DOMXrayTraits::createHolder(JSContext *cx, JSObject *wrapper)
{ {