From 8b1f8fe34cf28dd752bb36906af7ab0cb9d311ff Mon Sep 17 00:00:00 2001 From: "pedemont%us.ibm.com" Date: Wed, 2 May 2007 15:43:41 +0000 Subject: [PATCH] Bug 378236 - Crash when embedding trunk XULRunner in Java. Properly pass XPCOM object ptrs. Also do some restructuring. XULRunner only. git-svn-id: svn://10.0.0.236/trunk@225455 18797224-902f-48f8-a5cc-f745e15eee43 --- .../java/xpcom/src/nsJavaInterfaces.cpp | 43 ++++++---- .../java/xpcom/src/nsJavaWrapper.cpp | 48 +++++++---- .../extensions/java/xpcom/src/nsJavaWrapper.h | 22 ++--- .../xpcom/src/nsJavaXPCOMBindingUtils.cpp | 82 ++++--------------- .../java/xpcom/src/nsJavaXPCOMBindingUtils.h | 16 ++-- .../java/xpcom/src/nsJavaXPTCStub.cpp | 71 ++++++++++++++-- .../java/xpcom/src/nsJavaXPTCStub.h | 15 ++++ 7 files changed, 171 insertions(+), 126 deletions(-) diff --git a/mozilla/extensions/java/xpcom/src/nsJavaInterfaces.cpp b/mozilla/extensions/java/xpcom/src/nsJavaInterfaces.cpp index 188191987c4..bafe8babe8f 100644 --- a/mozilla/extensions/java/xpcom/src/nsJavaInterfaces.cpp +++ b/mozilla/extensions/java/xpcom/src/nsJavaInterfaces.cpp @@ -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; } diff --git a/mozilla/extensions/java/xpcom/src/nsJavaWrapper.cpp b/mozilla/extensions/java/xpcom/src/nsJavaWrapper.cpp index c86245398a2..9b54f2f50d6 100644 --- a/mozilla/extensions/java/xpcom/src/nsJavaWrapper.cpp +++ b/mozilla/extensions/java/xpcom/src/nsJavaWrapper.cpp @@ -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 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 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 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 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; diff --git a/mozilla/extensions/java/xpcom/src/nsJavaWrapper.h b/mozilla/extensions/java/xpcom/src/nsJavaWrapper.h index a468ead2e0d..c441a41c303 100644 --- a/mozilla/extensions/java/xpcom/src/nsJavaWrapper.h +++ b/mozilla/extensions/java/xpcom/src/nsJavaWrapper.h @@ -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. diff --git a/mozilla/extensions/java/xpcom/src/nsJavaXPCOMBindingUtils.cpp b/mozilla/extensions/java/xpcom/src/nsJavaXPCOMBindingUtils.cpp index 61fcabdeeec..33ccb8887eb 100644 --- a/mozilla/extensions/java/xpcom/src/nsJavaXPCOMBindingUtils.cpp +++ b/mozilla/extensions/java/xpcom/src/nsJavaXPCOMBindingUtils.cpp @@ -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 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 - iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr 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 diff --git a/mozilla/extensions/java/xpcom/src/nsJavaXPCOMBindingUtils.h b/mozilla/extensions/java/xpcom/src/nsJavaXPCOMBindingUtils.h index 865da2e9494..35948e7738a 100644 --- a/mozilla/extensions/java/xpcom/src/nsJavaXPCOMBindingUtils.h +++ b/mozilla/extensions/java/xpcom/src/nsJavaXPCOMBindingUtils.h @@ -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, diff --git a/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.cpp b/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.cpp index db64b691993..4283d3733e1 100644 --- a/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.cpp +++ b/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.cpp @@ -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 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 in = do_QueryInterface(*variant); - nsCOMPtr out = do_QueryInterface(xpcom_obj); + nsCOMPtr 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 + iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr 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; +} \ No newline at end of file diff --git a/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.h b/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.h index 9a1b55b43eb..dd65f72b278 100644 --- a/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.h +++ b/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.h @@ -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();