This is the mail archive of the
java-patches@sourceware.cygnus.com
mailing list for the Java project.
Patch: missing arguments to JNI calls
- To: Java Patch List <java-patches at sourceware dot cygnus dot com>
- Subject: Patch: missing arguments to JNI calls
- From: Tom Tromey <tromey at cygnus dot com>
- Date: 15 Feb 2000 17:07:01 -0700
- Reply-To: tromey at cygnus dot com
This patch changes the JNI implementation to pass required (but
previously missing) arguments to JNI functions. With this change, JNI
native functions with arguments work correctly.
I'm checking this in.
2000-02-15 Tom Tromey <tromey@cygnus.com>
* resolve.cc (ncode): Set args_raw_size. Compute jni_cif and
jni_arg_types.
(init_cif): Added `rtype_p' argument.
* include/java-interp.h (class _Jv_MethodBase): Added
args_raw_size.
(class _Jv_InterpMethod): Removed args_raw_size.
(class _Jv_JNIMethod): Added jni_cif and jni_arg_types fields.
* jni.cc (call): Pass JNIEnv and (for static methods only) the
class pointer as well as the ordinary arguments.
Tom
Index: jni.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/jni.cc,v
retrieving revision 1.16
diff -u -r1.16 jni.cc
--- jni.cc 2000/02/15 22:59:23 1.16
+++ jni.cc 2000/02/16 00:03:43
@@ -1323,7 +1323,7 @@
// This function is the stub which is used to turn an ordinary (CNI)
// method call into a JNI call.
void
-_Jv_JNIMethod::call (ffi_cif *cif, void *ret, ffi_raw *args, void *__this)
+_Jv_JNIMethod::call (ffi_cif *, void *ret, ffi_raw *args, void *__this)
{
_Jv_JNIMethod* _this = (_Jv_JNIMethod *) __this;
@@ -1372,9 +1372,24 @@
}
}
+ JvAssert (_this->args_raw_size % sizeof (ffi_raw) == 0);
+ ffi_raw real_args[2 + _this->args_raw_size / sizeof (ffi_raw)];
+ int offset = 0;
+
+ // First argument is always the environment pointer.
+ real_args[offset++].ptr = &env;
+
+ // For a static method, we pass in the Class. For non-static
+ // methods, the `this' argument is already handled.
+ if ((_this->self->accflags & java::lang::reflect::Modifier::STATIC))
+ real_args[offset++].ptr = _this->defining_class;
+
+ // Copy over passed-in arguments.
+ memcpy (&real_args[offset], args, _this->args_raw_size);
+
// The actual call to the JNI function.
- // FIXME: if this is a static function we must include the class!
- ffi_raw_call (cif, (void (*) (...)) _this->function, ret, args);
+ ffi_raw_call (&_this->jni_cif, (void (*) (...)) _this->function,
+ ret, real_args);
do
{
Index: resolve.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/resolve.cc,v
retrieving revision 1.13
diff -u -r1.13 resolve.cc
--- resolve.cc 2000/02/10 17:15:22 1.13
+++ resolve.cc 2000/02/16 00:04:00
@@ -941,7 +941,8 @@
int arg_count,
jboolean staticp,
ffi_cif *cif,
- ffi_type **arg_types)
+ ffi_type **arg_types,
+ ffi_type **rtype_p)
{
unsigned char *ptr = (unsigned char*) signature->data;
@@ -983,6 +984,9 @@
arg_count, rtype, arg_types) != FFI_OK)
throw_internal_error ("ffi_prep_cif failed");
+ if (rtype_p != NULL)
+ *rtype_p = rtype;
+
return item_count;
}
@@ -1019,7 +1023,8 @@
arg_count,
staticp,
&closure->cif,
- &closure->arg_types[0]);
+ &closure->arg_types[0],
+ NULL);
ffi_closure_fun fun;
@@ -1064,14 +1069,37 @@
(ncode_closure*)_Jv_AllocBytesChecked (sizeof (ncode_closure)
+ arg_count * sizeof (ffi_type*));
+ ffi_type *rtype;
init_cif (self->signature,
arg_count,
staticp,
&closure->cif,
- &closure->arg_types[0]);
+ &closure->arg_types[0],
+ &rtype);
ffi_closure_fun fun;
+ args_raw_size = ffi_raw_size (&closure->cif);
+
+ // Initialize the argument types and CIF that represent the actual
+ // underlying JNI function.
+ int extra_args = 1;
+ if ((self->accflags & Modifier::STATIC))
+ ++extra_args;
+ jni_arg_types = (ffi_type **) _Jv_Malloc ((extra_args + arg_count)
+ * sizeof (ffi_type *));
+ int offset = 0;
+ jni_arg_types[offset++] = &ffi_type_pointer;
+ if ((self->accflags & Modifier::STATIC))
+ jni_arg_types[offset++] = &ffi_type_pointer;
+ memcpy (&jni_arg_types[offset], &closure->arg_types[0],
+ arg_count * sizeof (ffi_type *));
+
+ if (ffi_prep_cif (&jni_cif, FFI_DEFAULT_ABI,
+ extra_args + arg_count, rtype,
+ jni_arg_types) != FFI_OK)
+ throw_internal_error ("ffi_prep_cif failed for JNI function");
+
JvAssert ((self->accflags & Modifier::NATIVE) != 0);
// FIXME: for now we assume that all native methods for
@@ -1083,7 +1111,7 @@
fun,
(void*) this);
- self->ncode = (void*)closure;
+ self->ncode = (void *) closure;
return self->ncode;
}
@@ -1107,7 +1135,8 @@
arg_count,
staticp,
&result->cif,
- &result->arg_types[0]);
+ &result->arg_types[0],
+ NULL);
result->vtable_index = vtable_index;
result->method = method;
Index: include/java-interp.h
===================================================================
RCS file: /cvs/java/libgcj/libjava/include/java-interp.h,v
retrieving revision 1.7
diff -u -r1.7 java-interp.h
--- java-interp.h 2000/02/07 21:17:30 1.7
+++ java-interp.h 2000/02/16 00:04:00
@@ -76,6 +76,9 @@
// The method description.
_Jv_Method *self;
+
+ // Size of raw arguments.
+ _Jv_ushort args_raw_size;
};
class _Jv_InterpMethod : public _Jv_MethodBase
@@ -85,7 +88,6 @@
int code_length;
_Jv_ushort exc_count;
- _Jv_ushort args_raw_size;
unsigned char* bytecode ()
{
@@ -174,6 +176,12 @@
// The underlying function. If NULL we have to look for the
// function.
void *function;
+
+ // This is the CIF used by the JNI function.
+ ffi_cif jni_cif;
+
+ // These are the argument types used by the JNI function.
+ ffi_type **jni_arg_types;
// This function is used when making a JNI call from the interpreter.
static void call (ffi_cif *, void *, ffi_raw *, void *);