зеркало из https://github.com/mozilla/gecko-dev.git
Reorganize bindings methods. Also, properly check error conditions in those methods.
This commit is contained in:
Родитель
1c4678463e
Коммит
2b5e618ee2
|
@ -130,7 +130,6 @@ XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jclass, jobject aMozBinDirectory,
|
|||
delete provider;
|
||||
}
|
||||
|
||||
jobject java_stub = nsnull;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// wrap xpcom instance
|
||||
JavaXPCOMInstance* inst;
|
||||
|
@ -140,12 +139,13 @@ XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jclass, jobject aMozBinDirectory,
|
|||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// create java stub
|
||||
java_stub = CreateJavaWrapper(env, "nsIServiceManager");
|
||||
jobject java_stub = CreateJavaWrapper(env, "nsIServiceManager");
|
||||
|
||||
if (java_stub) {
|
||||
// Associate XPCOM object w/ Java stub
|
||||
AddJavaXPCOMBinding(env, java_stub, inst);
|
||||
return java_stub;
|
||||
rv = gBindings->AddBinding(env, java_stub, inst);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return java_stub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,8 +164,8 @@ XPCOM_NATIVE(shutdownXPCOM) (JNIEnv *env, jclass, jobject aServMgr)
|
|||
nsCOMPtr<nsIServiceManager> servMgr;
|
||||
if (aServMgr) {
|
||||
// Find corresponding XPCOM object
|
||||
void* xpcomObj = GetMatchingXPCOMObject(env, aServMgr);
|
||||
NS_ASSERTION(xpcomObj != nsnull, "Failed to get matching XPCOM object");
|
||||
void* xpcomObj = gBindings->GetXPCOMObject(env, aServMgr);
|
||||
NS_ASSERTION(xpcomObj != nsnull, "Failed to get XPCOM obj for ServiceMgr.");
|
||||
|
||||
// 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.
|
||||
|
@ -188,8 +188,6 @@ extern "C" JNIEXPORT jobject JNICALL
|
|||
XPCOM_NATIVE(newLocalFile) (JNIEnv *env, jclass, jstring aPath,
|
||||
jboolean aFollowLinks)
|
||||
{
|
||||
jobject java_stub = nsnull;
|
||||
|
||||
// Create a Mozilla string from the jstring
|
||||
jboolean isCopy;
|
||||
const PRUnichar* buf = nsnull;
|
||||
|
@ -216,26 +214,24 @@ XPCOM_NATIVE(newLocalFile) (JNIEnv *env, jclass, jstring aPath,
|
|||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// create java stub
|
||||
java_stub = CreateJavaWrapper(env, "nsILocalFile");
|
||||
jobject java_stub = CreateJavaWrapper(env, "nsILocalFile");
|
||||
|
||||
if (java_stub) {
|
||||
// Associate XPCOM object w/ Java stub
|
||||
AddJavaXPCOMBinding(env, java_stub, inst);
|
||||
rv = gBindings->AddBinding(env, java_stub, inst);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return java_stub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (java_stub == nsnull)
|
||||
ThrowException(env, rv, "Failure in newLocalFile");
|
||||
|
||||
return java_stub;
|
||||
ThrowException(env, rv, "Failure in newLocalFile");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jclass)
|
||||
{
|
||||
jobject java_stub = nsnull;
|
||||
|
||||
// Call XPCOM method
|
||||
nsIComponentManager* cm = nsnull;
|
||||
nsresult rv = NS_GetComponentManager(&cm);
|
||||
|
@ -248,26 +244,24 @@ XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jclass)
|
|||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// create java stub
|
||||
java_stub = CreateJavaWrapper(env, "nsIComponentManager");
|
||||
jobject java_stub = CreateJavaWrapper(env, "nsIComponentManager");
|
||||
|
||||
if (java_stub) {
|
||||
// Associate XPCOM object w/ Java stub
|
||||
AddJavaXPCOMBinding(env, java_stub, inst);
|
||||
rv = gBindings->AddBinding(env, java_stub, inst);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return java_stub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (java_stub == nsnull)
|
||||
ThrowException(env, rv, "Failure in getComponentManager");
|
||||
|
||||
return java_stub;
|
||||
ThrowException(env, rv, "Failure in getComponentManager");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
XPCOM_NATIVE(getComponentRegistrar) (JNIEnv *env, jclass)
|
||||
{
|
||||
jobject java_stub = nsnull;
|
||||
|
||||
// Call XPCOM method
|
||||
nsIComponentRegistrar* cr = nsnull;
|
||||
nsresult rv = NS_GetComponentRegistrar(&cr);
|
||||
|
@ -280,26 +274,24 @@ XPCOM_NATIVE(getComponentRegistrar) (JNIEnv *env, jclass)
|
|||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// create java stub
|
||||
java_stub = CreateJavaWrapper(env, "nsIComponentRegistrar");
|
||||
jobject java_stub = CreateJavaWrapper(env, "nsIComponentRegistrar");
|
||||
|
||||
if (java_stub) {
|
||||
// Associate XPCOM object w/ Java stub
|
||||
AddJavaXPCOMBinding(env, java_stub, inst);
|
||||
rv = gBindings->AddBinding(env, java_stub, inst);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return java_stub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (java_stub == nsnull)
|
||||
ThrowException(env, rv, "Failure in getComponentRegistrar");
|
||||
|
||||
return java_stub;
|
||||
ThrowException(env, rv, "Failure in getComponentRegistrar");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jclass)
|
||||
{
|
||||
jobject java_stub = nsnull;
|
||||
|
||||
// Call XPCOM method
|
||||
nsIServiceManager* sm = nsnull;
|
||||
nsresult rv = NS_GetServiceManager(&sm);
|
||||
|
@ -312,19 +304,19 @@ XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jclass)
|
|||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// create java stub
|
||||
java_stub = CreateJavaWrapper(env, "nsIServiceManager");
|
||||
jobject java_stub = CreateJavaWrapper(env, "nsIServiceManager");
|
||||
|
||||
if (java_stub) {
|
||||
// Associate XPCOM object w/ Java stub
|
||||
AddJavaXPCOMBinding(env, java_stub, inst);
|
||||
rv = gBindings->AddBinding(env, java_stub, inst);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return java_stub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (java_stub == nsnull)
|
||||
ThrowException(env, rv, "Failure in getServiceManager");
|
||||
|
||||
return java_stub;
|
||||
ThrowException(env, rv, "Failure in getServiceManager");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
@ -539,7 +531,7 @@ extern "C" JNIEXPORT void JNICALL
|
|||
XPCOMPRIVATE_NATIVE(FinalizeStub) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_pedemonte
|
||||
jboolean isCopy;
|
||||
jclass clazz = env->GetObjectClass(aJavaObject);
|
||||
jstring name = (jstring) env->CallObjectMethod(clazz, getNameMID);
|
||||
|
@ -549,10 +541,10 @@ XPCOMPRIVATE_NATIVE(FinalizeStub) (JNIEnv *env, jclass that,
|
|||
env->ReleaseStringUTFChars(name, javaObjectName);
|
||||
#endif
|
||||
|
||||
void* obj = GetMatchingXPCOMObject(env, aJavaObject);
|
||||
void* obj = gBindings->GetXPCOMObject(env, aJavaObject);
|
||||
NS_ASSERTION(!IsXPTCStub(obj),
|
||||
"Expecting JavaXPCOMInstance, got nsJavaXPTCStub");
|
||||
RemoveJavaXPCOMBinding(env, aJavaObject, nsnull);
|
||||
gBindings->RemoveBinding(env, aJavaObject, nsnull);
|
||||
delete (JavaXPCOMInstance*) obj;
|
||||
}
|
||||
|
||||
|
|
|
@ -334,7 +334,7 @@ SetupParams(JNIEnv *env, const jobject aParam, const nsXPTParamInfo &aParamInfo,
|
|||
void* xpcom_obj;
|
||||
if (java_obj) {
|
||||
// Check if we already have a corresponding XPCOM object
|
||||
void* inst = GetMatchingXPCOMObject(env, java_obj);
|
||||
void* inst = gBindings->GetXPCOMObject(env, java_obj);
|
||||
|
||||
// Get IID for this param
|
||||
nsID iid;
|
||||
|
@ -366,7 +366,7 @@ SetupParams(JNIEnv *env, const jobject aParam, const nsXPTParamInfo &aParamInfo,
|
|||
break;
|
||||
}
|
||||
inst = SetAsXPTCStub(xpcomStub);
|
||||
AddJavaXPCOMBinding(env, java_obj, inst);
|
||||
gBindings->AddBinding(env, java_obj, inst);
|
||||
}
|
||||
|
||||
if (isWeakRef) {
|
||||
|
@ -670,7 +670,7 @@ FinalizeParams(JNIEnv *env, const jobject aParam,
|
|||
jobject java_obj = nsnull;
|
||||
if (xpcom_obj) {
|
||||
// Find matching Java object for given xpcom object
|
||||
java_obj = GetMatchingJavaObject(env, xpcom_obj);
|
||||
java_obj = gBindings->GetJavaObject(env, xpcom_obj);
|
||||
|
||||
// If no matching Java object exists, create one
|
||||
if (java_obj == nsnull) {
|
||||
|
@ -699,7 +699,7 @@ FinalizeParams(JNIEnv *env, const jobject aParam,
|
|||
|
||||
if (java_obj) {
|
||||
// Associate XPCOM object w/ Java stub
|
||||
AddJavaXPCOMBinding(env, java_obj, inst);
|
||||
gBindings->AddBinding(env, java_obj, inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -889,7 +889,7 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
|||
case nsXPTType::T_INTERFACE_IS:
|
||||
{
|
||||
if (aVariant.val.p) {
|
||||
jobject java_obj = GetMatchingJavaObject(env, aVariant.val.p);
|
||||
jobject java_obj = gBindings->GetJavaObject(env, aVariant.val.p);
|
||||
|
||||
if (java_obj == nsnull) {
|
||||
nsID iid;
|
||||
|
@ -914,10 +914,9 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
|||
java_obj = CreateJavaWrapper(env, iface_name);
|
||||
|
||||
if (java_obj)
|
||||
AddJavaXPCOMBinding(env, java_obj, inst);
|
||||
gBindings->AddBinding(env, java_obj, inst);
|
||||
}
|
||||
|
||||
// XXX not sure if this is necessary
|
||||
// If returned object is an nsJavaXPTCStub, release it.
|
||||
nsISupports* xpcom_obj = NS_STATIC_CAST(nsISupports*, aVariant.val.p);
|
||||
nsJavaXPTCStub* stub = nsnull;
|
||||
|
@ -989,7 +988,7 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
|
|||
jint aMethodIndex, jobjectArray aParams, jvalue &aResult)
|
||||
{
|
||||
// Find corresponding XPCOM object
|
||||
void* xpcomObj = GetMatchingXPCOMObject(env, aJavaObject);
|
||||
void* xpcomObj = gBindings->GetXPCOMObject(env, aJavaObject);
|
||||
if (xpcomObj == nsnull) {
|
||||
ThrowException(env, 0, "Failed to get matching XPCOM object");
|
||||
return;
|
||||
|
@ -1008,7 +1007,7 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_pedemonte
|
||||
const char* ifaceName;
|
||||
iinfo->GetNameShared(&ifaceName);
|
||||
LOG(("=> Calling %s::%s()\n", ifaceName, methodInfo->GetName()));
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "nsJavaXPTCStub.h"
|
||||
#include "jni.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "pldhash.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsEventQueueUtils.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
@ -65,6 +64,8 @@ jmethodID doubleValueMID = nsnull;
|
|||
jmethodID getNameMID = nsnull;
|
||||
#endif
|
||||
|
||||
nsJavaXPCOMBindings* gBindings = nsnull;
|
||||
|
||||
|
||||
/**************************************
|
||||
* Java<->XPCOM binding stores
|
||||
|
@ -79,9 +80,6 @@ public:
|
|||
void* mXPCOMInstance;
|
||||
};
|
||||
|
||||
static PLDHashTable *gJAVAtoXPCOMBindings = nsnull;
|
||||
static PLDHashTable *gXPCOMtoJAVABindings = nsnull;
|
||||
|
||||
PR_STATIC_CALLBACK(PRBool)
|
||||
InitJavaXPCOMBindingEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
|
||||
const void *key)
|
||||
|
@ -95,20 +93,78 @@ InitJavaXPCOMBindingEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
AddJavaXPCOMBinding(JNIEnv* env, jobject aJavaObject, void* aXPCOMObject)
|
||||
NS_IMETHODIMP
|
||||
nsJavaXPCOMBindings::Init()
|
||||
{
|
||||
static PLDHashTableOps java_to_xpcom_hash_ops =
|
||||
{
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
PL_DHashGetKeyStub,
|
||||
PL_DHashVoidPtrKeyStub,
|
||||
PL_DHashMatchEntryStub,
|
||||
PL_DHashMoveEntryStub,
|
||||
PL_DHashClearEntryStub,
|
||||
PL_DHashFinalizeStub,
|
||||
InitJavaXPCOMBindingEntry
|
||||
};
|
||||
|
||||
mJAVAtoXPCOMBindings = PL_NewDHashTable(&java_to_xpcom_hash_ops, nsnull,
|
||||
sizeof(JavaXPCOMBindingEntry), 16);
|
||||
if (!mJAVAtoXPCOMBindings)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
static PLDHashTableOps xpcom_to_java_hash_ops =
|
||||
{
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
PL_DHashGetKeyStub,
|
||||
PL_DHashVoidPtrKeyStub,
|
||||
PL_DHashMatchEntryStub,
|
||||
PL_DHashMoveEntryStub,
|
||||
PL_DHashClearEntryStub,
|
||||
PL_DHashFinalizeStub,
|
||||
InitJavaXPCOMBindingEntry
|
||||
};
|
||||
|
||||
mXPCOMtoJAVABindings = PL_NewDHashTable(&xpcom_to_java_hash_ops, nsnull,
|
||||
sizeof(JavaXPCOMBindingEntry), 16);
|
||||
if (!mXPCOMtoJAVABindings)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsJavaXPCOMBindings::~nsJavaXPCOMBindings()
|
||||
{
|
||||
if (mJAVAtoXPCOMBindings)
|
||||
PL_DHashTableDestroy(mJAVAtoXPCOMBindings);
|
||||
if (mXPCOMtoJAVABindings)
|
||||
PL_DHashTableDestroy(mXPCOMtoJAVABindings);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJavaXPCOMBindings::AddBinding(JNIEnv* env, jobject aJavaObject,
|
||||
void* aXPCOMObject)
|
||||
{
|
||||
// We use a Java hash of the Java object as a key since the JVM can return
|
||||
// different "addresses" for the same Java object, but the hash code (the
|
||||
// result of calling |hashCode()| on the Java object) will always be the same.
|
||||
jint hash = env->CallIntMethod(aJavaObject, hashCodeMID);
|
||||
jweak java_ref = env->NewWeakGlobalRef(aJavaObject);
|
||||
if (!java_ref)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Add a new entry into hash
|
||||
JavaXPCOMBindingEntry *entry =
|
||||
NS_STATIC_CAST(JavaXPCOMBindingEntry*,
|
||||
PL_DHashTableOperate(gJAVAtoXPCOMBindings,
|
||||
PL_DHashTableOperate(mJAVAtoXPCOMBindings,
|
||||
NS_INT32_TO_PTR(hash),
|
||||
PL_DHASH_ADD));
|
||||
if (!entry)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Set entry fields
|
||||
entry->mJavaObject = java_ref;
|
||||
entry->mXPCOMInstance = aXPCOMObject;
|
||||
|
||||
|
@ -119,29 +175,40 @@ AddJavaXPCOMBinding(JNIEnv* env, jobject aJavaObject, void* aXPCOMObject)
|
|||
else
|
||||
xpcomObjKey = ((JavaXPCOMInstance*) aXPCOMObject)->GetInstance();
|
||||
|
||||
// Add a new entry into other hash table
|
||||
entry =
|
||||
NS_STATIC_CAST(JavaXPCOMBindingEntry*,
|
||||
PL_DHashTableOperate(gXPCOMtoJAVABindings, xpcomObjKey,
|
||||
PL_DHashTableOperate(mXPCOMtoJAVABindings, xpcomObjKey,
|
||||
PL_DHASH_ADD));
|
||||
if (!entry)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
entry->mJavaObject = java_ref;
|
||||
entry->mXPCOMInstance = aXPCOMObject;
|
||||
|
||||
LOG(("+ Adding Java<->XPCOM binding (Java=0x%08x | XPCOM=0x%08x) weakref=0x%08x\n",
|
||||
hash, (int) xpcomObjKey, (PRUint32) java_ref));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
RemoveJavaXPCOMBinding(JNIEnv* env, jobject aJavaObject, void* aXPCOMObject)
|
||||
NS_IMETHODIMP
|
||||
nsJavaXPCOMBindings::RemoveBinding(JNIEnv* env, jobject aJavaObject,
|
||||
void* aXPCOMObject)
|
||||
{
|
||||
// We either get a Java or an XPCOM object. So find the other object.
|
||||
// Given a Java or XPCOM object, find the associated object.
|
||||
NS_PRECONDITION(aJavaObject != nsnull || aXPCOMObject != nsnull,
|
||||
"Need either a Java or XPCOM object");
|
||||
|
||||
jint hash = 0;
|
||||
void* xpcomObjKey = nsnull;
|
||||
JavaXPCOMBindingEntry* entry = nsnull;
|
||||
|
||||
if (aJavaObject) {
|
||||
hash = env->CallIntMethod(aJavaObject, hashCodeMID);
|
||||
JavaXPCOMBindingEntry* e =
|
||||
NS_STATIC_CAST(JavaXPCOMBindingEntry*,
|
||||
PL_DHashTableOperate(gJAVAtoXPCOMBindings,
|
||||
PL_DHashTableOperate(mJAVAtoXPCOMBindings,
|
||||
NS_INT32_TO_PTR(hash),
|
||||
PL_DHASH_LOOKUP));
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(e))
|
||||
|
@ -149,61 +216,63 @@ RemoveJavaXPCOMBinding(JNIEnv* env, jobject aJavaObject, void* aXPCOMObject)
|
|||
} else {
|
||||
JavaXPCOMBindingEntry* e =
|
||||
NS_STATIC_CAST(JavaXPCOMBindingEntry*,
|
||||
PL_DHashTableOperate(gXPCOMtoJAVABindings, aXPCOMObject,
|
||||
PL_DHashTableOperate(mXPCOMtoJAVABindings, aXPCOMObject,
|
||||
PL_DHASH_LOOKUP));
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(e))
|
||||
entry = e;
|
||||
}
|
||||
NS_ASSERTION(entry != nsnull, "Failed to find matching entry");
|
||||
|
||||
if (entry) {
|
||||
jobject jweakref = entry->mJavaObject;
|
||||
void* xpcom_obj = entry->mXPCOMInstance;
|
||||
|
||||
// Get keys. For Java, we use the hash key of the Java object. For XPCOM,
|
||||
// we get the 'actual' object (either the nsJavaXPTCStub or the instance
|
||||
// that is wrapped by JavaXPCOMInstance).
|
||||
void* xpcomObjKey = nsnull;
|
||||
if (hash == 0)
|
||||
hash = env->CallIntMethod(jweakref, hashCodeMID);
|
||||
if (aXPCOMObject) {
|
||||
xpcomObjKey = aXPCOMObject;
|
||||
} else {
|
||||
if (IsXPTCStub(xpcom_obj))
|
||||
xpcomObjKey = GetXPTCStubAddr(xpcom_obj);
|
||||
else
|
||||
xpcomObjKey = ((JavaXPCOMInstance*) xpcom_obj)->GetInstance();
|
||||
}
|
||||
|
||||
NS_ASSERTION(env->IsSameObject(jweakref, aJavaObject),
|
||||
"Weakref does not point to expected Java object");
|
||||
NS_ASSERTION(!env->IsSameObject(jweakref, NULL),
|
||||
"Weakref refers to garbage collected Java object. No longer valid");
|
||||
|
||||
// Remove both instances from stores
|
||||
PL_DHashTableOperate(gJAVAtoXPCOMBindings, NS_INT32_TO_PTR(hash),
|
||||
PL_DHASH_REMOVE);
|
||||
PL_DHashTableOperate(gXPCOMtoJAVABindings, xpcomObjKey, PL_DHASH_REMOVE);
|
||||
LOG(("- Removing Java<->XPCOM binding (Java=0x%08x | XPCOM=0x%08x) weakref=0x%08x\n",
|
||||
hash, (int) xpcomObjKey, (PRUint32) jweakref));
|
||||
|
||||
env->DeleteWeakGlobalRef(NS_STATIC_CAST(jweak, jweakref));
|
||||
if (!entry) {
|
||||
NS_WARNING("Failed to find matching entry");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
jobject jweakref = entry->mJavaObject;
|
||||
void* xpcom_obj = entry->mXPCOMInstance;
|
||||
|
||||
// Get keys. For Java, we use the hash key of the Java object. For XPCOM,
|
||||
// we get the 'actual' object (either the nsJavaXPTCStub or the instance
|
||||
// that is wrapped by JavaXPCOMInstance).
|
||||
if (hash == 0) {
|
||||
hash = env->CallIntMethod(jweakref, hashCodeMID);
|
||||
}
|
||||
if (aXPCOMObject) {
|
||||
xpcomObjKey = aXPCOMObject;
|
||||
} else {
|
||||
if (IsXPTCStub(xpcom_obj))
|
||||
xpcomObjKey = GetXPTCStubAddr(xpcom_obj);
|
||||
else
|
||||
xpcomObjKey = ((JavaXPCOMInstance*) xpcom_obj)->GetInstance();
|
||||
}
|
||||
|
||||
NS_ASSERTION(env->IsSameObject(jweakref, aJavaObject),
|
||||
"Weakref does not point to expected Java object");
|
||||
NS_ASSERTION(!env->IsSameObject(jweakref, NULL),
|
||||
"Weakref refers to garbage collected Java object. No longer valid");
|
||||
|
||||
// Remove both instances from stores
|
||||
PL_DHashTableOperate(mJAVAtoXPCOMBindings, NS_INT32_TO_PTR(hash),
|
||||
PL_DHASH_REMOVE);
|
||||
PL_DHashTableOperate(mXPCOMtoJAVABindings, xpcomObjKey, PL_DHASH_REMOVE);
|
||||
LOG(("- Removing Java<->XPCOM binding (Java=0x%08x | XPCOM=0x%08x) weakref=0x%08x\n",
|
||||
hash, (int) xpcomObjKey, (PRUint32) jweakref));
|
||||
|
||||
env->DeleteWeakGlobalRef(NS_STATIC_CAST(jweak, jweakref));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void*
|
||||
GetMatchingXPCOMObject(JNIEnv* env, jobject aJavaObject)
|
||||
nsJavaXPCOMBindings::GetXPCOMObject(JNIEnv* env, jobject aJavaObject)
|
||||
{
|
||||
jint hash = env->CallIntMethod(aJavaObject, hashCodeMID);
|
||||
|
||||
JavaXPCOMBindingEntry *entry =
|
||||
NS_STATIC_CAST(JavaXPCOMBindingEntry*,
|
||||
PL_DHashTableOperate(gJAVAtoXPCOMBindings,
|
||||
PL_DHashTableOperate(mJAVAtoXPCOMBindings,
|
||||
NS_INT32_TO_PTR(hash),
|
||||
PL_DHASH_LOOKUP));
|
||||
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_pedemonte
|
||||
void* xpcomObjKey = nsnull;
|
||||
if (IsXPTCStub(entry->mXPCOMInstance))
|
||||
xpcomObjKey = GetXPTCStubAddr(entry->mXPCOMInstance);
|
||||
|
@ -219,7 +288,7 @@ GetMatchingXPCOMObject(JNIEnv* env, jobject aJavaObject)
|
|||
}
|
||||
|
||||
jobject
|
||||
GetMatchingJavaObject(JNIEnv* env, void* aXPCOMObject)
|
||||
nsJavaXPCOMBindings::GetJavaObject(JNIEnv* env, void* aXPCOMObject)
|
||||
{
|
||||
jobject java_obj = nsnull;
|
||||
nsISupports* xpcom_obj = NS_STATIC_CAST(nsISupports*, aXPCOMObject);
|
||||
|
@ -235,7 +304,7 @@ GetMatchingJavaObject(JNIEnv* env, void* aXPCOMObject)
|
|||
if (java_obj == nsnull) {
|
||||
JavaXPCOMBindingEntry *entry =
|
||||
NS_STATIC_CAST(JavaXPCOMBindingEntry*,
|
||||
PL_DHashTableOperate(gXPCOMtoJAVABindings, aXPCOMObject,
|
||||
PL_DHashTableOperate(mXPCOMtoJAVABindings, aXPCOMObject,
|
||||
PL_DHASH_LOOKUP));
|
||||
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
|
@ -243,10 +312,12 @@ GetMatchingJavaObject(JNIEnv* env, void* aXPCOMObject)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_pedemonte
|
||||
if (java_obj) {
|
||||
LOG(("< Get Java<->XPCOM binding (Java=0x%08x | XPCOM=0x%08x)\n",
|
||||
env->CallIntMethod(java_obj, hashCodeMID), (int) aXPCOMObject));
|
||||
}
|
||||
#endif
|
||||
|
||||
return java_obj;
|
||||
}
|
||||
|
@ -344,41 +415,8 @@ InitializeJavaGlobals(JNIEnv *env)
|
|||
}
|
||||
#endif
|
||||
|
||||
static PLDHashTableOps java_to_xpcom_hash_ops =
|
||||
{
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
PL_DHashGetKeyStub,
|
||||
PL_DHashVoidPtrKeyStub,
|
||||
PL_DHashMatchEntryStub,
|
||||
PL_DHashMoveEntryStub,
|
||||
PL_DHashClearEntryStub,
|
||||
PL_DHashFinalizeStub,
|
||||
InitJavaXPCOMBindingEntry
|
||||
};
|
||||
|
||||
gJAVAtoXPCOMBindings = PL_NewDHashTable(&java_to_xpcom_hash_ops, nsnull,
|
||||
sizeof(JavaXPCOMBindingEntry), 16);
|
||||
if (!gJAVAtoXPCOMBindings) {
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
static PLDHashTableOps xpcom_to_java_hash_ops =
|
||||
{
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
PL_DHashGetKeyStub,
|
||||
PL_DHashVoidPtrKeyStub,
|
||||
PL_DHashMatchEntryStub,
|
||||
PL_DHashMoveEntryStub,
|
||||
PL_DHashClearEntryStub,
|
||||
PL_DHashFinalizeStub,
|
||||
InitJavaXPCOMBindingEntry
|
||||
};
|
||||
|
||||
gXPCOMtoJAVABindings = PL_NewDHashTable(&xpcom_to_java_hash_ops, nsnull,
|
||||
sizeof(JavaXPCOMBindingEntry), 16);
|
||||
if (!gXPCOMtoJAVABindings) {
|
||||
gBindings = new nsJavaXPCOMBindings();
|
||||
if (NS_FAILED(gBindings->Init())) {
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
|
@ -411,13 +449,9 @@ FreeJavaGlobals(JNIEnv* env)
|
|||
xpcomExceptionClass = nsnull;
|
||||
}
|
||||
|
||||
if (gJAVAtoXPCOMBindings) {
|
||||
PL_DHashTableDestroy(gJAVAtoXPCOMBindings);
|
||||
gJAVAtoXPCOMBindings = nsnull;
|
||||
}
|
||||
if (gXPCOMtoJAVABindings) {
|
||||
PL_DHashTableDestroy(gXPCOMtoJAVABindings);
|
||||
gXPCOMtoJAVABindings = nsnull;
|
||||
if (gBindings) {
|
||||
delete gBindings;
|
||||
gBindings = nsnull;
|
||||
}
|
||||
|
||||
gInitialized = PR_FALSE;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "xptcall.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "pldhash.h"
|
||||
|
||||
#ifdef DEBUG_pedemonte
|
||||
#define LOG(x) printf x
|
||||
|
@ -71,6 +72,9 @@ extern jmethodID doubleValueMID;
|
|||
extern jmethodID getNameMID;
|
||||
#endif
|
||||
|
||||
class nsJavaXPCOMBindings;
|
||||
extern nsJavaXPCOMBindings* gBindings;
|
||||
|
||||
PRBool InitializeJavaGlobals(JNIEnv *env);
|
||||
void FreeJavaGlobals(JNIEnv* env);
|
||||
|
||||
|
@ -111,12 +115,38 @@ nsresult CreateJavaXPCOMInstance(nsISupports* aXPCOMObject, const nsIID* aIID,
|
|||
/**************************************
|
||||
* Java<->XPCOM binding stores
|
||||
**************************************/
|
||||
void AddJavaXPCOMBinding(JNIEnv* env, jobject aJavaStub,
|
||||
void* aXPCOMObject);
|
||||
void RemoveJavaXPCOMBinding(JNIEnv* env, jobject aJavaObject,
|
||||
void* aXPCOMObject);
|
||||
void* GetMatchingXPCOMObject(JNIEnv* env, jobject aJavaObject);
|
||||
jobject GetMatchingJavaObject(JNIEnv* env, void* aXPCOMObject);
|
||||
// This class is used to store the associations between existing Java object
|
||||
// and XPCOM objects.
|
||||
class nsJavaXPCOMBindings
|
||||
{
|
||||
public:
|
||||
nsJavaXPCOMBindings()
|
||||
: mJAVAtoXPCOMBindings(nsnull)
|
||||
, mXPCOMtoJAVABindings(nsnull)
|
||||
{ }
|
||||
~nsJavaXPCOMBindings();
|
||||
|
||||
// Initializes internal structures.
|
||||
NS_IMETHOD Init();
|
||||
|
||||
// Associates the given Java object with the given XPCOM object
|
||||
NS_IMETHOD AddBinding(JNIEnv* env, jobject aJavaStub, void* aXPCOMObject);
|
||||
|
||||
// Given either a Java object or XPCOM object, removes the association
|
||||
// between the two.
|
||||
NS_IMETHOD RemoveBinding(JNIEnv* env, jobject aJavaObject, void* aXPCOMObject);
|
||||
|
||||
// Given a Java object, returns the associated XPCOM object.
|
||||
void* GetXPCOMObject(JNIEnv* env, jobject aJavaObject);
|
||||
|
||||
// Given an XPCOM object, returns the associated Java Object.
|
||||
jobject GetJavaObject(JNIEnv* env, void* aXPCOMObject);
|
||||
|
||||
private:
|
||||
PLDHashTable* mJAVAtoXPCOMBindings;
|
||||
PLDHashTable* mXPCOMtoJAVABindings;
|
||||
};
|
||||
|
||||
|
||||
|
||||
nsresult GetIIDForMethodParam(nsIInterfaceInfo *iinfo,
|
||||
|
|
|
@ -53,7 +53,7 @@ nsJavaXPTCStub::nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject,
|
|||
{
|
||||
mJavaObject = aJavaEnv->NewGlobalRef(aJavaObject);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_pedemonte
|
||||
jboolean isCopy = PR_FALSE;
|
||||
jstring name;
|
||||
const char* javaObjectName = nsnull;
|
||||
|
@ -85,7 +85,7 @@ nsJavaXPTCStub::nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject,
|
|||
|
||||
nsJavaXPTCStub::~nsJavaXPTCStub()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_pedemonte
|
||||
jboolean isCopy = PR_FALSE;
|
||||
jstring name;
|
||||
const char* javaObjectName = nsnull;
|
||||
|
@ -108,7 +108,7 @@ nsJavaXPTCStub::~nsJavaXPTCStub()
|
|||
delete (nsJavaXPTCStub*) mChildren[i];
|
||||
}
|
||||
|
||||
RemoveJavaXPCOMBinding(mJavaEnv, mJavaObject, this);
|
||||
gBindings->RemoveBinding(mJavaEnv, mJavaObject, this);
|
||||
}
|
||||
|
||||
mJavaEnv->DeleteGlobalRef(mJavaObject);
|
||||
|
@ -205,9 +205,10 @@ nsJavaXPTCStub::QueryInterface(const nsID &aIID, void **aInstancePtr)
|
|||
}
|
||||
|
||||
// construct IID string
|
||||
jstring iid_jstr = nsnull;
|
||||
char* iid_str = aIID.ToString();
|
||||
if (iid_str) {
|
||||
jstring iid_jstr = mJavaEnv->NewStringUTF(iid_str);
|
||||
iid_jstr = mJavaEnv->NewStringUTF(iid_str);
|
||||
}
|
||||
if (!iid_str || !iid_jstr) {
|
||||
mJavaEnv->ExceptionClear();
|
||||
|
@ -312,7 +313,7 @@ nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex,
|
|||
const nsXPTMethodInfo *aMethodInfo,
|
||||
nsXPTCMiniVariant *aParams)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_pedemonte
|
||||
const char* ifaceName;
|
||||
mIInfo->GetNameShared(&ifaceName);
|
||||
LOG(("nsJavaXPTCStub::CallMethod [%s::%s]\n", ifaceName, aMethodInfo->GetName()));
|
||||
|
@ -820,7 +821,7 @@ nsJavaXPTCStub::SetupJavaParams(const nsXPTParamInfo &aParamInfo,
|
|||
|
||||
jobject java_stub = nsnull;
|
||||
if (xpcom_obj) {
|
||||
java_stub = GetMatchingJavaObject(mJavaEnv, xpcom_obj);
|
||||
java_stub = gBindings->GetJavaObject(mJavaEnv, xpcom_obj);
|
||||
|
||||
if (java_stub == nsnull) {
|
||||
// wrap xpcom instance
|
||||
|
@ -845,7 +846,9 @@ nsJavaXPTCStub::SetupJavaParams(const nsXPTParamInfo &aParamInfo,
|
|||
|
||||
if (java_stub) {
|
||||
// Associate XPCOM object w/ Java stub
|
||||
AddJavaXPCOMBinding(mJavaEnv, java_stub, inst);
|
||||
rv = gBindings->AddBinding(mJavaEnv, java_stub, inst);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1366,7 +1369,7 @@ nsJavaXPTCStub::FinalizeJavaParams(const nsXPTParamInfo &aParamInfo,
|
|||
nsISupports** variant = NS_STATIC_CAST(nsISupports**, aVariant.val.p);
|
||||
if (java_obj) {
|
||||
// Check if we already have a corresponding XPCOM object
|
||||
void* inst = GetMatchingXPCOMObject(mJavaEnv, java_obj);
|
||||
void* inst = gBindings->GetXPCOMObject(mJavaEnv, java_obj);
|
||||
|
||||
// Get IID for this param
|
||||
nsID iid;
|
||||
|
@ -1394,7 +1397,9 @@ nsJavaXPTCStub::FinalizeJavaParams(const nsXPTParamInfo &aParamInfo,
|
|||
break;
|
||||
}
|
||||
inst = SetAsXPTCStub(xpcomStub);
|
||||
AddJavaXPCOMBinding(mJavaEnv, java_obj, inst);
|
||||
rv = gBindings->AddBinding(mJavaEnv, java_obj, inst);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
|
||||
// Get appropriate XPCOM object
|
||||
|
|
|
@ -70,7 +70,7 @@ nsJavaXPTCStubWeakRef::QueryReferent(const nsIID& aIID, void** aInstancePtr)
|
|||
|
||||
// Java object has not been garbage collected. Do we have an
|
||||
// associated nsJavaXPTCStub?
|
||||
void* inst = GetMatchingXPCOMObject(mJavaEnv, javaObject);
|
||||
void* inst = gBindings->GetXPCOMObject(mJavaEnv, javaObject);
|
||||
|
||||
if (!inst) {
|
||||
// No XPTCStub exists, so create one
|
||||
|
@ -87,7 +87,7 @@ nsJavaXPTCStubWeakRef::QueryReferent(const nsIID& aIID, void** aInstancePtr)
|
|||
if (!xpcomStub)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(xpcomStub);
|
||||
AddJavaXPCOMBinding(mJavaEnv, javaObject, SetAsXPTCStub(xpcomStub));
|
||||
gBindings->AddBinding(mJavaEnv, javaObject, SetAsXPTCStub(xpcomStub));
|
||||
|
||||
// return created stub
|
||||
*aInstancePtr = (void*) xpcomStub;
|
||||
|
|
Загрузка…
Ссылка в новой задаче