diff --git a/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.cpp b/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.cpp index 04538b175f0..db67109cf75 100644 --- a/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.cpp +++ b/mozilla/extensions/java/xpcom/src/nsJavaXPTCStub.cpp @@ -46,23 +46,51 @@ nsJavaXPTCStub::nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject, - nsIInterfaceInfo *aIInfo) + nsIInterfaceInfo *aIInfo, nsJavaXPTCStub* aMaster) : mJavaEnv(aJavaEnv) , mIInfo(aIInfo) - , mMaster(nsnull) + , mMaster(aMaster) { - mJavaObject = aJavaEnv->NewGlobalRef(aJavaObject); + // Only the master stub object holds a strong ref to the Java object + if (!mMaster) + mJavaObject = aJavaEnv->NewGlobalRef(aJavaObject); + +#ifdef DEBUG + jboolean isCopy; + nsID* iid = nsnull; + char* iid_str = nsnull; + nsJavaXPTCStub *master = mMaster ? mMaster : this; + jclass clazz = mJavaEnv->GetObjectClass(master->mJavaObject); + jstring name = (jstring) mJavaEnv->CallObjectMethod(clazz, getNameMID); + const char* javaObjectName = mJavaEnv->GetStringUTFChars(name, &isCopy); + if (mIInfo) { + mIInfo->GetInterfaceIID(&iid); + if (iid) { + iid_str = iid->ToString(); + nsMemory::Free(iid); + } + } + LOG("+++ nsJavaXPTCStub(this=0x%08x java_obj=0x%08x %s iid=%s)\n", (int) this, + mJavaEnv->CallIntMethod(master->mJavaObject, hashCodeMID), javaObjectName, + iid_str ? iid_str : "NULL"); + if (isCopy) + mJavaEnv->ReleaseStringUTFChars(name, javaObjectName); + if (iid_str) + nsMemory::Free(iid_str); +#endif } nsJavaXPTCStub::~nsJavaXPTCStub() { + nsJavaXPTCStub *master = mMaster ? mMaster : this; + #ifdef DEBUG jboolean isCopy; - jclass clazz = mJavaEnv->GetObjectClass(mJavaObject); + jclass clazz = mJavaEnv->GetObjectClass(master->mJavaObject); jstring name = (jstring) mJavaEnv->CallObjectMethod(clazz, getNameMID); const char* javaObjectName = mJavaEnv->GetStringUTFChars(name, &isCopy); - LOG("*** ~nsJavaXPTCStub(this=0x%08x java_obj=0x%08x %s)\n", (int) this, - mJavaEnv->CallIntMethod(mJavaObject, hashCodeMID), javaObjectName); + LOG("--- ~nsJavaXPTCStub(this=0x%08x java_obj=0x%08x %s)\n", (int) this, + mJavaEnv->CallIntMethod(master->mJavaObject, hashCodeMID), javaObjectName); if (isCopy) mJavaEnv->ReleaseStringUTFChars(name, javaObjectName); #endif @@ -72,11 +100,10 @@ nsJavaXPTCStub::~nsJavaXPTCStub() for (PRInt32 i = 0; i < mChildren.Count(); i++) { delete (nsJavaXPTCStub*) mChildren[i]; } + + RemoveJavaXPCOMBinding(mJavaEnv, mJavaObject, this); + mJavaEnv->DeleteGlobalRef(mJavaObject); } - - RemoveJavaXPCOMBinding(mJavaEnv, mJavaObject, this); - - mJavaEnv->DeleteGlobalRef(mJavaObject); } NS_IMETHODIMP_(nsrefcnt) @@ -146,7 +173,7 @@ nsJavaXPTCStub::QueryInterface(const nsID &aIID, void **aInstancePtr) // Query Java object LOG("\tCalling Java object queryInterface\n"); - jclass clazz = mJavaEnv->GetObjectClass(mJavaObject); + jclass clazz = mJavaEnv->GetObjectClass(master->mJavaObject); char* sig = "(Ljava/lang/String;)Lorg/mozilla/xpcom/nsISupports;"; jmethodID qiMID = mJavaEnv->GetMethodID(clazz, "queryInterface", sig); NS_ASSERTION(qiMID, "Failed to get queryInterface method ID"); @@ -154,7 +181,7 @@ nsJavaXPTCStub::QueryInterface(const nsID &aIID, void **aInstancePtr) char* iid_str = aIID.ToString(); jstring iid_jstr = mJavaEnv->NewStringUTF(iid_str); PR_Free(iid_str); - jobject obj = mJavaEnv->CallObjectMethod(mJavaObject, qiMID, iid_jstr); + jobject obj = mJavaEnv->CallObjectMethod(master->mJavaObject, qiMID, iid_jstr); if (obj) { // Get interface info for new java object @@ -162,7 +189,7 @@ nsJavaXPTCStub::QueryInterface(const nsID &aIID, void **aInstancePtr) nsCOMPtr iinfo; iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo)); - nsJavaXPTCStub* stub = new nsJavaXPTCStub(mJavaEnv, obj, iinfo); + nsJavaXPTCStub* stub = new nsJavaXPTCStub(mJavaEnv, obj, iinfo, master); // add stub to the master's list of children, so we can preserve // symmetry in future QI calls. the master will delete each child @@ -185,7 +212,6 @@ nsJavaXPTCStub::QueryInterface(const nsID &aIID, void **aInstancePtr) // to access |foo| even if the code doesn't own a strong reference // to |foo|! clearly wrong, but we need to support it anyways. - stub->mMaster = master; master->mChildren.AppendElement(stub); *aInstancePtr = stub; @@ -252,6 +278,7 @@ nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex, #endif nsresult rv = NS_OK; + nsJavaXPTCStub *master = mMaster ? mMaster : this; nsCAutoString methodSig("("); @@ -304,7 +331,7 @@ nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex, methodName.SetCharAt(tolower(methodName[0]), 0); } - jclass clazz = mJavaEnv->GetObjectClass(mJavaObject); + jclass clazz = mJavaEnv->GetObjectClass(master->mJavaObject); if (clazz) mid = mJavaEnv->GetMethodID(clazz, methodName.get(), methodSig.get()); NS_ASSERTION(mid, "Failed to get requested method for Java object"); @@ -314,40 +341,47 @@ nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex, jvalue retval; if (mid) { if (!retvalInfo) { - mJavaEnv->CallVoidMethodA(mJavaObject, mid, java_params); + mJavaEnv->CallVoidMethodA(master->mJavaObject, mid, java_params); } else { switch (retvalInfo->GetType().TagPart()) { case nsXPTType::T_I8: case nsXPTType::T_U8: - retval.b = mJavaEnv->CallByteMethodA(mJavaObject, mid, java_params); + retval.b = mJavaEnv->CallByteMethodA(master->mJavaObject, mid, + java_params); break; case nsXPTType::T_I16: case nsXPTType::T_U16: - retval.s = mJavaEnv->CallShortMethodA(mJavaObject, mid, java_params); + retval.s = mJavaEnv->CallShortMethodA(master->mJavaObject, mid, + java_params); break; case nsXPTType::T_I32: case nsXPTType::T_U32: - retval.i = mJavaEnv->CallIntMethodA(mJavaObject, mid, java_params); + retval.i = mJavaEnv->CallIntMethodA(master->mJavaObject, mid, + java_params); break; case nsXPTType::T_FLOAT: - retval.f = mJavaEnv->CallFloatMethodA(mJavaObject, mid, java_params); + retval.f = mJavaEnv->CallFloatMethodA(master->mJavaObject, mid, + java_params); break; case nsXPTType::T_DOUBLE: - retval.d = mJavaEnv->CallDoubleMethodA(mJavaObject, mid, java_params); + retval.d = mJavaEnv->CallDoubleMethodA(master->mJavaObject, mid, + java_params); break; case nsXPTType::T_BOOL: - retval.z = mJavaEnv->CallBooleanMethodA(mJavaObject, mid, java_params); + retval.z = mJavaEnv->CallBooleanMethodA(master->mJavaObject, mid, + java_params); break; case nsXPTType::T_CHAR: case nsXPTType::T_WCHAR: - retval.c = mJavaEnv->CallCharMethodA(mJavaObject, mid, java_params); + retval.c = mJavaEnv->CallCharMethodA(master->mJavaObject, mid, + java_params); break; case nsXPTType::T_CHAR_STR: @@ -359,11 +393,13 @@ nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex, case nsXPTType::T_CSTRING: case nsXPTType::T_INTERFACE: case nsXPTType::T_INTERFACE_IS: - retval.l = mJavaEnv->CallObjectMethodA(mJavaObject, mid, java_params); + retval.l = mJavaEnv->CallObjectMethodA(master->mJavaObject, mid, + java_params); break; case nsXPTType::T_VOID: - retval.i = mJavaEnv->CallIntMethodA(mJavaObject, mid, java_params); + retval.i = mJavaEnv->CallIntMethodA(master->mJavaObject, mid, + java_params); break; default: @@ -1229,11 +1265,18 @@ nsJavaXPTCStub::GetWeakReference(nsIWeakReference** aInstancePtr) if (!aInstancePtr) return NS_ERROR_NULL_POINTER; + nsJavaXPTCStub *master = mMaster ? mMaster : this; nsJavaXPTCStubWeakRef* weakref = - new nsJavaXPTCStubWeakRef(mJavaEnv, mJavaObject); + new nsJavaXPTCStubWeakRef(mJavaEnv, master->mJavaObject); *aInstancePtr = weakref; NS_ADDREF(*aInstancePtr); return NS_OK; } +jobject +nsJavaXPTCStub::GetJavaObject() +{ + nsJavaXPTCStub *master = mMaster ? mMaster : this; + return master->mJavaObject; +}