mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Only master XPTCStub should hold strong ref to Java object. Not part of default build.
This commit is contained in:
parent
dc2f808614
commit
fba0b494d1
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user