Reorganize bindings methods. Also, properly check error conditions in those methods.

This commit is contained in:
pedemont%us.ibm.com 2005-01-14 00:09:49 +00:00
Родитель 1c4678463e
Коммит 2b5e618ee2
6 изменённых файлов: 221 добавлений и 161 удалений

Просмотреть файл

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