This is the mail archive of the java-patches@sourceware.cygnus.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch: missing arguments to JNI calls


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]