This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
JNI/Win32 Patch #3: Change _Jv_LookupJNIMethod( ) for "stdcall" exportvariations on Win32
- From: Ranjit Mathew <rmathew at hotmail dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Sun, 08 Dec 2002 22:29:13 +0530
- Subject: JNI/Win32 Patch #3: Change _Jv_LookupJNIMethod( ) for "stdcall" exportvariations on Win32
Hi,
This patch proposes to change _Jv_LookupJNIMethod( ) in jni.cc
to accommodate the vagaries of exported symbols for JNI functions
that use the "stdcall" calling convention on Win32.
Please note that this would break the compiler generated stubs
for making a JNI call, for which I'll soon submit a separate
patch.
I've had to increase the size of the "buf" buffer in this
method to accommodate the '_', '@' and arguments size (1 + 1 + 10)
used by Win32 compilers to decorate "stdcall" functions. (For
example, "_fooBar@12" for MSVC.)
I store the leading '_' in buf[0] and consequently every offset
used in the previous incarnation of this function had to be
increased by one, even for non-Win32 platforms.
Finally, sorry Tom, but I didn't change it all the way to the
thread-safe form suggested by you (taking an "out" parameter,
rather than returning a value) - I wasn't too sure of how to
do it and it is too close to the GCC 3.3 branch. :-(
ChangeLog:
2002-12-08 Ranjit Mathew <rmathew@hotmail.com>
* jni.cc (_Jv_LookupJNIMethod): Modified to accept the
size of the arguments for a JNI function. For Win32,
modified to search for all forms of possible exported
names of an "stdcall" JNI function.
(_Jv_JNIMethod::call): Modified to calculate the size
of the arguments passed to a JNI function and pass it
to _Jv_LookupJNIMethod( ).
-------------------------------- 8< --------------------------------
--- jni.cc 2002-11-08 08:28:50.000000000 +0530
+++ jni.cc 2002-12-08 20:26:04.000000000 +0530
@@ -11,4 +11,5 @@
#include <config.h>
+#include <stdio.h>
#include <stddef.h>
#include <string.h>
@@ -2023,7 +2025,7 @@
extern "C" void *
_Jv_LookupJNIMethod (jclass klass, _Jv_Utf8Const *name,
- _Jv_Utf8Const *signature)
+ _Jv_Utf8Const *signature, int args_size)
{
- char buf[10 + 6 * (name->length + signature->length)];
+ char buf[10 + 6 * (name->length + signature->length) + 12];
int long_start;
void *function;
@@ -2045,17 +2047,75 @@
// If there was no override, then look in the symbol table.
- mangled_name (klass, name, signature, buf, &long_start);
- char c = buf[long_start];
- buf[long_start] = '\0';
- function = _Jv_FindSymbolInExecutable (buf);
+ buf[0] = '_';
+ mangled_name (klass, name, signature, buf + 1, &long_start);
+ char c = buf[long_start + 1];
+ buf[long_start + 1] = '\0';
+
+ function = _Jv_FindSymbolInExecutable (buf + 1);
+#ifdef WIN32
+ // On Win32, we use the "stdcall" calling convention (see JNICALL
+ // in jni.h).
+ //
+ // For a function named 'fooBar' that takes 'nn' bytes as arguments,
+ // by default, MinGW GCC exports it as 'fooBar@nn', MSVC exports
+ // it as '_fooBar@nn' and BCC exports it as 'fooBar'. We try to
+ // take care of all of these variations.
+
+ char asz_buf[12]; /* '@' + '2147483647' (32-bit INT_MAX) + '\0' */
+ char long_nm_sv[11]; /* Ditto, except for the '\0'. */
+
if (function == NULL)
{
- buf[long_start] = c;
+ // We have tried searching for the 'fooBar' form (BCC).
+ // Now try the others.
+
+ // First, save the part of the long name that will be damaged
+ // by appending '@nn'.
+ memcpy (long_nm_sv, (buf + long_start + 1 + 1), sizeof (long_nm_sv));
+
+ sprintf (asz_buf, "@%d", args_size);
+ strcat (buf, asz_buf);
+
+ // Search for the '_fooBar@xx' form (MSVC).
function = _Jv_FindSymbolInExecutable (buf);
+
+ if ( function == NULL)
+ {
+ // Search for the 'fooBar@xx' form (MinGW GCC).
+ function = _Jv_FindSymbolInExecutable (buf + 1);
+ }
+ }
+#else /* WIN32 */
+ args_size; /* Dummy statement to avoid unused parameter warning */
+#endif /* ! WIN32 */
+
+ if (function == NULL)
+ {
+ buf[long_start + 1] = c;
+#ifdef WIN32
+ // Restore the part of the long name that was damaged by
+ // appending the '@nn'.
+ memcpy ((buf + long_start + 1 + 1), long_nm_sv, sizeof (long_nm_sv));
+#endif /* WIN32 */
+ function = _Jv_FindSymbolInExecutable (buf + 1);
if (function == NULL)
{
- jstring str = JvNewStringUTF (name->data);
- throw new java::lang::UnsatisfiedLinkError (str);
- }
+#ifdef WIN32
+ strcat (buf, asz_buf);
+
+ function = _Jv_FindSymbolInExecutable (buf);
+
+ if (function == NULL)
+ {
+ function = _Jv_FindSymbolInExecutable (buf + 1);
+ }
+
+ if (function == NULL)
+#endif /* WIN32 */
+ {
+ jstring str = JvNewStringUTF (name->data);
+ throw new java::lang::UnsatisfiedLinkError (str);
+ }
+ }
}
@@ -2087,7 +2147,15 @@
JvSynchronize sync (global_ref_table);
if (_this->function == NULL)
- _this->function = _Jv_LookupJNIMethod (_this->defining_class,
- _this->self->name,
- _this->self->signature);
+ {
+ int args_size = sizeof (JNIEnv *) + _this->args_raw_size;
+
+ if (_this->self->accflags & java::lang::reflect::Modifier::STATIC)
+ args_size += sizeof (_this->defining_class);
+
+ _this->function = _Jv_LookupJNIMethod (_this->defining_class,
+ _this->self->name,
+ _this->self->signature,
+ args_size);
+ }
}
-------------------------------- 8< --------------------------------
Sincerely Yours,
Ranjit.
--
Ranjit Mathew Email: rmathew AT hotmail DOT com
Bangalore,
INDIA. Web: http://ranjitmathew.tripod.com/