зеркало из https://github.com/mozilla/pjs.git
Bug 378236 - Crash when embedding trunk XULRunner in Java. Properly pass XPCOM object ptrs. Also do some restructuring. XULRunner only.
This commit is contained in:
Родитель
7728e98df0
Коммит
c794639cc7
|
@ -145,8 +145,8 @@ InitXPCOM_Impl(JNIEnv* env, jobject aMozBinDirectory,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// create Java proxy for service manager returned by NS_InitXPCOM2
|
||||
return GetNewOrUsedJavaObject(env, servMan, NS_GET_IID(nsIServiceManager),
|
||||
nsnull, aResult);
|
||||
return NativeInterfaceToJavaObject(env, servMan, NS_GET_IID(nsIServiceManager),
|
||||
nsnull, aResult);
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT jobject JNICALL
|
||||
|
@ -171,9 +171,16 @@ XPCOM_NATIVE(shutdownXPCOM) (JNIEnv *env, jobject, jobject aServMgr)
|
|||
nsIServiceManager* servMgr = nsnull;
|
||||
if (aServMgr) {
|
||||
// Get native XPCOM instance
|
||||
rv = GetNewOrUsedXPCOMObject(env, aServMgr, NS_GET_IID(nsIServiceManager),
|
||||
(nsISupports**) &servMgr);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to get XPCOM obj for ServiceMgr.");
|
||||
nsISupports* instancePtr = nsnull;
|
||||
rv = JavaObjectToNativeInterface(env, aServMgr,
|
||||
NS_GET_IID(nsIServiceManager), (void**) &instancePtr);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && instancePtr != nsnull,
|
||||
"Failed to get XPCOM obj for ServiceMgr.");
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = instancePtr->QueryInterface(NS_GET_IID(nsIServiceManager),
|
||||
(void**) &servMgr);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "QI for nsIServiceManager failed");
|
||||
}
|
||||
|
||||
// Even if we failed to get the matching xpcom object, we don't abort this
|
||||
// function. Just call NS_ShutdownXPCOM with a null service manager.
|
||||
|
@ -209,8 +216,8 @@ XPCOM_NATIVE(newLocalFile) (JNIEnv *env, jobject, jstring aPath,
|
|||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
jobject javaProxy;
|
||||
rv = GetNewOrUsedJavaObject(env, file, NS_GET_IID(nsILocalFile),
|
||||
nsnull, &javaProxy);
|
||||
rv = NativeInterfaceToJavaObject(env, file, NS_GET_IID(nsILocalFile),
|
||||
nsnull, &javaProxy);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return javaProxy;
|
||||
}
|
||||
|
@ -228,8 +235,8 @@ XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jobject)
|
|||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
jobject javaProxy;
|
||||
rv = GetNewOrUsedJavaObject(env, cm, NS_GET_IID(nsIComponentManager),
|
||||
nsnull, &javaProxy);
|
||||
rv = NativeInterfaceToJavaObject(env, cm, NS_GET_IID(nsIComponentManager),
|
||||
nsnull, &javaProxy);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return javaProxy;
|
||||
}
|
||||
|
@ -247,8 +254,8 @@ XPCOM_NATIVE(getComponentRegistrar) (JNIEnv *env, jobject)
|
|||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
jobject javaProxy;
|
||||
rv = GetNewOrUsedJavaObject(env, cr, NS_GET_IID(nsIComponentRegistrar),
|
||||
nsnull, &javaProxy);
|
||||
rv = NativeInterfaceToJavaObject(env, cr, NS_GET_IID(nsIComponentRegistrar),
|
||||
nsnull, &javaProxy);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return javaProxy;
|
||||
}
|
||||
|
@ -266,8 +273,8 @@ XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jobject)
|
|||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
jobject javaProxy;
|
||||
rv = GetNewOrUsedJavaObject(env, sm, NS_GET_IID(nsIServiceManager),
|
||||
nsnull, &javaProxy);
|
||||
rv = NativeInterfaceToJavaObject(env, sm, NS_GET_IID(nsIServiceManager),
|
||||
nsnull, &javaProxy);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return javaProxy;
|
||||
}
|
||||
|
@ -359,7 +366,7 @@ JXUTILS_NATIVE(wrapJavaObject) (JNIEnv* env, jobject, jobject aJavaObject,
|
|||
jstring aIID)
|
||||
{
|
||||
nsresult rv;
|
||||
nsISupports* xpcomObject = nsnull;
|
||||
void* xpcomObject = nsnull;
|
||||
|
||||
if (!aJavaObject || !aIID) {
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
|
@ -370,7 +377,10 @@ JXUTILS_NATIVE(wrapJavaObject) (JNIEnv* env, jobject, jobject aJavaObject,
|
|||
} else {
|
||||
nsID iid;
|
||||
if (iid.Parse(str)) {
|
||||
rv = GetNewOrUsedXPCOMObject(env, aJavaObject, iid, &xpcomObject);
|
||||
rv = JavaObjectToNativeInterface(env, aJavaObject, iid, &xpcomObject);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = ((nsISupports*) xpcomObject)->QueryInterface(iid, &xpcomObject);
|
||||
}
|
||||
} else {
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
@ -403,7 +413,8 @@ JXUTILS_NATIVE(wrapXPCOMObject) (JNIEnv* env, jobject, jlong aXPCOMObject,
|
|||
nsID iid;
|
||||
if (iid.Parse(str)) {
|
||||
// XXX Should we be passing something other than NULL for aObjectLoader?
|
||||
rv = GetNewOrUsedJavaObject(env, xpcomObject, iid, nsnull, &javaObject);
|
||||
rv = NativeInterfaceToJavaObject(env, xpcomObject, iid, nsnull,
|
||||
&javaObject);
|
||||
} else {
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
|
|
@ -728,7 +728,7 @@ SetupParams(JNIEnv *env, const jobject aParam, PRUint8 aType, PRBool aIsOut,
|
|||
aIndex);
|
||||
}
|
||||
|
||||
nsISupports* xpcom_obj;
|
||||
void* xpcom_obj;
|
||||
if (java_obj) {
|
||||
// If the requested interface is nsIWeakReference, then we look for or
|
||||
// create a stub for the nsISupports interface. Then we create a weak
|
||||
|
@ -743,21 +743,25 @@ SetupParams(JNIEnv *env, const jobject aParam, PRUint8 aType, PRBool aIsOut,
|
|||
iid = aIID;
|
||||
}
|
||||
|
||||
rv = GetNewOrUsedXPCOMObject(env, java_obj, iid, &xpcom_obj);
|
||||
rv = JavaObjectToNativeInterface(env, java_obj, iid, &xpcom_obj);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
rv = ((nsISupports*) xpcom_obj)->QueryInterface(iid, &xpcom_obj);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
// If the function expects a weak reference, then we need to
|
||||
// create it here.
|
||||
if (isWeakRef) {
|
||||
nsISupports* isupports = (nsISupports*) xpcom_obj;
|
||||
nsCOMPtr<nsISupportsWeakReference> supportsweak =
|
||||
do_QueryInterface(xpcom_obj);
|
||||
do_QueryInterface(isupports);
|
||||
if (supportsweak) {
|
||||
nsWeakPtr weakref;
|
||||
supportsweak->GetWeakReference(getter_AddRefs(weakref));
|
||||
NS_RELEASE(xpcom_obj);
|
||||
NS_RELEASE(isupports);
|
||||
xpcom_obj = weakref;
|
||||
NS_ADDREF(xpcom_obj);
|
||||
NS_ADDREF((nsISupports*) xpcom_obj);
|
||||
} else {
|
||||
xpcom_obj = nsnull;
|
||||
}
|
||||
|
@ -774,7 +778,7 @@ SetupParams(JNIEnv *env, const jobject aParam, PRUint8 aType, PRBool aIsOut,
|
|||
aVariant.SetPtrIsData();
|
||||
}
|
||||
} else { // 'array'
|
||||
NS_STATIC_CAST(nsISupports**, aVariant.val.p)[aIndex] = xpcom_obj;
|
||||
NS_STATIC_CAST(void**, aVariant.val.p)[aIndex] = xpcom_obj;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1111,7 +1115,8 @@ FinalizeParams(JNIEnv *env, const nsXPTParamInfo &aParamInfo, PRUint8 aType,
|
|||
jobject java_obj = nsnull;
|
||||
if (xpcom_obj) {
|
||||
// Get matching Java object for given xpcom object
|
||||
rv = GetNewOrUsedJavaObject(env, xpcom_obj, aIID, nsnull, &java_obj);
|
||||
rv = NativeInterfaceToJavaObject(env, xpcom_obj, aIID, nsnull,
|
||||
&java_obj);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
|
@ -1568,13 +1573,28 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
|||
}
|
||||
|
||||
nsresult
|
||||
CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
|
||||
jobject aObjectLoader, jobject* aResult)
|
||||
GetNewOrUsedJavaWrapper(JNIEnv* env, nsISupports* aXPCOMObject,
|
||||
const nsIID& aIID, jobject aObjectLoader,
|
||||
jobject* aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Get the root nsISupports of the xpcom object
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISupports> rootObject = do_QueryInterface(aXPCOMObject, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get associated Java object from hash table
|
||||
rv = gNativeToJavaProxyMap->Find(env, rootObject, aIID, aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (*aResult)
|
||||
return NS_OK;
|
||||
|
||||
// No Java object is associated with the given XPCOM object, so we
|
||||
// create a Java proxy.
|
||||
|
||||
nsCOMPtr<nsIInterfaceInfoManager>
|
||||
iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
|
||||
NS_ASSERTION(iim, "Failed to get InterfaceInfoManager");
|
||||
|
@ -1583,12 +1603,12 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
|
|||
|
||||
// Get interface info for class
|
||||
nsCOMPtr<nsIInterfaceInfo> info;
|
||||
nsresult rv = iim->GetInfoForIID(&aIID, getter_AddRefs(info));
|
||||
rv = iim->GetInfoForIID(&aIID, getter_AddRefs(info));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Wrap XPCOM object (addrefs aXPCOMObject)
|
||||
JavaXPCOMInstance* inst = new JavaXPCOMInstance(aXPCOMObject, info);
|
||||
// Wrap XPCOM object (addrefs rootObject)
|
||||
JavaXPCOMInstance* inst = new JavaXPCOMInstance(rootObject, info);
|
||||
if (!inst)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -1618,12 +1638,12 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
|
|||
LOG(("+ CreateJavaProxy (Java=%08x | XPCOM=%08x | IID=%s)\n",
|
||||
(PRUint32) env->CallStaticIntMethod(systemClass, hashCodeMID,
|
||||
java_obj),
|
||||
(PRUint32) aXPCOMObject, iid_str));
|
||||
(PRUint32) rootObject, iid_str));
|
||||
PR_Free(iid_str);
|
||||
#endif
|
||||
|
||||
// Associate XPCOM object with Java proxy
|
||||
rv = gNativeToJavaProxyMap->Add(env, aXPCOMObject, aIID, java_obj);
|
||||
rv = gNativeToJavaProxyMap->Add(env, rootObject, aIID, java_obj);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aResult = java_obj;
|
||||
return NS_OK;
|
||||
|
|
|
@ -43,21 +43,21 @@
|
|||
|
||||
|
||||
/**
|
||||
* Creates a Java proxy around an XPCOM C++ object.
|
||||
* Finds the associated Java wraper for the given XPCOM object and IID. If no
|
||||
* such Java wrapper exists, then a new one is created.
|
||||
*
|
||||
* @param env pointer to Java context
|
||||
* @param aXPCOMObject XPCOM object to create proxy for
|
||||
* @param aIID IID for XPCOM object
|
||||
* @param aObjectLoader Java object whose class loader we use for finding
|
||||
* @param env Java environment pointer
|
||||
* @param aXPCOMObject XPCOM object for which to find/create Java wrapper
|
||||
* @param aIID desired interface IID for Java wrapper
|
||||
* @param aObjectLoader Java wrapper whose class loader we use for finding
|
||||
* classes; can be null
|
||||
* @param aResult on exit, holds reference to Java proxy
|
||||
* @param aResult on success, holds reference to Java wrapper
|
||||
*
|
||||
* @return NS_OK if Java proxy was successfully created;
|
||||
* any other value denotes an error condition.
|
||||
* @return NS_OK if succeeded; all other return values are error codes.
|
||||
*/
|
||||
nsresult CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject,
|
||||
const nsIID& aIID, jobject aObjectLoader,
|
||||
jobject* aResult);
|
||||
nsresult GetNewOrUsedJavaWrapper(JNIEnv* env, nsISupports* aXPCOMObject,
|
||||
const nsIID& aIID, jobject aObjectLoader,
|
||||
jobject* aResult);
|
||||
|
||||
/**
|
||||
* Returns the XPCOM object for which the given Java proxy was created.
|
||||
|
|
|
@ -797,43 +797,32 @@ JavaXPCOMInstance::~JavaXPCOMInstance()
|
|||
*******************************/
|
||||
|
||||
nsresult
|
||||
GetNewOrUsedJavaObject(JNIEnv* env, nsISupports* aXPCOMObject,
|
||||
const nsIID& aIID, jobject aObjectLoader,
|
||||
jobject* aResult)
|
||||
NativeInterfaceToJavaObject(JNIEnv* env, nsISupports* aXPCOMObject,
|
||||
const nsIID& aIID, jobject aObjectLoader,
|
||||
jobject* aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult rv;
|
||||
// If the object is an nsJavaXPTCStub, then get the Java object directly
|
||||
nsJavaXPTCStub* stub = nsnull;
|
||||
aXPCOMObject->QueryInterface(NS_GET_IID(nsJavaXPTCStub), (void**) &stub);
|
||||
if (stub) {
|
||||
// Get Java object directly from nsJavaXPTCStub
|
||||
*aResult = stub->GetJavaObject();
|
||||
NS_ASSERTION(*aResult != nsnull, "nsJavaXPTCStub w/o matching Java object");
|
||||
NS_RELEASE(stub);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the root nsISupports of the xpcom object
|
||||
nsCOMPtr<nsISupports> rootObject = do_QueryInterface(aXPCOMObject, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get associated Java object from hash table
|
||||
rv = gNativeToJavaProxyMap->Find(env, rootObject, aIID, aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (*aResult)
|
||||
return NS_OK;
|
||||
|
||||
// No Java object is associated with the given XPCOM object, so we
|
||||
// create a Java proxy.
|
||||
return CreateJavaProxy(env, rootObject, aIID, aObjectLoader, aResult);
|
||||
// ... else, get a Java wrapper for the native object
|
||||
return GetNewOrUsedJavaWrapper(env, aXPCOMObject, aIID, aObjectLoader,
|
||||
aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetNewOrUsedXPCOMObject(JNIEnv* env, jobject aJavaObject, const nsIID& aIID,
|
||||
nsISupports** aResult)
|
||||
JavaObjectToNativeInterface(JNIEnv* env, jobject aJavaObject, const nsIID& aIID,
|
||||
void** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (!aResult)
|
||||
|
@ -842,10 +831,8 @@ GetNewOrUsedXPCOMObject(JNIEnv* env, jobject aJavaObject, const nsIID& aIID,
|
|||
nsresult rv;
|
||||
*aResult = nsnull;
|
||||
|
||||
// Check if the given Java object is actually one of our Java proxies. If so,
|
||||
// then we query the associated XPCOM object directly from the proxy.
|
||||
// If Java object is not a proxy, then we try to find associated XPCOM object
|
||||
// in the mapping table.
|
||||
// If the given Java object is one of our Java proxies, then query the
|
||||
// associated XPCOM object directly from the proxy.
|
||||
jboolean isProxy = env->CallStaticBooleanMethod(xpcomJavaProxyClass,
|
||||
isXPCOMJavaProxyMID,
|
||||
aJavaObject);
|
||||
|
@ -859,55 +846,14 @@ GetNewOrUsedXPCOMObject(JNIEnv* env, jobject aJavaObject, const nsIID& aIID,
|
|||
|
||||
nsISupports* rootObject =
|
||||
NS_STATIC_CAST(JavaXPCOMInstance*, inst)->GetInstance();
|
||||
rv = rootObject->QueryInterface(aIID, (void**) aResult);
|
||||
rv = rootObject->QueryInterface(aIID, aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsJavaXPTCStub* stub;
|
||||
jint hash = env->CallStaticIntMethod(systemClass, hashCodeMID, aJavaObject);
|
||||
rv = gJavaToXPTCStubMap->Find(hash, aIID, &stub);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (stub) {
|
||||
// stub is already AddRef'd and QI'd
|
||||
*aResult = stub->GetStub();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If there is no corresponding XPCOM object, then that means that the
|
||||
// parameter is a non-generated class (that is, it is not one of our
|
||||
// Java stubs that represent an exising XPCOM object). So we need to
|
||||
// create an XPCOM stub, that can route any method calls to the class.
|
||||
|
||||
// Get interface info for class
|
||||
nsCOMPtr<nsIInterfaceInfoManager>
|
||||
iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIInterfaceInfo> iinfo;
|
||||
rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create XPCOM stub
|
||||
stub = new nsJavaXPTCStub(aJavaObject, iinfo, &rv);
|
||||
if (!stub)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (NS_FAILED(rv)) {
|
||||
delete stub;
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = gJavaToXPTCStubMap->Add(hash, stub);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete stub;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ADDREF(stub);
|
||||
*aResult = stub->GetStub();
|
||||
|
||||
return NS_OK;
|
||||
// ... else, we get an nsJavaXPTCStub
|
||||
return nsJavaXPTCStub::GetNewOrUsed(env, aJavaObject, aIID, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -264,8 +264,7 @@ protected:
|
|||
*******************************/
|
||||
|
||||
/**
|
||||
* Finds the associated Java object for the given XPCOM object and IID. If no
|
||||
* such Java object exists, then it creates one.
|
||||
* Convert a native nsISupports to a Java object.
|
||||
*
|
||||
* @param env Java environment pointer
|
||||
* @param aXPCOMObject XPCOM object for which to find/create Java object
|
||||
|
@ -276,13 +275,12 @@ protected:
|
|||
*
|
||||
* @return NS_OK if succeeded; all other return values are error codes.
|
||||
*/
|
||||
nsresult GetNewOrUsedJavaObject(JNIEnv* env, nsISupports* aXPCOMObject,
|
||||
const nsIID& aIID, jobject aObjectLoader,
|
||||
jobject* aResult);
|
||||
nsresult NativeInterfaceToJavaObject(JNIEnv* env, nsISupports* aXPCOMObject,
|
||||
const nsIID& aIID, jobject aObjectLoader,
|
||||
jobject* aResult);
|
||||
|
||||
/**
|
||||
* Finds the associated XPCOM object for the given Java object and IID. If no
|
||||
* such XPCOM object exists, then it creates one.
|
||||
* Convert a Java object to a native nsISupports object.
|
||||
*
|
||||
* @param env Java environment pointer
|
||||
* @param aJavaObject Java object for which to find/create XPCOM object
|
||||
|
@ -291,8 +289,8 @@ nsresult GetNewOrUsedJavaObject(JNIEnv* env, nsISupports* aXPCOMObject,
|
|||
*
|
||||
* @return NS_OK if succeeded; all other return values are error codes.
|
||||
*/
|
||||
nsresult GetNewOrUsedXPCOMObject(JNIEnv* env, jobject aJavaObject,
|
||||
const nsIID& aIID, nsISupports** aResult);
|
||||
nsresult JavaObjectToNativeInterface(JNIEnv* env, jobject aJavaObject,
|
||||
const nsIID& aIID, void** aResult);
|
||||
|
||||
nsresult GetIIDForMethodParam(nsIInterfaceInfo *iinfo,
|
||||
const XPTMethodDescriptor *methodInfo,
|
||||
|
|
|
@ -928,7 +928,8 @@ nsJavaXPTCStub::SetupJavaParams(const nsXPTParamInfo &aParamInfo,
|
|||
if (xpcom_obj) {
|
||||
// Get matching Java object for given xpcom object
|
||||
jobject objLoader = env->CallObjectMethod(mJavaWeakRef, getReferentMID);
|
||||
rv = GetNewOrUsedJavaObject(env, xpcom_obj, iid, objLoader, &java_stub);
|
||||
rv = NativeInterfaceToJavaObject(env, xpcom_obj, iid, objLoader,
|
||||
&java_stub);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
|
@ -1477,7 +1478,7 @@ nsJavaXPTCStub::FinalizeJavaParams(const nsXPTParamInfo &aParamInfo,
|
|||
java_obj = env->GetObjectArrayElement((jobjectArray) aJValue.l, 0);
|
||||
}
|
||||
|
||||
nsISupports* xpcom_obj = nsnull;
|
||||
void* xpcom_obj = nsnull;
|
||||
if (java_obj) {
|
||||
// Get IID for this param
|
||||
nsID iid;
|
||||
|
@ -1498,21 +1499,25 @@ nsJavaXPTCStub::FinalizeJavaParams(const nsXPTParamInfo &aParamInfo,
|
|||
isWeakRef = PR_FALSE;
|
||||
}
|
||||
|
||||
rv = GetNewOrUsedXPCOMObject(env, java_obj, iid, &xpcom_obj);
|
||||
rv = JavaObjectToNativeInterface(env, java_obj, iid, &xpcom_obj);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
rv = ((nsISupports*) xpcom_obj)->QueryInterface(iid, &xpcom_obj);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
// If the function expects a weak reference, then we need to
|
||||
// create it here.
|
||||
if (isWeakRef) {
|
||||
nsISupports* isupports = (nsISupports*) xpcom_obj;
|
||||
nsCOMPtr<nsISupportsWeakReference> supportsweak =
|
||||
do_QueryInterface(xpcom_obj);
|
||||
do_QueryInterface(isupports);
|
||||
if (supportsweak) {
|
||||
nsWeakPtr weakref;
|
||||
supportsweak->GetWeakReference(getter_AddRefs(weakref));
|
||||
NS_RELEASE(xpcom_obj);
|
||||
NS_RELEASE(isupports);
|
||||
xpcom_obj = weakref;
|
||||
NS_ADDREF(xpcom_obj);
|
||||
NS_ADDREF((nsISupports*) xpcom_obj);
|
||||
} else {
|
||||
xpcom_obj = nsnull;
|
||||
}
|
||||
|
@ -1524,13 +1529,13 @@ nsJavaXPTCStub::FinalizeJavaParams(const nsXPTParamInfo &aParamInfo,
|
|||
nsISupports** variant = NS_STATIC_CAST(nsISupports**, aVariant.val.p);
|
||||
if (aParamInfo.IsIn() && *variant) {
|
||||
nsCOMPtr<nsISupports> in = do_QueryInterface(*variant);
|
||||
nsCOMPtr<nsISupports> out = do_QueryInterface(xpcom_obj);
|
||||
nsCOMPtr<nsISupports> out = do_QueryInterface((nsISupports*) xpcom_obj);
|
||||
if (in != out) {
|
||||
NS_RELEASE(*variant);
|
||||
}
|
||||
}
|
||||
|
||||
*variant = xpcom_obj;
|
||||
*(NS_STATIC_CAST(void**, aVariant.val.p)) = xpcom_obj;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1656,3 +1661,53 @@ nsJavaXPTCStub::GetJavaObject()
|
|||
|
||||
return javaObject;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ nsresult
|
||||
nsJavaXPTCStub::GetNewOrUsed(JNIEnv* env, jobject aJavaObject,
|
||||
const nsIID& aIID, void** aResult)
|
||||
{
|
||||
nsJavaXPTCStub* stub;
|
||||
jint hash = env->CallStaticIntMethod(systemClass, hashCodeMID, aJavaObject);
|
||||
nsresult rv = gJavaToXPTCStubMap->Find(hash, aIID, &stub);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (stub) {
|
||||
// stub is already AddRef'd and QI'd
|
||||
*aResult = stub;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If there is no corresponding XPCOM object, then that means that the
|
||||
// parameter is a non-generated class (that is, it is not one of our
|
||||
// Java stubs that represent an exising XPCOM object). So we need to
|
||||
// create an XPCOM stub, that can route any method calls to the class.
|
||||
|
||||
// Get interface info for class
|
||||
nsCOMPtr<nsIInterfaceInfoManager>
|
||||
iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIInterfaceInfo> iinfo;
|
||||
rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create XPCOM stub
|
||||
stub = new nsJavaXPTCStub(aJavaObject, iinfo, &rv);
|
||||
if (!stub)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (NS_FAILED(rv)) {
|
||||
delete stub;
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = gJavaToXPTCStubMap->Add(hash, stub);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete stub;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ADDREF(stub);
|
||||
*aResult = stub;
|
||||
|
||||
return NS_OK;
|
||||
}
|
|
@ -79,6 +79,21 @@ public:
|
|||
// collected if necessary. See DestroyXPTCMappingEnum().
|
||||
void DeleteStrongRef();
|
||||
|
||||
/**
|
||||
* Finds the associated nsJavaXPTCStub for the given Java object and IID.
|
||||
* If no such stub exists, then a new one is created.
|
||||
*
|
||||
* @param env Java environment pointer
|
||||
* @param aJavaObject Java object for which to find/create nsJavaXPTCStub
|
||||
* @param aIID desired interface IID for nsJavaXPTCStub
|
||||
* @param aResult on success, holds AddRef'd reference to nsJavaXPTCStub
|
||||
*
|
||||
* @return NS_OK if succeeded; all other return values are error codes.
|
||||
*/
|
||||
static nsresult GetNewOrUsed(JNIEnv* env, jobject aJavaObject,
|
||||
const nsIID& aIID, void** aResult);
|
||||
|
||||
|
||||
private:
|
||||
NS_IMETHOD_(nsrefcnt) AddRefInternal();
|
||||
NS_IMETHOD_(nsrefcnt) ReleaseInternal();
|
||||
|
|
Загрузка…
Ссылка в новой задаче