Bug 958641 - De-holder nsIXPConnect::WrapNative. r=gabor

This commit is contained in:
Andrew McCreight 2015-07-01 11:17:17 -07:00
parent ee4aa67f3d
commit f8e0ff1fa5
12 changed files with 79 additions and 104 deletions

View File

@ -1232,13 +1232,9 @@ _getpluginelement(NPP npp)
nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
NS_ENSURE_TRUE(xpc, nullptr);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
JS::RootedObject obj(cx);
xpc->WrapNative(cx, ::JS::CurrentGlobalOrNull(cx), element,
NS_GET_IID(nsIDOMElement),
getter_AddRefs(holder));
NS_ENSURE_TRUE(holder, nullptr);
JS::Rooted<JSObject*> obj(cx, holder->GetJSObject());
NS_GET_IID(nsIDOMElement), obj.address());
NS_ENSURE_TRUE(obj, nullptr);
return nsJSObjWrapper::GetNewOrUsed(npp, cx, obj);

View File

@ -266,7 +266,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
%}
[noscript, uuid(241fbefa-89dc-42b2-b180-08167d4b351b)]
[noscript, uuid(8bc1230e-036b-4749-8763-768ed65df143)]
interface nsIXPConnect : nsISupports
{
%{ C++
@ -303,13 +303,6 @@ interface nsIXPConnect : nsISupports
/**
* wrapNative will create a new JSObject or return an existing one.
*
* The JSObject is returned inside a refcounted nsIXPConnectJSObjectHolder.
* As long as this holder is held the JSObject will be protected from
* collection by JavaScript's garbage collector. It is a good idea to
* transfer the JSObject to some equally protected place before releasing
* the holder (i.e. use JS_SetProperty to make this object a property of
* some other JSObject).
*
* This method now correctly deals with cases where the passed in xpcom
* object already has an associated JSObject for the cases:
* 1) The xpcom object has already been wrapped for use in the same scope
@ -332,12 +325,21 @@ interface nsIXPConnect : nsISupports
* NS_ERROR_XPC_CANT_GET_JSOBJECT_OF_DOM_OBJECT
* NS_ERROR_FAILURE
*/
nsIXPConnectJSObjectHolder
JSObjectPtr
wrapNative(in JSContextPtr aJSContext,
in JSObjectPtr aScope,
in nsISupports aCOMObj,
in nsIIDRef aIID);
/**
* Same as wrapNative, but it returns the JSObject in an nsIXPConnectJSObjectHolder.
*/
nsIXPConnectJSObjectHolder
wrapNativeHolder(in JSContextPtr aJSContext,
in JSObjectPtr aScope,
in nsISupports aCOMObj,
in nsIIDRef aIID);
/**
* Same as wrapNative, but it returns the JSObject in aVal. C++ callers
* must ensure that aVal is rooted.

View File

@ -584,13 +584,11 @@ mozJSComponentLoader::PrepareObjectForLocation(JSContext* aCx,
*aRealFile = true;
if (XRE_GetProcessType() == GeckoProcessType_Default) {
nsCOMPtr<nsIXPConnectJSObjectHolder> locationHolder;
RootedObject locationObj(aCx);
rv = xpc->WrapNative(aCx, obj, aComponentFile,
NS_GET_IID(nsIFile),
getter_AddRefs(locationHolder));
locationObj.address());
NS_ENSURE_SUCCESS(rv, nullptr);
RootedObject locationObj(aCx, locationHolder->GetJSObject());
NS_ENSURE_TRUE(locationObj, nullptr);
if (!JS_DefineProperty(aCx, obj, "__LOCATION__", locationObj, 0))

View File

@ -307,15 +307,12 @@ nsXPCComponents_Interfaces::Resolve(nsIXPConnectWrappedNative* wrapper,
if (nsid) {
nsXPConnect* xpc = nsXPConnect::XPConnect();
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
RootedObject idobj(cx);
if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
static_cast<nsIJSIID*>(nsid),
NS_GET_IID(nsIJSIID),
getter_AddRefs(holder)))) {
RootedObject idobj(cx);
if (holder &&
// Assign, not compare
(idobj = holder->GetJSObject())) {
idobj.address()))) {
if (idobj) {
*resolvedp = true;
*_retval = JS_DefinePropertyById(cx, obj, id, idobj,
JSPROP_ENUMERATE |
@ -545,15 +542,12 @@ nsXPCComponents_InterfacesByID::Resolve(nsIXPConnectWrappedNative* wrapper,
return NS_ERROR_OUT_OF_MEMORY;
nsXPConnect* xpc = nsXPConnect::XPConnect();
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
RootedObject idobj(cx);
if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
static_cast<nsIJSIID*>(nsid),
NS_GET_IID(nsIJSIID),
getter_AddRefs(holder)))) {
RootedObject idobj(cx);
if (holder &&
// Assign, not compare
(idobj = holder->GetJSObject())) {
NS_GET_IID(nsIJSIID),
idobj.address()))) {
if (idobj) {
*resolvedp = true;
*_retval =
JS_DefinePropertyById(cx, obj, id, idobj,
@ -765,15 +759,12 @@ nsXPCComponents_Classes::Resolve(nsIXPConnectWrappedNative* wrapper,
nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr());
if (nsid) {
nsXPConnect* xpc = nsXPConnect::XPConnect();
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
RootedObject idobj(cx);
if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
static_cast<nsIJSCID*>(nsid),
NS_GET_IID(nsIJSCID),
getter_AddRefs(holder)))) {
RootedObject idobj(cx);
if (holder &&
// Assign, not compare
(idobj = holder->GetJSObject())) {
idobj.address()))) {
if (idobj) {
*resolvedp = true;
*_retval = JS_DefinePropertyById(cx, obj, id, idobj,
JSPROP_ENUMERATE |
@ -1004,15 +995,12 @@ nsXPCComponents_ClassesByID::Resolve(nsIXPConnectWrappedNative* wrapper,
nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr());
if (nsid) {
nsXPConnect* xpc = nsXPConnect::XPConnect();
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
RootedObject idobj(cx);
if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
static_cast<nsIJSCID*>(nsid),
NS_GET_IID(nsIJSCID),
getter_AddRefs(holder)))) {
RootedObject idobj(cx);
if (holder &&
// Assign, not compare
(idobj = holder->GetJSObject())) {
idobj.address()))) {
if (idobj) {
*resolvedp = true;
*_retval = JS_DefinePropertyById(cx, obj, id, idobj,
JSPROP_ENUMERATE |
@ -1763,13 +1751,8 @@ nsXPCComponents_Exception::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
parser.eStack,
parser.eData);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
RootedObject newObj(cx);
if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIXPCException),
getter_AddRefs(holder))) || !holder ||
// Assign, not compare
!(newObj = holder->GetJSObject())) {
if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIXPCException), newObj.address())) || !newObj) {
return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
}
@ -2011,19 +1994,11 @@ nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,JSContext*
// security check not required because we are going to call through the
// code which is reflected into JS which will do that for us later.
nsCOMPtr<nsIXPConnectJSObjectHolder> cidHolder;
nsCOMPtr<nsIXPConnectJSObjectHolder> iidHolder;
RootedObject cidObj(cx);
RootedObject iidObj(cx);
if (NS_FAILED(xpc->WrapNative(cx, obj, mClassID, NS_GET_IID(nsIJSCID),
getter_AddRefs(cidHolder))) || !cidHolder ||
// Assign, not compare
!(cidObj = cidHolder->GetJSObject()) ||
NS_FAILED(xpc->WrapNative(cx, obj, mInterfaceID, NS_GET_IID(nsIJSIID),
getter_AddRefs(iidHolder))) || !iidHolder ||
// Assign, not compare
!(iidObj = iidHolder->GetJSObject())) {
if (NS_FAILED(xpc->WrapNative(cx, obj, mClassID, NS_GET_IID(nsIJSCID), cidObj.address())) || !cidObj ||
NS_FAILED(xpc->WrapNative(cx, obj, mInterfaceID, NS_GET_IID(nsIJSIID), iidObj.address())) || !iidObj) {
return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
}
@ -2260,7 +2235,6 @@ nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
// XXXjband support passing "Components.interfaces.foo"?
nsCOMPtr<nsIXPCComponents_Interfaces> ifaces;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
RootedObject ifacesObj(cx);
// we do the lookup by asking the Components.interfaces object
@ -2270,9 +2244,7 @@ nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
if (NS_FAILED(comp->GetInterfaces(getter_AddRefs(ifaces))) ||
NS_FAILED(xpc->WrapNative(cx, obj, ifaces,
NS_GET_IID(nsIXPCComponents_Interfaces),
getter_AddRefs(holder))) || !holder ||
// Assign, not compare
!(ifacesObj = holder->GetJSObject())) {
ifacesObj.address())) || !ifacesObj) {
return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
}
@ -2312,15 +2284,12 @@ nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
// nsIJSCID objects work for us.
nsCOMPtr<nsIXPCComponents_Classes> classes;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
RootedObject classesObj(cx);
if (NS_FAILED(comp->GetClasses(getter_AddRefs(classes))) ||
NS_FAILED(xpc->WrapNative(cx, obj, classes,
NS_GET_IID(nsIXPCComponents_Classes),
getter_AddRefs(holder))) || !holder ||
// Assign, not compare
!(classesObj = holder->GetJSObject())) {
classesObj.address())) || !classesObj) {
return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
}
@ -2342,13 +2311,9 @@ nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
}
nsCOMPtr<nsIXPCConstructor> ctor = new nsXPCConstructor(cClassID, cInterfaceID, cInitializer);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder2;
RootedObject newObj(cx);
if (NS_FAILED(xpc->WrapNative(cx, obj, ctor, NS_GET_IID(nsIXPCConstructor),
getter_AddRefs(holder2))) || !holder2 ||
// Assign, not compare
!(newObj = holder2->GetJSObject())) {
if (NS_FAILED(xpc->WrapNative(cx, obj, ctor, NS_GET_IID(nsIXPCConstructor), newObj.address())) || !newObj) {
return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
}

View File

@ -766,14 +766,8 @@ xpc_NewIDObject(JSContext* cx, HandleObject jsobj, const nsID& aID)
if (iid) {
nsXPConnect* xpc = nsXPConnect::XPConnect();
if (xpc) {
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
nsresult rv = xpc->WrapNative(cx, jsobj,
static_cast<nsISupports*>(iid),
NS_GET_IID(nsIJSID),
getter_AddRefs(holder));
if (NS_SUCCEEDED(rv) && holder) {
obj = holder->GetJSObject();
}
xpc->WrapNative(cx, jsobj, static_cast<nsISupports*>(iid),
NS_GET_IID(nsIJSID), obj.address());
}
}
return obj;

View File

@ -174,20 +174,16 @@ GetLocationProperty(JSContext* cx, unsigned argc, Value* vp)
}
if (location) {
nsCOMPtr<nsIXPConnectJSObjectHolder> locationHolder;
bool symlink;
// don't normalize symlinks, because that's kind of confusing
if (NS_SUCCEEDED(location->IsSymlink(&symlink)) &&
!symlink)
location->Normalize();
RootedObject locationObj(cx);
rv = xpc->WrapNative(cx, &args.thisv().toObject(), location,
NS_GET_IID(nsIFile),
getter_AddRefs(locationHolder));
if (NS_SUCCEEDED(rv) &&
locationHolder->GetJSObject()) {
args.rval().setObject(*locationHolder->GetJSObject());
NS_GET_IID(nsIFile), locationObj.address());
if (NS_SUCCEEDED(rv) && locationObj) {
args.rval().setObject(*locationObj);
}
}
}

View File

@ -492,13 +492,39 @@ NativeInterface2JSObject(HandleObject aScope,
return NS_OK;
}
/* nsIXPConnectJSObjectHolder wrapNative (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDRef aIID); */
/* JSObjectPtr wrapNative (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDRef aIID); */
NS_IMETHODIMP
nsXPConnect::WrapNative(JSContext * aJSContext,
JSObject * aScopeArg,
nsISupports* aCOMObj,
const nsIID & aIID,
nsIXPConnectJSObjectHolder** aHolder)
JSObject** aRetVal)
{
MOZ_ASSERT(aJSContext, "bad param");
MOZ_ASSERT(aScopeArg, "bad param");
MOZ_ASSERT(aCOMObj, "bad param");
RootedObject aScope(aJSContext, aScopeArg);
RootedValue v(aJSContext);
nsresult rv = NativeInterface2JSObject(aScope, aCOMObj, nullptr, &aIID,
true, &v, nullptr);
if (NS_FAILED(rv))
return rv;
if (!v.isObjectOrNull())
return NS_ERROR_FAILURE;
*aRetVal = v.toObjectOrNull();
return NS_OK;
}
/* nsIXPConnectJSObjectHolder wrapNativeHolder(in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDRef aIID); */
NS_IMETHODIMP
nsXPConnect::WrapNativeHolder(JSContext * aJSContext,
JSObject * aScopeArg,
nsISupports* aCOMObj,
const nsIID & aIID,
nsIXPConnectJSObjectHolder **aHolder)
{
MOZ_ASSERT(aHolder, "bad param");
MOZ_ASSERT(aJSContext, "bad param");
@ -511,7 +537,7 @@ nsXPConnect::WrapNative(JSContext * aJSContext,
true, &v, aHolder);
}
/* void wrapNativeToJSVal (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDPtr aIID, out jsval aVal, out nsIXPConnectJSObjectHolder aHolder); */
/* void wrapNativeToJSVal (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDPtr aIID, out jsval aVal); */
NS_IMETHODIMP
nsXPConnect::WrapNativeToJSVal(JSContext* aJSContext,
JSObject* aScopeArg,

View File

@ -48,7 +48,7 @@ AsyncStatementJSHelper::getParams(AsyncStatement *aStatement,
JS::RootedObject scope(aCtx, aScopeObj);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
nsCOMPtr<nsIXPConnect> xpc(Service::getXPConnect());
rv = xpc->WrapNative(
rv = xpc->WrapNativeHolder(
aCtx,
::JS_GetGlobalForObject(aCtx, scope),
params,

View File

@ -101,7 +101,7 @@ StatementJSHelper::getRow(Statement *aStatement,
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
nsCOMPtr<nsIXPConnect> xpc(Service::getXPConnect());
rv = xpc->WrapNative(
rv = xpc->WrapNativeHolder(
aCtx,
::JS_GetGlobalForObject(aCtx, scope),
row,
@ -146,7 +146,7 @@ StatementJSHelper::getParams(Statement *aStatement,
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
nsCOMPtr<nsIXPConnect> xpc(Service::getXPConnect());
rv = xpc->WrapNative(
rv = xpc->WrapNativeHolder(
aCtx,
::JS_GetGlobalForObject(aCtx, scope),
params,

View File

@ -110,13 +110,11 @@ PlaceInfo::GetVisits(JSContext* aContext,
nsCOMPtr<nsIXPConnect> xpc = mozilla::services::GetXPConnect();
for (VisitsArray::size_type idx = 0; idx < mVisits.Length(); idx++) {
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
JS::RootedObject jsobj(aContext);
nsresult rv = xpc->WrapNative(aContext, global, mVisits[idx],
NS_GET_IID(mozIVisitInfo),
getter_AddRefs(wrapper));
jsobj.address());
NS_ENSURE_SUCCESS(rv, rv);
JS::Rooted<JSObject*> jsobj(aContext, wrapper->GetJSObject());
NS_ENSURE_STATE(jsobj);
bool rc = JS_DefineElement(aContext, visits, idx, jsobj, JSPROP_ENUMERATE);

View File

@ -418,11 +418,12 @@ void nsMenuX::MenuConstruct()
dom::AutoJSAPI jsapi;
if (ownerDoc && jsapi.Init(ownerDoc->GetInnerWindow())) {
JSContext* cx = jsapi.cx();
JS::RootedObject ignoredObj(cx);
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
xpconnect->WrapNative(cx, JS::CurrentGlobalOrNull(cx), menuPopup,
NS_GET_IID(nsISupports), getter_AddRefs(wrapper));
NS_GET_IID(nsISupports), ignoredObj.address());
mXBLAttached = true;
}
}
}
}

View File

@ -239,17 +239,16 @@ nsHTTPIndex::OnStartRequest(nsIRequest *request, nsISupports* aContext)
nsCOMPtr<nsIXPConnect> xpc(do_GetService(kXPConnectCID, &rv));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
JS::Rooted<JSObject*> jsobj(cx);
rv = xpc->WrapNative(cx,
global,
static_cast<nsIHTTPIndex*>(this),
NS_GET_IID(nsIHTTPIndex),
getter_AddRefs(wrapper));
jsobj.address());
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap http-index");
if (NS_FAILED(rv)) return rv;
JS::Rooted<JSObject*> jsobj(cx, wrapper->GetJSObject());
NS_ASSERTION(jsobj,
"unable to get jsobj from xpconnect wrapper");
if (!jsobj) return NS_ERROR_UNEXPECTED;