From 0bc1eebe87d6b52a624e9da6d289e622b9c00883 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Fri, 23 Mar 2012 14:59:04 -0700 Subject: [PATCH] Bug 733984 - Stop specializing createHolder, and simplify holder creation in WrapperFactory::Rewrap. r=mrbkap --- js/xpconnect/wrappers/WrapperFactory.cpp | 26 ++++------ js/xpconnect/wrappers/XrayWrapper.cpp | 61 +++++++++++++----------- js/xpconnect/wrappers/XrayWrapper.h | 4 +- 3 files changed, 44 insertions(+), 47 deletions(-) diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index 7babdfbbea8b..be799fceb852 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -287,7 +287,7 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO JSCompartment *origin = js::GetObjectCompartment(obj); JSCompartment *target = js::GetContextCompartment(cx); - JSObject *xrayHolder = nsnull; + bool usingXray = false; Wrapper *wrapper; CompartmentPrivate *targetdata = @@ -320,10 +320,8 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO wrapper = &XrayProxy::singleton; } else { typedef XrayWrapper Xray; + usingXray = true; wrapper = &Xray::singleton; - xrayHolder = Xray::createHolder(cx, obj, parent); - if (!xrayHolder) - return nsnull; } } else { wrapper = &NoWaiverWrapper::singleton; @@ -344,11 +342,9 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO (wn = GetWrappedNative(cx, obj)) && wn->HasProto() && wn->GetProto()->ClassIsDOMObject()) { typedef XrayWrapper Xray; + usingXray = true; wrapper = &FilteringWrapper::singleton; - xrayHolder = Xray::createHolder(cx, obj, parent); - if (!xrayHolder) - return nsnull; } else { wrapper = &FilteringWrapper::singleton; @@ -365,10 +361,8 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO wrapper = &XrayProxy::singleton; } else { typedef XrayWrapper Xray; + usingXray = true; wrapper = &Xray::singleton; - xrayHolder = Xray::createHolder(cx, obj, parent); - if (!xrayHolder) - return nsnull; } } else { wrapper = &CrossCompartmentWrapper::singleton; @@ -391,6 +385,7 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO CrossOriginAccessiblePropertiesOnly>::singleton; } else { typedef XrayWrapper Xray; + usingXray = true; // Location objects can become same origin after navigation, so we might // have to grant transparent access later on. @@ -401,18 +396,17 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO wrapper = &FilteringWrapper::singleton; } - - xrayHolder = Xray::createHolder(cx, obj, parent); - if (!xrayHolder) - return nsnull; } } } JSObject *wrapperObj = Wrapper::New(cx, obj, wrappedProto, parent, wrapper); - if (!wrapperObj || !xrayHolder) + if (!wrapperObj || !usingXray) return wrapperObj; + JSObject *xrayHolder = XrayUtils::createHolder(cx, obj, parent); + if (!xrayHolder) + return nsnull; js::SetProxyExtra(wrapperObj, 0, js::ObjectValue(*xrayHolder)); return wrapperObj; } @@ -430,7 +424,7 @@ WrapperFactory::IsLocationObject(JSObject *obj) JSObject * WrapperFactory::WrapLocationObject(JSContext *cx, JSObject *obj) { - JSObject *xrayHolder = LW::createHolder(cx, obj, js::GetObjectParent(obj)); + JSObject *xrayHolder = XrayUtils::createHolder(cx, obj, js::GetObjectParent(obj)); if (!xrayHolder) return nsnull; JSObject *wrapperObj = Wrapper::New(cx, obj, js::GetObjectProto(obj), js::GetObjectParent(obj), diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 7a6b738e2696..e7781bd0a345 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -103,6 +103,9 @@ holder_get(JSContext *cx, JSObject *holder, jsid id, jsval *vp); static JSBool holder_set(JSContext *cx, JSObject *holder, jsid id, JSBool strict, jsval *vp); + +static XPCWrappedNative *GetWrappedNative(JSObject *obj); + namespace XrayUtils { JSClass HolderClass = { @@ -112,6 +115,35 @@ JSClass HolderClass = { JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub }; +JSObject * +createHolder(JSContext *cx, JSObject *wrappedNative, JSObject *parent) +{ + JSObject *holder = JS_NewObjectWithGivenProto(cx, &HolderClass, nsnull, parent); + if (!holder) + return nsnull; + + CompartmentPrivate *priv = + (CompartmentPrivate *)JS_GetCompartmentPrivate(js::GetObjectCompartment(holder)); + JSObject *inner = JS_ObjectToInnerObject(cx, wrappedNative); + XPCWrappedNative *wn = GetWrappedNative(inner); + Value expando = ObjectOrNullValue(priv->LookupExpandoObject(wn)); + + // A note about ownership: the holder has a direct pointer to the wrapped + // native that we're wrapping. Normally, we'd have to AddRef the pointer + // so that it doesn't have to be collected, but then we'd have to tell the + // cycle collector. Fortunately for us, we know that the Xray wrapper + // itself has a reference to the flat JS object which will hold the + // wrapped native alive. Furthermore, the reachability of that object and + // the associated holder are exactly the same, so we can use that for our + // strong reference. + JS_ASSERT(IS_WN_WRAPPER(wrappedNative) || + js::GetObjectClass(wrappedNative)->ext.innerObject); + js::SetReservedSlot(holder, JSSLOT_WN, PrivateValue(wn)); + js::SetReservedSlot(holder, JSSLOT_RESOLVING, PrivateValue(NULL)); + js::SetReservedSlot(holder, JSSLOT_EXPANDO, expando); + return holder; +} + } using namespace XrayUtils; @@ -1042,35 +1074,6 @@ XrayWrapper::construct(JSContext *cx, JSObject *wrapper, unsigned argc, return true; } -template -JSObject * -XrayWrapper::createHolder(JSContext *cx, JSObject *wrappedNative, JSObject *parent) -{ - JSObject *holder = JS_NewObjectWithGivenProto(cx, &HolderClass, nsnull, parent); - if (!holder) - return nsnull; - - CompartmentPrivate *priv = - (CompartmentPrivate *)JS_GetCompartmentPrivate(js::GetObjectCompartment(holder)); - JSObject *inner = JS_ObjectToInnerObject(cx, wrappedNative); - XPCWrappedNative *wn = GetWrappedNative(inner); - Value expando = ObjectOrNullValue(priv->LookupExpandoObject(wn)); - - // A note about ownership: the holder has a direct pointer to the wrapped - // native that we're wrapping. Normally, we'd have to AddRef the pointer - // so that it doesn't have to be collected, but then we'd have to tell the - // cycle collector. Fortunately for us, we know that the Xray wrapper - // itself has a reference to the flat JS object which will hold the - // wrapped native alive. Furthermore, the reachability of that object and - // the associated holder are exactly the same, so we can use that for our - // strong reference. - JS_ASSERT(IS_WN_WRAPPER(wrappedNative) || - js::GetObjectClass(wrappedNative)->ext.innerObject); - js::SetReservedSlot(holder, JSSLOT_WN, PrivateValue(wn)); - js::SetReservedSlot(holder, JSSLOT_RESOLVING, PrivateValue(NULL)); - js::SetReservedSlot(holder, JSSLOT_EXPANDO, expando); - return holder; -} XrayProxy::XrayProxy(unsigned flags) : XrayWrapper(flags) diff --git a/js/xpconnect/wrappers/XrayWrapper.h b/js/xpconnect/wrappers/XrayWrapper.h index d9bd4ab592b7..18de57789439 100644 --- a/js/xpconnect/wrappers/XrayWrapper.h +++ b/js/xpconnect/wrappers/XrayWrapper.h @@ -52,6 +52,8 @@ namespace XrayUtils { extern JSClass HolderClass; +JSObject *createHolder(JSContext *cx, JSObject *wrappedNative, JSObject *parent); + bool IsTransparent(JSContext *cx, JSObject *wrapper); @@ -94,8 +96,6 @@ class XrayWrapper : public Base { virtual bool construct(JSContext *cx, JSObject *wrapper, unsigned argc, js::Value *argv, js::Value *rval); - static JSObject *createHolder(JSContext *cx, JSObject *wrappedNative, JSObject *parent); - static XrayWrapper singleton; private: