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