Only master XPTCStub should hold strong ref to Java object. Not part of default build.

This commit is contained in:
pedemont%us.ibm.com 2004-10-07 15:11:34 +00:00
parent dc2f808614
commit fba0b494d1
2 changed files with 78 additions and 31 deletions

View File

@ -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<nsIInterfaceInfo> 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;
}

View File

@ -54,7 +54,8 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSISUPPORTSWEAKREFERENCE
nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject, nsIInterfaceInfo *aIInfo);
nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject,
nsIInterfaceInfo *aIInfo, nsJavaXPTCStub* aMaster = nsnull);
virtual ~nsJavaXPTCStub();
@ -67,6 +68,9 @@ public:
const nsXPTMethodInfo *aInfo,
nsXPTCMiniVariant *aParams);
// getter for mJavaObject
jobject GetJavaObject();
private:
// NS_HIDDEN ~JavaStub();
@ -94,11 +98,11 @@ private:
jvalue &aJValue);
nsresult SetXPCOMRetval();
JNIEnv* mJavaEnv;
jobject mJavaObject;
nsCOMPtr<nsIInterfaceInfo> mIInfo;
JNIEnv* mJavaEnv;
jobject mJavaObject;
nsCOMPtr<nsIInterfaceInfo> mIInfo;
nsVoidArray mChildren; // weak references (cleared by the children)
nsVoidArray mChildren; // weak references (cleared by the children)
nsJavaXPTCStub *mMaster; // strong reference
};