diff --git a/mozilla/config/rules.mk b/mozilla/config/rules.mk
index 49d3b5c0cd7..ee49f642a01 100644
--- a/mozilla/config/rules.mk
+++ b/mozilla/config/rules.mk
@@ -1513,14 +1513,9 @@ $(XPIDL_GEN_DIR)/org/mozilla/xpcom/.done: $(XPIDL_GEN_DIR)/.done
@if test ! -d $(XPIDL_GEN_DIR)/org/mozilla/xpcom; then echo Creating $(XPIDL_GEN_DIR)/org/mozilla/xpcom/.done; rm -rf $(XPIDL_GEN_DIR)/org; mkdir $(XPIDL_GEN_DIR)/org; mkdir $(XPIDL_GEN_DIR)/org/mozilla; mkdir $(XPIDL_GEN_DIR)/org/mozilla/xpcom; fi
@touch $@
-$(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/.done: $(XPIDL_GEN_DIR)/org/mozilla/xpcom/.done
- @if test ! -d $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs; then echo Creating $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/.done; rm -rf $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs; mkdir $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs; fi
- @touch $@
-
-$(XPIDL_GEN_DIR)/org/mozilla/xpcom/.%.java.pp: %.idl $(JAVA_IDL_COMPILE) $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/.done
+$(XPIDL_GEN_DIR)/org/mozilla/xpcom/.%.java.pp: %.idl $(JAVA_IDL_COMPILE) $(XPIDL_GEN_DIR)/org/mozilla/xpcom/.done
$(REPORT_BUILD)
$(ELOG) $(JAVA_IDL_COMPILE) -m java -p org.mozilla.xpcom -w -I$(srcdir) -I$(IDL_DIR) -o $(XPIDL_GEN_DIR)/org/mozilla/xpcom/$* $(_VPATH_SRCS)
- $(ELOG) $(JAVA_IDL_COMPILE) -m javastub -p org.mozilla.xpcom -w -I$(srcdir) -I$(IDL_DIR) -o $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/$*_Stub $(_VPATH_SRCS)
@touch $@
@@ -1532,7 +1527,6 @@ export:: $(JAVA_DIST_DIR)
export:: $(JAVADEPFILES)
ifndef NO_DIST_INSTALL
$(INSTALL) $(IFLAGS1) $(XPIDL_GEN_DIR)/org/mozilla/xpcom/*.java $(JAVA_DIST_DIR)/org/mozilla/xpcom/
- $(INSTALL) $(IFLAGS1) $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/*.java $(JAVA_DIST_DIR)/org/mozilla/xpcom/stubs/
endif
endif # JAVA_XPIDLSRCS
diff --git a/mozilla/extensions/java/xpcom/Makefile.in b/mozilla/extensions/java/xpcom/Makefile.in
index e6dfe341f2f..292be06f649 100644
--- a/mozilla/extensions/java/xpcom/Makefile.in
+++ b/mozilla/extensions/java/xpcom/Makefile.in
@@ -69,7 +69,8 @@ CPPSRCS = \
JAVA_SRCS = \
XPCOM.java \
- XPCOMPrivate.java \
+ XPCOMJavaProxy.java \
+ XPCOMJavaProxyBase.java \
XPCOMException.java \
GeckoEmbed.java \
AppFileLocProvider.java \
diff --git a/mozilla/extensions/java/xpcom/XPCOMJavaProxy.java b/mozilla/extensions/java/xpcom/XPCOMJavaProxy.java
new file mode 100644
index 00000000000..c49e164a518
--- /dev/null
+++ b/mozilla/extensions/java/xpcom/XPCOMJavaProxy.java
@@ -0,0 +1,230 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Java XPCOM Bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Javier Pedemonte (jhpedemonte@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.xpcom;
+
+import java.lang.reflect.*;
+
+
+/**
+ * This class is used to pass XPCOM objects to Java functions. A
+ * java.lang.reflect.Proxy instance is created using the expected
+ * interface, and all calls to the proxy are forwarded to the XPCOM object.
+ */
+public final class XPCOMJavaProxy implements InvocationHandler {
+
+ /**
+ * Pointer to the XPCOM object for which we are a proxy.
+ */
+ protected long nativeXPCOMPtr;
+
+ /**
+ * Default constructor.
+ *
+ * @param aXPCOMInstance address of XPCOM object as a long
+ */
+ public XPCOMJavaProxy(long aXPCOMInstance)
+ {
+ nativeXPCOMPtr = aXPCOMInstance;
+ }
+
+ /**
+ * Creates a Proxy for the given XPCOM object.
+ *
+ * @param aInterface interface from which to create Proxy
+ * @param aXPCOMInstance address of XPCOM object as a long
+ *
+ * @return Proxy of given XPCOM object
+ */
+ protected static Object createProxy(Class aInterface, long aXPCOMInstance)
+ {
+ return Proxy.newProxyInstance(aInterface.getClassLoader(),
+ new Class[] { aInterface,
+ XPCOMJavaProxyBase.class },
+ new XPCOMJavaProxy(aXPCOMInstance));
+ }
+
+ /**
+ * All calls to the Java proxy are forwarded to this method. This method
+ * takes care of a few of the Object method calls; all other
+ * calls are forwarded to the XPCOM object.
+ *
+ * @param aProxy Proxy created by createProxy
+ * @param aMethod object that describes the called method
+ * @param aParams array of the arguments passed to the method
+ *
+ * @return return value as defined by given aMethod
+ */
+ public Object invoke(Object aProxy, Method aMethod, Object[] aParams)
+ throws Throwable
+ {
+ String methodName = aMethod.getName();
+
+ // Handle the three java.lang.Object methods that are passed to us.
+ if (aMethod.getDeclaringClass() == Object.class) {
+ if (methodName.equals("hashCode")) {
+ return proxyHashCode(aProxy);
+ }
+ if (methodName.equals("equals")) {
+ return proxyEquals(aProxy, aParams[0]);
+ }
+ if (methodName.equals("toString")) {
+ return proxyToString(aProxy);
+ }
+ System.err.println("WARNING: Unhandled Object method [" +
+ methodName + "]");
+ return null;
+ }
+
+ // Handle the 'finalize' method called during garbage collection
+ if (aMethod.getDeclaringClass() == XPCOMJavaProxyBase.class) {
+ if (methodName.equals("finalize")) {
+ finalizeProxy(aProxy);
+ } else {
+ System.err.println("WARNING: Unhandled XPCOMJavaProxyBase method [" +
+ methodName + "]");
+ }
+ return null;
+ }
+
+ // If not already handled, pass method calls to XPCOM object.
+ return callXPCOMMethod(aProxy, methodName, aParams);
+ }
+
+ /**
+ * Handles method calls of java.lang.Object.hashCode
+ *
+ * @param aProxy Proxy created by createProxy
+ *
+ * @return Integer object representing hash code of given object
+ *
+ * @see Object#hashCode()
+ */
+ protected static Integer proxyHashCode(Object aProxy)
+ {
+ return new Integer(System.identityHashCode(aProxy));
+ }
+
+ /**
+ * Handles method calls of java.lang.Object.equals
+ *
+ * @param aProxy Proxy created by createProxy
+ * @param aOther another object
+ *
+ * @return true if the given objects are the same;
+ * false otherwise
+ *
+ * @see Object#equals(Object)
+ */
+ protected static Boolean proxyEquals(Object aProxy, Object aOther)
+ {
+ return (aProxy == aOther ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Handles method calls of java.lang.Object.toString
+ *
+ * @param aProxy Proxy created by createProxy
+ *
+ * @return String representation of given object
+ *
+ * @see Object#toString()
+ */
+ protected static String proxyToString(Object aProxy)
+ {
+ return aProxy.getClass().getInterfaces()[0].getName() + '@' +
+ Integer.toHexString(aProxy.hashCode());
+ }
+
+ /**
+ * Indicates whether the given object is an XPCOMJavaProxy.
+ *
+ * @param aObject object to check
+ *
+ * @return true if the given object is an XPCOMJavaProxy;
+ * false otherwise
+ */
+ protected static boolean isXPCOMJavaProxy(Object aObject)
+ {
+ Class objectClass = aObject.getClass();
+ if (Proxy.isProxyClass(objectClass)) {
+ Class[] interfaces = objectClass.getInterfaces();
+ if (interfaces[interfaces.length-1] == XPCOMJavaProxyBase.class) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the XPCOM object that the given proxy references.
+ *
+ * @param aProxy Proxy created by createProxy
+ *
+ * @return address of XPCOM object as a long
+ */
+ protected static long getNativeXPCOMInstance(Object aProxy)
+ {
+ XPCOMJavaProxy proxy = (XPCOMJavaProxy) Proxy.getInvocationHandler(aProxy);
+ return proxy.nativeXPCOMPtr;
+ }
+
+ /**
+ * Calls the XPCOM object referenced by the proxy with the given method.
+ *
+ * @param aProxy Proxy created by createProxy
+ * @param aMethodName name of method that we want to call
+ * @param aParams array of params passed to method
+ *
+ * @return return value as defined by given method
+ *
+ * @exception XPCOMException if XPCOM method failed. Values of XPCOMException
+ * are defined by the method called.
+ */
+ protected static native
+ Object callXPCOMMethod(Object aProxy, String aMethodName, Object[] aParams);
+
+ /**
+ * Called when the proxy is garbage collected by the JVM. Allows us to clean
+ * up any references to the XPCOM object.
+ *
+ * @param aProxy reference to Proxy that is being garbage collected
+ */
+ protected static native
+ void finalizeProxy(Object aProxy);
+
+}
diff --git a/mozilla/extensions/java/xpcom/XPCOMJavaProxyBase.java b/mozilla/extensions/java/xpcom/XPCOMJavaProxyBase.java
new file mode 100644
index 00000000000..e2a823cdc0e
--- /dev/null
+++ b/mozilla/extensions/java/xpcom/XPCOMJavaProxyBase.java
@@ -0,0 +1,53 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Java XPCOM Bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Javier Pedemonte (jhpedemonte@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.xpcom;
+
+
+/**
+ * This interface forms the foundation of any XPCOMJavaProxy that is created.
+ * It allows us to handle any JVM calls to finalize when the Proxy
+ * is garbage collected.
+ */
+public interface XPCOMJavaProxyBase {
+
+ /**
+ * @see java.lang.Object#finalize()
+ */
+ void finalize() throws Throwable;
+
+}
diff --git a/mozilla/extensions/java/xpcom/build/Makefile.in b/mozilla/extensions/java/xpcom/build/Makefile.in
index ac047684b0d..3a606728a98 100644
--- a/mozilla/extensions/java/xpcom/build/Makefile.in
+++ b/mozilla/extensions/java/xpcom/build/Makefile.in
@@ -51,20 +51,19 @@ GARBAGE_DIRS += org
include $(topsrcdir)/config/rules.mk
+ifdef MOZ_DEBUG
+JAVAC_FLAGS = -g
+endif
+
org/mozilla/xpcom/.class_done:
@echo Compiling Java interface classes
- @$(JAVAC) -classpath . -d . $(JAVA_DIST_DIR)/org/mozilla/xpcom/*.java
+ @$(JAVAC) $(JAVAC_FLAGS) -classpath . -d . $(JAVA_DIST_DIR)/org/mozilla/xpcom/*.java
@touch $@
-org/mozilla/xpcom/stubs/.class_done:
- @echo Compiling Java stub classes
- @$(JAVAC) -classpath . -d . $(JAVA_DIST_DIR)/org/mozilla/xpcom/stubs/*.java
- @touch $@
-
-$(JARFILE): org/mozilla/xpcom/.class_done org/mozilla/xpcom/stubs/.class_done
+$(JARFILE): org/mozilla/xpcom/.class_done Makefile
$(JAR) cf $@ org
-$(JARFILE_SRC):
+$(JARFILE_SRC): $(JARFILE)
$(JAR) cf $@ -C $(JAVA_DIST_DIR) org
libs:: $(JARFILE) $(JARFILE_SRC)
diff --git a/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp b/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp
index 96962dfe9b1..d24bb55bc6b 100644
--- a/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp
+++ b/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp
@@ -47,48 +47,61 @@
#include "nsEnumeratorUtils.h"
#include "nsArray.h"
#include "nsAppFileLocProviderProxy.h"
+#include "nsIEventQueueService.h"
#define GECKO_NATIVE(func) Java_org_mozilla_xpcom_GeckoEmbed_##func
#define XPCOM_NATIVE(func) Java_org_mozilla_xpcom_XPCOM_##func
-#define XPCOMPRIVATE_NATIVE(func) Java_org_mozilla_xpcom_XPCOMPrivate_##func
+nsresult
+InitEmbedding_Impl(JNIEnv* env, jobject aMozBinDirectory,
+ jobject aAppFileLocProvider)
+{
+ nsresult rv;
+ if (!InitializeJavaGlobals(env))
+ return NS_ERROR_FAILURE;
+
+ // create an nsILocalFile from given java.io.File
+ nsCOMPtr directory;
+ if (aMozBinDirectory) {
+ rv = File_to_nsILocalFile(env, aMozBinDirectory, getter_AddRefs(directory));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // create nsAppFileLocProviderProxy from given Java object
+ nsAppFileLocProviderProxy* provider = nsnull;
+ if (aAppFileLocProvider) {
+ provider = new nsAppFileLocProviderProxy(env, aAppFileLocProvider);
+ if (!provider)
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // init Gecko
+ rv = NS_InitEmbedding(directory, provider);
+ if (provider) {
+ delete provider;
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // init Event Queue
+ nsCOMPtr
+ eventQService(do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = eventQService->CreateThreadEventQueue();
+
+ return rv;
+}
+
extern "C" JX_EXPORT void JNICALL
GECKO_NATIVE(initEmbedding) (JNIEnv* env, jclass, jobject aMozBinDirectory,
jobject aAppFileLocProvider)
{
- nsresult rv = NS_OK;
- if (!InitializeJavaGlobals(env)) {
- rv = NS_ERROR_FAILURE;
- } else {
- // Create an nsILocalFile from given java.io.File
- nsCOMPtr directory;
- if (aMozBinDirectory) {
- rv = File_to_nsILocalFile(env, aMozBinDirectory, getter_AddRefs(directory));
- }
+ nsresult rv = InitEmbedding_Impl(env, aMozBinDirectory, aAppFileLocProvider);
- if (NS_SUCCEEDED(rv)) {
- nsAppFileLocProviderProxy* provider = nsnull;
- if (aAppFileLocProvider) {
- provider = new nsAppFileLocProviderProxy(env, aAppFileLocProvider);
- if (!provider)
- rv = NS_ERROR_OUT_OF_MEMORY;
- }
-
- if (NS_SUCCEEDED(rv)) {
- rv = NS_InitEmbedding(directory, provider);
- if (provider) {
- delete provider;
- }
- if (NS_SUCCEEDED(rv)) {
- return;
- }
- }
- }
+ if (NS_FAILED(rv)) {
+ ThrowException(env, rv, "Failure in initEmbedding");
+ FreeJavaGlobals(env);
}
-
- ThrowException(env, rv, "Failure in initEmbedding");
- FreeJavaGlobals(env);
}
extern "C" JX_EXPORT void JNICALL
@@ -101,46 +114,61 @@ GECKO_NATIVE(termEmbedding) (JNIEnv *env, jclass)
FreeJavaGlobals(env);
}
+nsresult
+InitXPCOM_Impl(JNIEnv* env, jobject aMozBinDirectory,
+ jobject aAppFileLocProvider, jobject* aResult)
+{
+ nsresult rv;
+ if (!InitializeJavaGlobals(env))
+ return NS_ERROR_FAILURE;
+
+ // create an nsILocalFile from given java.io.File
+ nsCOMPtr directory;
+ if (aMozBinDirectory) {
+ rv = File_to_nsILocalFile(env, aMozBinDirectory, getter_AddRefs(directory));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // create nsAppFileLocProviderProxy from given Java object
+ nsAppFileLocProviderProxy* provider = nsnull;
+ if (aAppFileLocProvider) {
+ provider = new nsAppFileLocProviderProxy(env, aAppFileLocProvider);
+ if (!provider)
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // init XPCOM
+ nsIServiceManager* servMan = nsnull;
+ rv = NS_InitXPCOM2(&servMan, directory, provider);
+ if (provider) {
+ delete provider;
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // init Event Queue
+ nsCOMPtr
+ eventQService(do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = eventQService->CreateThreadEventQueue();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // create Java proxy for service manager returned by NS_InitXPCOM2
+ rv = CreateJavaProxy(env, servMan, NS_GET_IID(nsIServiceManager),
+ aResult);
+ NS_RELEASE(servMan); // Java proxy has owning ref
+
+ return rv;
+}
+
extern "C" JX_EXPORT jobject JNICALL
XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jclass, jobject aMozBinDirectory,
jobject aAppFileLocProvider)
{
- nsresult rv = NS_OK;
- if (!InitializeJavaGlobals(env)) {
- rv = NS_ERROR_FAILURE;
- } else {
- // Create an nsILocalFile from given java.io.File
- nsCOMPtr directory;
- if (aMozBinDirectory) {
- rv = File_to_nsILocalFile(env, aMozBinDirectory, getter_AddRefs(directory));
- }
-
- if (NS_SUCCEEDED(rv)) {
- nsAppFileLocProviderProxy* provider = nsnull;
- if (aAppFileLocProvider) {
- provider = new nsAppFileLocProviderProxy(env, aAppFileLocProvider);
- if (!provider)
- rv = NS_ERROR_OUT_OF_MEMORY;
- }
-
- if (NS_SUCCEEDED(rv)) {
- nsIServiceManager* servMan = nsnull;
- rv = NS_InitXPCOM2(&servMan, directory, provider);
- if (provider) {
- delete provider;
- }
-
- if (NS_SUCCEEDED(rv)) {
- jobject javaProxy;
- rv = CreateJavaProxy(env, servMan, NS_GET_IID(nsIServiceManager),
- &javaProxy);
- NS_RELEASE(servMan); // JavaXPCOMInstance has owning ref
- if (NS_SUCCEEDED(rv))
- return javaProxy;
- }
- }
- }
- }
+ jobject servMan;
+ nsresult rv = InitXPCOM_Impl(env, aMozBinDirectory, aAppFileLocProvider,
+ &servMan);
+ if (NS_SUCCEEDED(rv))
+ return servMan;
ThrowException(env, rv, "Failure in initXPCOM");
FreeJavaGlobals(env);
@@ -150,23 +178,24 @@ XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jclass, jobject aMozBinDirectory,
extern "C" JX_EXPORT void JNICALL
XPCOM_NATIVE(shutdownXPCOM) (JNIEnv *env, jclass, jobject aServMgr)
{
+ nsresult rv;
nsCOMPtr servMgr;
if (aServMgr) {
- // Find corresponding XPCOM object
- void* xpcomObj = gBindings->GetXPCOMObject(env, aServMgr);
- NS_ASSERTION(xpcomObj != nsnull, "Failed to get XPCOM obj for ServiceMgr.");
+ // Get native XPCOM instance
+ void* xpcom_obj;
+ rv = GetXPCOMInstFromProxy(env, aServMgr, &xpcom_obj);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "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.
- if (xpcomObj) {
- NS_ASSERTION(!IsXPTCStub(xpcomObj),
- "Expected JavaXPCOMInstance, but got nsJavaXPTCStub");
- servMgr = do_QueryInterface(((JavaXPCOMInstance*) xpcomObj)->GetInstance());
+ if (NS_SUCCEEDED(rv)) {
+ JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj);
+ servMgr = do_QueryInterface(inst->GetInstance());
}
}
- nsresult rv = NS_ShutdownXPCOM(servMgr);
+ rv = NS_ShutdownXPCOM(servMgr);
if (NS_FAILED(rv))
ThrowException(env, rv, "NS_ShutdownXPCOM failed");
@@ -261,239 +290,3 @@ XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jclass)
return nsnull;
}
-extern "C" JX_EXPORT void JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodVoid) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
-}
-
-extern "C" JX_EXPORT jboolean JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodBool) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return rc.z;
-}
-
-extern "C" JX_EXPORT jbooleanArray JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodBoolA) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return (jbooleanArray) rc.l;
-}
-
-extern "C" JX_EXPORT jbyte JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodByte) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return rc.b;
-}
-
-extern "C" JX_EXPORT jbyteArray JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodByteA) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return (jbyteArray) rc.l;
-}
-
-extern "C" JX_EXPORT jchar JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodChar) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return rc.c;
-}
-
-extern "C" JX_EXPORT jcharArray JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodCharA) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return (jcharArray) rc.l;
-}
-
-extern "C" JX_EXPORT jshort JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodShort) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return rc.s;
-}
-
-extern "C" JX_EXPORT jshortArray JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodShortA) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return (jshortArray) rc.l;
-}
-
-extern "C" JX_EXPORT jint JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodInt) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return rc.i;
-}
-
-extern "C" JX_EXPORT jintArray JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodIntA) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return (jintArray) rc.l;
-}
-
-extern "C" JX_EXPORT jlong JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodLong) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return rc.j;
-}
-
-extern "C" JX_EXPORT jlongArray JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodLongA) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return (jlongArray) rc.l;
-}
-
-extern "C" JX_EXPORT jfloat JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodFloat) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return rc.f;
-}
-
-extern "C" JX_EXPORT jfloatArray JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodFloatA) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return (jfloatArray) rc.l;
-}
-
-extern "C" JX_EXPORT jdouble JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodDouble) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return rc.d;
-}
-
-extern "C" JX_EXPORT jdoubleArray JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodDoubleA) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return (jdoubleArray) rc.l;
-}
-
-extern "C" JX_EXPORT jobject JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodObj) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return rc.l;
-}
-
-extern "C" JX_EXPORT jobjectArray JNICALL
-XPCOMPRIVATE_NATIVE(CallXPCOMMethodObjA) (JNIEnv *env, jclass that,
- jobject aJavaObject,
- jint aMethodIndex,
- jobjectArray aParams)
-{
- jvalue rc;
- CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
- return (jobjectArray) rc.l;
-}
-
-extern "C" JX_EXPORT void JNICALL
-XPCOMPRIVATE_NATIVE(FinalizeStub) (JNIEnv *env, jclass that,
- jobject aJavaObject)
-{
-#ifdef DEBUG_pedemonte
- jclass clazz = env->GetObjectClass(aJavaObject);
- jstring name = (jstring) env->CallObjectMethod(clazz, getNameMID);
- const char* javaObjectName = env->GetStringUTFChars(name, nsnull);
- LOG(("*** Finalize(java_obj=%s)\n", javaObjectName));
- env->ReleaseStringUTFChars(name, javaObjectName);
-#endif
-
- // Due to Java's garbage collection, this finalize statement may get called
- // after FreeJavaGlobals(). So check to make sure that everything is still
- // initialized.
- if (gJavaXPCOMInitialized) {
- void* obj = gBindings->GetXPCOMObject(env, aJavaObject);
- NS_ASSERTION(obj != nsnull, "No matching XPCOM obj in FinalizeStub");
-
- if (obj) {
- NS_ASSERTION(!IsXPTCStub(obj),
- "Expecting JavaXPCOMInstance, got nsJavaXPTCStub");
- gBindings->RemoveBinding(env, aJavaObject, nsnull);
- delete (JavaXPCOMInstance*) obj;
- }
- }
-}
-
diff --git a/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp b/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp
index e86fede9d85..fb7e25f5deb 100644
--- a/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp
+++ b/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp
@@ -45,6 +45,8 @@
#include "nsCRT.h"
#include "prmem.h"
+#define JAVAPROXY_NATIVE(func) Java_org_mozilla_xpcom_XPCOMJavaProxy_##func
+
static nsID nullID = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
@@ -328,13 +330,29 @@ SetupParams(JNIEnv *env, const jobject aParam, const nsXPTParamInfo &aParamInfo,
java_obj = (jobject) aParam;
} else { // 'inout'
if (aParam)
- java_obj = (jobject) env->GetObjectArrayElement((jobjectArray) aParam, 0);
+ java_obj = (jobject)
+ env->GetObjectArrayElement((jobjectArray) aParam, 0);
}
void* xpcom_obj;
if (java_obj) {
// Check if we already have a corresponding XPCOM object
- void* inst = gBindings->GetXPCOMObject(env, java_obj);
+ jboolean isProxy = env->CallStaticBooleanMethod(xpcomJavaProxyClass,
+ isXPCOMJavaProxyMID,
+ java_obj);
+ if (env->ExceptionCheck()) {
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ void* inst;
+ if (isProxy) {
+ rv = GetXPCOMInstFromProxy(env, java_obj, &inst);
+ if (NS_FAILED(rv))
+ break;
+ } else {
+ inst = gBindings->GetXPCOMObject(env, java_obj);
+ }
// Get IID for this param
nsID iid;
@@ -767,7 +785,7 @@ nsresult
SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
const nsXPTMethodInfo* aMethodInfo, nsIInterfaceInfo* aIInfo,
PRUint16 aMethodIndex, nsXPTCVariant* aDispatchParams,
- nsXPTCVariant &aVariant, jvalue &aResult)
+ nsXPTCVariant &aVariant, jobject* result)
{
nsresult rv = NS_OK;
const nsXPTType &type = aParamInfo.GetType();
@@ -776,54 +794,52 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
{
case nsXPTType::T_I8:
case nsXPTType::T_U8:
- aResult.b = aVariant.val.u8;
+ *result = env->NewObject(byteClass, byteInitMID, aVariant.val.u8);
break;
case nsXPTType::T_I16:
case nsXPTType::T_U16:
- aResult.s = aVariant.val.u16;
+ *result = env->NewObject(shortClass, shortInitMID, aVariant.val.u16);
break;
case nsXPTType::T_I32:
case nsXPTType::T_U32:
- aResult.i = aVariant.val.u32;
+ *result = env->NewObject(intClass, intInitMID, aVariant.val.u32);
break;
case nsXPTType::T_I64:
case nsXPTType::T_U64:
- aResult.j = aVariant.val.u64;
+ *result = env->NewObject(longClass, longInitMID, aVariant.val.u64);
break;
case nsXPTType::T_FLOAT:
- aResult.f = aVariant.val.f;
+ *result = env->NewObject(floatClass, floatInitMID, aVariant.val.f);
break;
case nsXPTType::T_DOUBLE:
- aResult.d = aVariant.val.d;
+ *result = env->NewObject(doubleClass, doubleInitMID, aVariant.val.d);
break;
case nsXPTType::T_BOOL:
- aResult.z = aVariant.val.b;
+ *result = env->NewObject(booleanClass, booleanInitMID, aVariant.val.b);
break;
case nsXPTType::T_CHAR:
- aResult.c = aVariant.val.c;
+ *result = env->NewObject(charClass, charInitMID, aVariant.val.c);
break;
case nsXPTType::T_WCHAR:
- aResult.c = aVariant.val.wc;
+ *result = env->NewObject(charClass, charInitMID, aVariant.val.wc);
break;
case nsXPTType::T_CHAR_STR:
{
if (aVariant.ptr) {
- aResult.l = env->NewStringUTF((const char*) aVariant.ptr);
- if (aResult.l == nsnull) {
+ *result = env->NewStringUTF((const char*) aVariant.ptr);
+ if (*result == nsnull) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
- } else {
- aResult.l = nsnull;
}
}
break;
@@ -832,13 +848,11 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
{
if (aVariant.ptr) {
PRUint32 length = nsCRT::strlen((const PRUnichar*) aVariant.ptr);
- aResult.l = env->NewString((const jchar*) aVariant.ptr, length);
- if (aResult.l == nsnull) {
+ *result = env->NewString((const jchar*) aVariant.ptr, length);
+ if (*result == nsnull) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
- } else {
- aResult.l = nsnull;
}
}
break;
@@ -849,15 +863,13 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
nsID* iid = (nsID*) aVariant.ptr;
char* iid_str = iid->ToString();
if (iid_str) {
- aResult.l = env->NewStringUTF(iid_str);
+ *result = env->NewStringUTF(iid_str);
}
- if (iid_str == nsnull || aResult.l == nsnull) {
+ if (iid_str == nsnull || *result == nsnull) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
PR_Free(iid_str);
- } else {
- aResult.l = nsnull;
}
}
break;
@@ -888,9 +900,7 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
NS_RELEASE(stub);
}
- aResult.l = java_obj;
- } else {
- aResult.l = nsnull;
+ *result = java_obj;
}
}
break;
@@ -900,13 +910,11 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
{
if (aVariant.ptr) {
nsString* str = (nsString*) aVariant.ptr;
- aResult.l = env->NewString(str->get(), str->Length());
- if (aResult.l == nsnull) {
+ *result = env->NewString(str->get(), str->Length());
+ if (*result == nsnull) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
- } else {
- aResult.l = nsnull;
}
}
break;
@@ -916,13 +924,11 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
{
if (aVariant.ptr) {
nsCString* str = (nsCString*) aVariant.ptr;
- aResult.l = env->NewStringUTF(str->get());
- if (aResult.l == nsnull) {
+ *result = env->NewStringUTF(str->get());
+ if (*result == nsnull) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
- } else {
- aResult.l = nsnull;
}
}
break;
@@ -930,7 +936,7 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
case nsXPTType::T_VOID:
// handle "void *" as an "int" in Java
LOG((" returns int (void*)"));
- aResult.i = (jint) aVariant.val.p;
+ *result = env->NewObject(intClass, intInitMID, aVariant.val.p);
break;
case nsXPTType::T_ARRAY:
@@ -945,31 +951,132 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
return rv;
}
-void
-CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
- jint aMethodIndex, jobjectArray aParams, jvalue &aResult)
+/**
+ * Given an interface info struct and a method name, returns the method info
+ * and index, if that method exists.
+ *
+ * Most method names are lower case. Unfortunately, the method names of some
+ * interfaces (such as nsIAppShell) start with a capital letter. This function
+ * will try all of the permutations.
+ */
+nsresult
+QueryMethodInfo(nsIInterfaceInfo* aIInfo, const char* aMethodName,
+ PRUint16* aMethodIndex, const nsXPTMethodInfo** aMethodInfo)
{
- // Find corresponding XPCOM object
- void* xpcomObj = gBindings->GetXPCOMObject(env, aJavaObject);
- if (xpcomObj == nsnull) {
- ThrowException(env, 0, "Failed to get matching XPCOM object");
- return;
+ // The common case is that the method name is lower case, so we check
+ // that first.
+ nsresult rv;
+ rv = aIInfo->GetMethodInfoForName(aMethodName, aMethodIndex, aMethodInfo);
+ if (NS_SUCCEEDED(rv))
+ return rv;
+
+ // If there is no method called , then maybe it is an
+ // 'attribute'. An 'attribute' will start with "get" or "set". But first,
+ // we check the length, in order to skip over method names that match exactly
+ // "get" or "set".
+ if (strlen(aMethodName) > 3) {
+ if (strncmp("get", aMethodName, 3) == 0) {
+ char* getterName = strdup(aMethodName + 3);
+ getterName[0] = tolower(getterName[0]);
+ rv = aIInfo->GetMethodInfoForName(getterName, aMethodIndex, aMethodInfo);
+ free(getterName);
+ } else if (strncmp("set", aMethodName, 3) == 0) {
+ char* setterName = strdup(aMethodName + 3);
+ setterName[0] = tolower(setterName[0]);
+ rv = aIInfo->GetMethodInfoForName(setterName, aMethodIndex, aMethodInfo);
+ if (NS_SUCCEEDED(rv)) {
+ // If this succeeded, GetMethodInfoForName will have returned the
+ // method info for the 'getter'. We want the 'setter', so increase
+ // method index by one ('setter' immediately follows the 'getter'),
+ // and get its method info.
+ (*aMethodIndex)++;
+ rv = aIInfo->GetMethodInfo(*aMethodIndex, aMethodInfo);
+ if (NS_SUCCEEDED(rv)) {
+ // Double check that this methodInfo matches the given method.
+ if (!(*aMethodInfo)->IsSetter() ||
+ strcmp(setterName, (*aMethodInfo)->name) != 0) {
+ rv = NS_ERROR_FAILURE;
+ }
+ }
+ }
+ free(setterName);
+ }
+ }
+ if (NS_SUCCEEDED(rv))
+ return rv;
+
+ // If we get here, then maybe the method name is capitalized.
+ char* methodName = strdup(aMethodName);
+ methodName[0] = toupper(methodName[0]);
+ rv = aIInfo->GetMethodInfoForName(methodName, aMethodIndex, aMethodInfo);
+ free(methodName);
+ if (NS_SUCCEEDED(rv))
+ return rv;
+
+ // If there is no method called , then maybe it is an
+ // 'attribute'.
+ if (strlen(aMethodName) > 3) {
+ if (strncmp("get", aMethodName, 3) == 0) {
+ char* getterName = strdup(aMethodName + 3);
+ rv = aIInfo->GetMethodInfoForName(getterName, aMethodIndex, aMethodInfo);
+ free(getterName);
+ } else if (strncmp("set", aMethodName, 3) == 0) {
+ char* setterName = strdup(aMethodName + 3);
+ rv = aIInfo->GetMethodInfoForName(setterName, aMethodIndex, aMethodInfo);
+ if (NS_SUCCEEDED(rv)) {
+ // If this succeeded, GetMethodInfoForName will have returned the
+ // method info for the 'getter'. We want the 'setter', so increase
+ // method index by one ('setter' immediately follows the 'getter'),
+ // and get its method info.
+ (*aMethodIndex)++;
+ rv = aIInfo->GetMethodInfo(*aMethodIndex, aMethodInfo);
+ if (NS_SUCCEEDED(rv)) {
+ // Double check that this methodInfo matches the given method.
+ if (!(*aMethodInfo)->IsSetter() ||
+ strcmp(setterName, (*aMethodInfo)->name) != 0) {
+ rv = NS_ERROR_FAILURE;
+ }
+ }
+ }
+ free(setterName);
+ }
}
- NS_ASSERTION(!IsXPTCStub(xpcomObj),
- "Expected JavaXPCOMInstance, but got nsJavaXPTCStub");
- JavaXPCOMInstance* inst = (JavaXPCOMInstance*) xpcomObj;
+ return rv;
+}
+
+/**
+ * org.mozilla.xpcom.XPCOMJavaProxy.callXPCOMMethod
+ */
+extern "C" JX_EXPORT jobject JNICALL
+JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
+ jstring aMethodName, jobjectArray aParams)
+{
+ nsresult rv;
+
+ // Get native XPCOM instance
+ void* xpcom_obj;
+ rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj);
+ if (NS_FAILED(rv)) {
+ ThrowException(env, 0, "Failed to get matching XPCOM object");
+ return nsnull;
+ }
+ JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj);
// Get method info
+ PRUint16 methodIndex;
const nsXPTMethodInfo* methodInfo;
nsIInterfaceInfo* iinfo = inst->InterfaceInfo();
- nsresult rv = iinfo->GetMethodInfo(aMethodIndex, &methodInfo);
+ const char* methodName = env->GetStringUTFChars(aMethodName, nsnull);
+ rv = QueryMethodInfo(iinfo, methodName, &methodIndex, &methodInfo);
+ env->ReleaseStringUTFChars(aMethodName, methodName);
+
if (NS_FAILED(rv)) {
- ThrowException(env, rv, "GetMethodInfo failed");
- return;
+ ThrowException(env, rv, "GetMethodInfoForName failed");
+ return nsnull;
}
-#ifdef DEBUG_pedemonte
+#ifdef DEBUG_JAVAXPCOM
const char* ifaceName;
iinfo->GetNameShared(&ifaceName);
LOG(("=> Calling %s::%s()\n", ifaceName, methodInfo->GetName()));
@@ -983,7 +1090,7 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
params = new nsXPTCVariant[paramCount];
if (!params) {
ThrowException(env, NS_ERROR_OUT_OF_MEMORY, "Can't create params array");
- return;
+ return nsnull;
}
for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
@@ -993,7 +1100,7 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
if (paramInfo.IsIn() && !paramInfo.IsDipper()) {
rv = SetupParams(env, env->GetObjectArrayElement(aParams, i), paramInfo,
- methodInfo, iinfo, aMethodIndex, params, params[i]);
+ methodInfo, iinfo, methodIndex, params, params[i]);
} else if (paramInfo.IsDipper()) {
LOG(("dipper"));
const nsXPTType &type = paramInfo.GetType();
@@ -1036,32 +1143,33 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
}
if (NS_FAILED(rv)) {
ThrowException(env, rv, "SetupParams failed");
- return;
+ return nsnull;
}
}
// Call the XPCOM method
nsresult invokeResult;
- invokeResult = XPTC_InvokeByIndex(inst->GetInstance(), aMethodIndex,
+ invokeResult = XPTC_InvokeByIndex(inst->GetInstance(), methodIndex,
paramCount, params);
// Clean up params
+ jobject result = nsnull;
for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
{
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i);
if (!paramInfo.IsRetval()) {
rv = FinalizeParams(env, env->GetObjectArrayElement(aParams, i),
- paramInfo, methodInfo, iinfo, aMethodIndex,
+ paramInfo, methodInfo, iinfo, methodIndex,
params, params[i]);
} else {
- rv = SetRetval(env, paramInfo, methodInfo, iinfo, aMethodIndex, params,
- params[i], aResult);
+ rv = SetRetval(env, paramInfo, methodInfo, iinfo, methodIndex, params,
+ params[i], &result);
}
}
if (NS_FAILED(rv)) {
ThrowException(env, rv, "FinalizeParams/SetRetval failed");
- return;
+ return nsnull;
}
// Normally, we would delete any created nsID object in the above loop.
@@ -1091,7 +1199,7 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
ThrowException(env, invokeResult, message.get());
}
- return;
+ return result;
}
nsresult
@@ -1102,8 +1210,6 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
if (!aResult)
return NS_ERROR_NULL_POINTER;
- jobject java_obj = nsnull;
-
nsCOMPtr iim = XPTI_GetInterfaceInfoManager();
NS_ASSERTION(iim != nsnull, "Failed to get InterfaceInfoManager");
if (!iim)
@@ -1125,19 +1231,19 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
rv = info->GetNameShared(&iface_name);
if (NS_SUCCEEDED(rv)) {
- // Create proxy class name
- nsCAutoString class_name("org/mozilla/xpcom/stubs/");
- class_name.AppendASCII(iface_name);
- class_name.AppendLiteral("_Stub");
+ jobject java_obj = nsnull;
- // Create java proxy object
- jclass clazz;
- clazz = env->FindClass(class_name.get());
- if (clazz) {
- jmethodID constructor = env->GetMethodID(clazz, "", "()V");
- if (constructor) {
- java_obj = env->NewObject(clazz, constructor);
- }
+ // Create proper Java interface name
+ nsCAutoString class_name("org/mozilla/xpcom/");
+ class_name.AppendASCII(iface_name);
+ jclass ifaceClass = env->FindClass(class_name.get());
+
+ if (ifaceClass) {
+ java_obj = env->CallStaticObjectMethod(xpcomJavaProxyClass,
+ createProxyMID, ifaceClass,
+ NS_REINTERPRET_CAST(jlong, inst));
+ if (env->ExceptionCheck())
+ java_obj = nsnull;
}
if (java_obj) {
@@ -1157,3 +1263,53 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
return rv;
}
+nsresult
+GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject, void** aResult)
+{
+ NS_PRECONDITION(aResult != nsnull, "null ptr");
+ if (!aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ long xpcom_obj = env->CallStaticIntMethod(xpcomJavaProxyClass,
+ getNativeXPCOMInstMID, aJavaObject);
+
+ if (!xpcom_obj || env->ExceptionCheck()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aResult = NS_REINTERPRET_CAST(void*, xpcom_obj);
+ return NS_OK;
+}
+
+/**
+ * org.mozilla.xpcom.XPCOMJavaProxy.finalizeProxy
+ */
+extern "C" JX_EXPORT void JNICALL
+JAVAPROXY_NATIVE(finalizeProxy) (JNIEnv *env, jclass that, jobject aJavaProxy)
+{
+#ifdef DEBUG_JAVAXPCOM
+ jstring string = nsnull;
+ string = (jstring) env->CallStaticObjectMethod(xpcomJavaProxyClass,
+ proxyToStringMID, aJavaProxy);
+ const char* javaObjectName = env->GetStringUTFChars(string, nsnull);
+ LOG(("*** Finalize(java_obj=%s)\n", javaObjectName));
+ env->ReleaseStringUTFChars(string, javaObjectName);
+#endif
+
+ // Due to Java's garbage collection, this finalize statement may get called
+ // after FreeJavaGlobals(). So check to make sure that everything is still
+ // initialized.
+ if (gJavaXPCOMLock) {
+ nsAutoLock lock(gJavaXPCOMLock);
+
+ // Get native XPCOM instance
+ void* xpcom_obj;
+ nsresult rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj);
+ if (NS_SUCCEEDED(rv)) {
+ JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj);
+ gBindings->RemoveBinding(env, aJavaProxy, nsnull);
+ delete inst;
+ }
+ }
+}
+
diff --git a/mozilla/extensions/java/xpcom/nsJavaWrapper.h b/mozilla/extensions/java/xpcom/nsJavaWrapper.h
index 19ba79b890b..74dc63fc575 100644
--- a/mozilla/extensions/java/xpcom/nsJavaWrapper.h
+++ b/mozilla/extensions/java/xpcom/nsJavaWrapper.h
@@ -42,11 +42,31 @@
#include "nsISupports.h"
-void CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
- jint aMethodIndex, jobjectArray aParams, jvalue &aResult);
-
-// Creates a Java proxy for the given XPCOM object.
+/**
+ * Creates a Java proxy around an XPCOM C++ object.
+ *
+ * @param env pointer to Java context
+ * @param aXPCOMObject XPCOM object to create proxy for
+ * @param aIID IID for XPCOM object
+ * @param aResult on exit, holds reference to Java proxy
+ *
+ * @return NS_OK if Java proxy was successfully created;
+ * any other value denotes an error condition.
+ */
nsresult CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject,
const nsIID& aIID, jobject* aResult);
+/**
+ * Returns the XPCOM object for which the given Java proxy was created.
+ *
+ * @param env pointer to Java context
+ * @param aJavaObject a Java proxy created by CreateJavaProxy()
+ * @param aResult on exit, holds pointer to XPCOM instance
+ *
+ * @return NS_OK if the XPCOM object was successfully retrieved;
+ * any other value denotes an error condition.
+ */
+nsresult GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject,
+ void** aResult);
+
#endif // _nsJavaWrapper_h_
diff --git a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp
index 561b9699887..6ebf759771b 100644
--- a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp
+++ b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp
@@ -47,26 +47,47 @@
/* Java JNI globals */
+jclass booleanClass = nsnull;
+jclass charClass = nsnull;
+jclass byteClass = nsnull;
+jclass shortClass = nsnull;
+jclass intClass = nsnull;
+jclass longClass = nsnull;
+jclass floatClass = nsnull;
+jclass doubleClass = nsnull;
jclass stringClass = nsnull;
jclass nsISupportsClass = nsnull;
jclass xpcomExceptionClass = nsnull;
+jclass xpcomJavaProxyClass = nsnull;
jmethodID hashCodeMID = nsnull;
jmethodID booleanValueMID = nsnull;
+jmethodID booleanInitMID = nsnull;
jmethodID charValueMID = nsnull;
+jmethodID charInitMID = nsnull;
jmethodID byteValueMID = nsnull;
+jmethodID byteInitMID = nsnull;
jmethodID shortValueMID = nsnull;
+jmethodID shortInitMID = nsnull;
jmethodID intValueMID = nsnull;
+jmethodID intInitMID = nsnull;
jmethodID longValueMID = nsnull;
+jmethodID longInitMID = nsnull;
jmethodID floatValueMID = nsnull;
+jmethodID floatInitMID = nsnull;
jmethodID doubleValueMID = nsnull;
+jmethodID doubleInitMID = nsnull;
+jmethodID createProxyMID = nsnull;
+jmethodID isXPCOMJavaProxyMID = nsnull;
+jmethodID getNativeXPCOMInstMID = nsnull;
-#ifdef DEBUG
+#ifdef DEBUG_JAVAXPCOM
jmethodID getNameMID = nsnull;
+jmethodID proxyToStringMID = nsnull;
#endif
nsJavaXPCOMBindings* gBindings = nsnull;
-PRBool gJavaXPCOMInitialized = PR_FALSE;
+PRLock* gJavaXPCOMLock = nsnull;
/**************************************
@@ -274,7 +295,7 @@ nsJavaXPCOMBindings::GetXPCOMObject(JNIEnv* env, jobject aJavaObject)
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
-#ifdef DEBUG_pedemonte
+#ifdef DEBUG_JAVAXPCOM
void* xpcomObjKey = nsnull;
if (IsXPTCStub(entry->mXPCOMInstance))
xpcomObjKey = GetXPTCStubAddr(entry->mXPCOMInstance);
@@ -331,7 +352,7 @@ nsJavaXPCOMBindings::GetJavaObject(JNIEnv* env, void* aXPCOMObject,
NS_RELEASE(xpcom_obj); // Owning ref passed on
}
-#ifdef DEBUG_pedemonte
+#ifdef DEBUG_JAVAXPCOM
if (*aResult) {
LOG(("< Get Java<->XPCOM binding (Java=0x%08x | XPCOM=0x%08x)\n",
env->CallIntMethod(*aResult, hashCodeMID), (int) aXPCOMObject));
@@ -348,96 +369,148 @@ nsJavaXPCOMBindings::GetJavaObject(JNIEnv* env, void* aXPCOMObject,
PRBool
InitializeJavaGlobals(JNIEnv *env)
{
- if (gJavaXPCOMInitialized)
+ if (gJavaXPCOMLock)
return PR_TRUE;
jclass clazz;
if (!(clazz = env->FindClass("java/lang/Object")) ||
!(hashCodeMID = env->GetMethodID(clazz, "hashCode","()I")))
{
+ NS_WARNING("Problem creating java.lang.Object globals");
goto init_error;
}
if (!(clazz = env->FindClass("java/lang/Boolean")) ||
- !(booleanValueMID = env->GetMethodID(clazz,"booleanValue","()Z")))
+ !(booleanClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(booleanValueMID = env->GetMethodID(clazz, "booleanValue", "()Z")) ||
+ !(booleanInitMID = env->GetMethodID(clazz, "", "(Z)V")))
{
+ NS_WARNING("Problem creating java.lang.Boolean globals");
goto init_error;
}
if (!(clazz = env->FindClass("java/lang/Character")) ||
- !(charValueMID = env->GetMethodID(clazz,"charValue","()C")))
+ !(charClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(charValueMID = env->GetMethodID(clazz, "charValue", "()C")) ||
+ !(charInitMID = env->GetMethodID(clazz, "", "(C)V")))
{
+ NS_WARNING("Problem creating java.lang.Character globals");
goto init_error;
}
if (!(clazz = env->FindClass("java/lang/Byte")) ||
- !(byteValueMID = env->GetMethodID(clazz,"byteValue","()B")))
+ !(byteClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(byteValueMID = env->GetMethodID(clazz, "byteValue", "()B")) ||
+ !(byteInitMID = env->GetMethodID(clazz, "", "(B)V")))
{
+ NS_WARNING("Problem creating java.lang.Byte globals");
goto init_error;
}
if (!(clazz = env->FindClass("java/lang/Short")) ||
- !(shortValueMID = env->GetMethodID(clazz,"shortValue","()S")))
+ !(shortClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(shortValueMID = env->GetMethodID(clazz, "shortValue", "()S")) ||
+ !(shortInitMID = env->GetMethodID(clazz, "", "(S)V")))
{
+ NS_WARNING("Problem creating java.lang.Short globals");
goto init_error;
}
if (!(clazz = env->FindClass("java/lang/Integer")) ||
- !(intValueMID = env->GetMethodID(clazz,"intValue","()I")))
+ !(intClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(intValueMID = env->GetMethodID(clazz, "intValue", "()I")) ||
+ !(intInitMID = env->GetMethodID(clazz, "", "(I)V")))
{
+ NS_WARNING("Problem creating java.lang.Integer globals");
goto init_error;
}
if (!(clazz = env->FindClass("java/lang/Long")) ||
- !(longValueMID = env->GetMethodID(clazz,"longValue","()J")))
+ !(longClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(longValueMID = env->GetMethodID(clazz, "longValue", "()J")) ||
+ !(longInitMID = env->GetMethodID(clazz, "", "(J)V")))
{
+ NS_WARNING("Problem creating java.lang.Long globals");
goto init_error;
}
if (!(clazz = env->FindClass("java/lang/Float")) ||
- !(floatValueMID = env->GetMethodID(clazz,"floatValue","()F")))
+ !(floatClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(floatValueMID = env->GetMethodID(clazz, "floatValue", "()F")) ||
+ !(floatInitMID = env->GetMethodID(clazz, "", "(F)V")))
{
+ NS_WARNING("Problem creating java.lang.Float globals");
goto init_error;
}
if (!(clazz = env->FindClass("java/lang/Double")) ||
- !(doubleValueMID = env->GetMethodID(clazz,"doubleValue","()D")))
+ !(doubleClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(doubleValueMID = env->GetMethodID(clazz, "doubleValue", "()D")) ||
+ !(doubleInitMID = env->GetMethodID(clazz, "", "(D)V")))
{
+ NS_WARNING("Problem creating java.lang.Double globals");
goto init_error;
}
if (!(clazz = env->FindClass("java/lang/String")) ||
!(stringClass = (jclass) env->NewGlobalRef(clazz)))
{
+ NS_WARNING("Problem creating java.lang.String globals");
goto init_error;
}
if (!(clazz = env->FindClass("org/mozilla/xpcom/nsISupports")) ||
!(nsISupportsClass = (jclass) env->NewGlobalRef(clazz)))
{
+ NS_WARNING("Problem creating org.mozilla.xpcom.nsISupports globals");
goto init_error;
}
if (!(clazz = env->FindClass("org/mozilla/xpcom/XPCOMException")) ||
!(xpcomExceptionClass = (jclass) env->NewGlobalRef(clazz)))
{
+ NS_WARNING("Problem creating org.mozilla.xpcom.XPCOMException globals");
goto init_error;
}
-#ifdef DEBUG
+ if (!(clazz = env->FindClass("org/mozilla/xpcom/XPCOMJavaProxy")) ||
+ !(xpcomJavaProxyClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(createProxyMID = env->GetStaticMethodID(clazz, "createProxy",
+ "(Ljava/lang/Class;J)Ljava/lang/Object;")) ||
+ !(isXPCOMJavaProxyMID = env->GetStaticMethodID(clazz, "isXPCOMJavaProxy",
+ "(Ljava/lang/Object;)Z")) ||
+ !(getNativeXPCOMInstMID = env->GetStaticMethodID(xpcomJavaProxyClass,
+ "getNativeXPCOMInstance",
+ "(Ljava/lang/Object;)J")))
+ {
+ NS_WARNING("Problem creating org.mozilla.xpcom.XPCOMJavaProxy globals");
+ goto init_error;
+ }
+
+#ifdef DEBUG_JAVAXPCOM
if (!(clazz = env->FindClass("java/lang/Class")) ||
!(getNameMID = env->GetMethodID(clazz, "getName","()Ljava/lang/String;")))
{
+ NS_WARNING("Problem creating java.lang.Class globals");
+ goto init_error;
+ }
+
+ if (!(proxyToStringMID = env->GetStaticMethodID(xpcomJavaProxyClass,
+ "proxyToString",
+ "(Ljava/lang/Object;)Ljava/lang/String;")))
+ {
+ NS_WARNING("Problem creating proxyToString global");
goto init_error;
}
#endif
gBindings = new nsJavaXPCOMBindings();
if (NS_FAILED(gBindings->Init())) {
+ NS_WARNING("Problem creating JavaXPCOMBindings");
goto init_error;
}
- gJavaXPCOMInitialized = PR_TRUE;
+ gJavaXPCOMLock = PR_NewLock();
return PR_TRUE;
init_error:
@@ -453,6 +526,40 @@ init_error:
void
FreeJavaGlobals(JNIEnv* env)
{
+ PR_Lock(gJavaXPCOMLock);
+
+ if (booleanClass) {
+ env->DeleteGlobalRef(booleanClass);
+ booleanClass = nsnull;
+ }
+ if (charClass) {
+ env->DeleteGlobalRef(charClass);
+ charClass = nsnull;
+ }
+ if (byteClass) {
+ env->DeleteGlobalRef(byteClass);
+ byteClass = nsnull;
+ }
+ if (shortClass) {
+ env->DeleteGlobalRef(shortClass);
+ shortClass = nsnull;
+ }
+ if (intClass) {
+ env->DeleteGlobalRef(intClass);
+ intClass = nsnull;
+ }
+ if (longClass) {
+ env->DeleteGlobalRef(longClass);
+ longClass = nsnull;
+ }
+ if (floatClass) {
+ env->DeleteGlobalRef(floatClass);
+ floatClass = nsnull;
+ }
+ if (doubleClass) {
+ env->DeleteGlobalRef(doubleClass);
+ doubleClass = nsnull;
+ }
if (stringClass) {
env->DeleteGlobalRef(stringClass);
stringClass = nsnull;
@@ -465,13 +572,19 @@ FreeJavaGlobals(JNIEnv* env)
env->DeleteGlobalRef(xpcomExceptionClass);
xpcomExceptionClass = nsnull;
}
+ if (xpcomJavaProxyClass) {
+ env->DeleteGlobalRef(xpcomJavaProxyClass);
+ xpcomJavaProxyClass = nsnull;
+ }
if (gBindings) {
delete gBindings;
gBindings = nsnull;
}
- gJavaXPCOMInitialized = PR_FALSE;
+ PR_Unlock(gJavaXPCOMLock);
+ PR_DestroyLock(gJavaXPCOMLock);
+ gJavaXPCOMLock = nsnull;
}
@@ -484,14 +597,18 @@ JavaXPCOMInstance::JavaXPCOMInstance(nsISupports* aInstance,
mIInfo(aIInfo)
{
NS_ADDREF(mInstance);
+ NS_ADDREF(mIInfo);
}
JavaXPCOMInstance::~JavaXPCOMInstance()
{
+ // Need to release these objects on the main thread.
nsCOMPtr eventQ;
nsresult rv = NS_GetMainEventQ(getter_AddRefs(eventQ));
- if (NS_SUCCEEDED(rv))
+ if (NS_SUCCEEDED(rv)) {
rv = NS_ProxyRelease(eventQ, mInstance);
+ rv += NS_ProxyRelease(eventQ, mIInfo);
+ }
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to release using NS_ProxyRelease");
}
diff --git a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h
index 4e3129fa1b8..74e2d9f52c1 100644
--- a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h
+++ b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h
@@ -43,8 +43,10 @@
#include "nsCOMPtr.h"
#include "nsString.h"
#include "pldhash.h"
+#include "nsAutoLock.h"
-#ifdef DEBUG_pedemonte
+//#define DEBUG_JAVAXPCOM
+#ifdef DEBUG_JAVAXPCOM
#define LOG(x) printf x
#else
#define LOG(x) /* nothing */
@@ -60,28 +62,49 @@
/*********************
* Java JNI globals
*********************/
+extern jclass booleanClass;
+extern jclass charClass;
+extern jclass byteClass;
+extern jclass shortClass;
+extern jclass intClass;
+extern jclass longClass;
+extern jclass floatClass;
+extern jclass doubleClass;
extern jclass stringClass;
extern jclass nsISupportsClass;
extern jclass xpcomExceptionClass;
+extern jclass xpcomJavaProxyClass;
extern jmethodID hashCodeMID;
extern jmethodID booleanValueMID;
+extern jmethodID booleanInitMID;
extern jmethodID charValueMID;
+extern jmethodID charInitMID;
extern jmethodID byteValueMID;
+extern jmethodID byteInitMID;
extern jmethodID shortValueMID;
+extern jmethodID shortInitMID;
extern jmethodID intValueMID;
+extern jmethodID intInitMID;
extern jmethodID longValueMID;
+extern jmethodID longInitMID;
extern jmethodID floatValueMID;
+extern jmethodID floatInitMID;
extern jmethodID doubleValueMID;
+extern jmethodID doubleInitMID;
+extern jmethodID createProxyMID;
+extern jmethodID isXPCOMJavaProxyMID;
+extern jmethodID getNativeXPCOMInstMID;
-#ifdef DEBUG
+#ifdef DEBUG_JAVAXPCOM
extern jmethodID getNameMID;
+extern jmethodID proxyToStringMID;
#endif
class nsJavaXPCOMBindings;
extern nsJavaXPCOMBindings* gBindings;
-extern PRBool gJavaXPCOMInitialized;
+extern PRLock* gJavaXPCOMLock;
PRBool InitializeJavaGlobals(JNIEnv *env);
void FreeJavaGlobals(JNIEnv* env);
@@ -100,8 +123,8 @@ public:
nsIInterfaceInfo* InterfaceInfo() { return mIInfo; }
private:
- nsISupports* mInstance;
- nsCOMPtr mIInfo;
+ nsISupports* mInstance;
+ nsIInterfaceInfo* mIInfo;
};
diff --git a/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp b/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp
index 0c2ac587d3a..11dfebfa790 100644
--- a/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp
+++ b/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp
@@ -53,13 +53,14 @@ nsJavaXPTCStub::nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject,
{
mJavaObject = aJavaEnv->NewGlobalRef(aJavaObject);
-#ifdef DEBUG_pedemonte
+#ifdef DEBUG_JAVAXPCOM
jstring name;
const char* javaObjectName = nsnull;
jclass clazz = mJavaEnv->GetObjectClass(mJavaObject);
if (clazz) {
name = (jstring) mJavaEnv->CallObjectMethod(clazz, getNameMID);
- javaObjectName = mJavaEnv->GetStringUTFChars(name, nsnull);
+ if (name)
+ javaObjectName = mJavaEnv->GetStringUTFChars(name, nsnull);
}
nsID* iid = nsnull;
@@ -75,7 +76,8 @@ nsJavaXPTCStub::nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject,
LOG(("+++ nsJavaXPTCStub(this=0x%08x java_obj=0x%08x %s iid=%s)\n", (int) this,
mJavaEnv->CallIntMethod(mJavaObject, hashCodeMID),
javaObjectName ? javaObjectName : "<-->", iid_str ? iid_str : "NULL"));
- mJavaEnv->ReleaseStringUTFChars(name, javaObjectName);
+ if (name)
+ mJavaEnv->ReleaseStringUTFChars(name, javaObjectName);
if (iid_str)
nsMemory::Free(iid_str);
#endif
@@ -83,19 +85,21 @@ nsJavaXPTCStub::nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject,
nsJavaXPTCStub::~nsJavaXPTCStub()
{
-#ifdef DEBUG_pedemonte
+#ifdef DEBUG_JAVAXPCOM
jstring name;
const char* javaObjectName = nsnull;
jclass clazz = mJavaEnv->GetObjectClass(mJavaObject);
if (clazz) {
name = (jstring) mJavaEnv->CallObjectMethod(clazz, getNameMID);
- javaObjectName = mJavaEnv->GetStringUTFChars(name, nsnull);
+ if (name)
+ javaObjectName = mJavaEnv->GetStringUTFChars(name, nsnull);
}
LOG(("--- ~nsJavaXPTCStub(this=0x%08x java_obj=0x%08x %s)\n", (int) this,
mJavaEnv->CallIntMethod(mJavaObject, hashCodeMID),
javaObjectName ? javaObjectName : "<-->"));
- mJavaEnv->ReleaseStringUTFChars(name, javaObjectName);
+ if (name)
+ mJavaEnv->ReleaseStringUTFChars(name, javaObjectName);
#endif
if (!mMaster) {
@@ -309,7 +313,7 @@ nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex,
const nsXPTMethodInfo *aMethodInfo,
nsXPTCMiniVariant *aParams)
{
-#ifdef DEBUG_pedemonte
+#ifdef DEBUG_JAVAXPCOM
const char* ifaceName;
mIInfo->GetNameShared(&ifaceName);
LOG(("nsJavaXPTCStub::CallMethod [%s::%s]\n", ifaceName, aMethodInfo->GetName()));
@@ -1346,7 +1350,23 @@ 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 = gBindings->GetXPCOMObject(mJavaEnv, java_obj);
+ jboolean isProxy;
+ isProxy = mJavaEnv->CallStaticBooleanMethod(xpcomJavaProxyClass,
+ isXPCOMJavaProxyMID,
+ java_obj);
+ if (mJavaEnv->ExceptionCheck()) {
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ void* inst;
+ if (isProxy) {
+ rv = GetXPCOMInstFromProxy(mJavaEnv, java_obj, &inst);
+ if (NS_FAILED(rv))
+ break;
+ } else {
+ inst = gBindings->GetXPCOMObject(mJavaEnv, java_obj);
+ }
// Get IID for this param
nsID iid;
diff --git a/mozilla/extensions/java/xpcom/tools/xpidl/Makefile.in b/mozilla/extensions/java/xpcom/tools/xpidl/Makefile.in
index 98ef63bb683..f5bdfe5e618 100644
--- a/mozilla/extensions/java/xpcom/tools/xpidl/Makefile.in
+++ b/mozilla/extensions/java/xpcom/tools/xpidl/Makefile.in
@@ -61,7 +61,6 @@ CSRCS = \
xpidl_typelib.c \
xpidl_doc.c \
xpidl_java.c \
- xpidl_javastub.c \
$(NULL)
SDK_BINARY = \
diff --git a/mozilla/extensions/java/xpcom/tools/xpidl/xpidl.c b/mozilla/extensions/java/xpcom/tools/xpidl/xpidl.c
index badddced60d..39be2e4d85f 100644
--- a/mozilla/extensions/java/xpcom/tools/xpidl/xpidl.c
+++ b/mozilla/extensions/java/xpcom/tools/xpidl/xpidl.c
@@ -46,7 +46,6 @@ static ModeData modes[] = {
{"typelib", "Generate XPConnect typelib", "xpt", xpidl_typelib_dispatch},
{"doc", "Generate HTML documentation", "html", xpidl_doc_dispatch},
{"java", "Generate Java interface", "java", xpidl_java_dispatch},
- {"javastub","Generate Java Stub", "java", xpidl_javastub_dispatch},
{0, 0, 0, 0}
};
diff --git a/mozilla/extensions/java/xpcom/tools/xpidl/xpidl.h b/mozilla/extensions/java/xpcom/tools/xpidl/xpidl.h
index fbc990dcb06..99f9ce2f177 100644
--- a/mozilla/extensions/java/xpcom/tools/xpidl/xpidl.h
+++ b/mozilla/extensions/java/xpcom/tools/xpidl/xpidl.h
@@ -112,7 +112,6 @@ extern backend *xpidl_header_dispatch(void);
extern backend *xpidl_typelib_dispatch(void);
extern backend *xpidl_doc_dispatch(void);
extern backend *xpidl_java_dispatch(void);
-extern backend *xpidl_javastub_dispatch(void);
typedef struct ModeData {
char *mode;
diff --git a/mozilla/extensions/java/xpcom/tools/xpidl/xpidl_idl.c b/mozilla/extensions/java/xpcom/tools/xpidl/xpidl_idl.c
index e7625758a1f..98db3691a59 100644
--- a/mozilla/extensions/java/xpcom/tools/xpidl/xpidl_idl.c
+++ b/mozilla/extensions/java/xpcom/tools/xpidl/xpidl_idl.c
@@ -760,8 +760,7 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
}
/* don't create/open file here for Java */
- if (strcmp(mode->mode, "java") == 0 ||
- strcmp(mode->mode, "javastub") == 0)
+ if (strcmp(mode->mode, "java") == 0)
{
state.filename = real_outname;
} else {
@@ -785,8 +784,7 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
if (emitter->emit_epilog)
emitter->emit_epilog(&state);
- if (strcmp(mode->mode, "java") != 0 &&
- strcmp(mode->mode, "javastub") != 0)
+ if (strcmp(mode->mode, "java") != 0)
{
if (state.file != stdout)
fclose(state.file);