resolve.cc (ncode): Set args_raw_size.
authorTom Tromey <tromey@cygnus.com>
Wed, 16 Feb 2000 00:07:34 +0000 (00:07 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Wed, 16 Feb 2000 00:07:34 +0000 (00:07 +0000)
* 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.

From-SVN: r31995

libjava/ChangeLog
libjava/include/java-interp.h
libjava/jni.cc
libjava/resolve.cc

index 30b8ee9..2f27224 100644 (file)
@@ -1,5 +1,15 @@
 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.
+
        * jni.cc (mangled_name): Skip leading `(' in signature.
 
        * jni.cc (add_char): Added missing `else'.
index 8111d40..a0ca347 100644 (file)
@@ -76,6 +76,9 @@ protected:
 
   // 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 @@ class _Jv_InterpMethod : public _Jv_MethodBase
   int              code_length;
 
   _Jv_ushort       exc_count;
-  _Jv_ushort       args_raw_size;
 
   unsigned char* bytecode () 
   {
@@ -175,6 +177,12 @@ class _Jv_JNIMethod : public _Jv_MethodBase
   // 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 0d78b32..26f3b04 100644 (file)
@@ -1323,7 +1323,7 @@ mangled_name (jclass klass, _Jv_Utf8Const *func_name,
 // 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 @@ _Jv_JNIMethod::call (ffi_cif *cif, void *ret, ffi_raw *args, void *__this)
        }
     }
 
+  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 0d39de1..634c08f 100644 (file)
@@ -941,7 +941,8 @@ init_cif (_Jv_Utf8Const* signature,
          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 @@ init_cif (_Jv_Utf8Const* signature,
                    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 @@ _Jv_InterpMethod::ncode ()
            arg_count,
            staticp,
            &closure->cif,
-           &closure->arg_types[0]);
+           &closure->arg_types[0],
+           NULL);
 
   ffi_closure_fun fun;
 
@@ -1064,14 +1069,37 @@ _Jv_JNIMethod::ncode ()
     (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 @@ _Jv_JNIMethod::ncode ()
                        fun,
                        (void*) this);
 
-  self->ncode = (void*)closure;
+  self->ncode = (void *) closure;
   return self->ncode;
 }
 
@@ -1107,7 +1135,8 @@ _Jv_BuildResolvedMethod (_Jv_Method* method,
                arg_count,
                staticp,
                &result->cif,
-               &result->arg_types[0]);
+               &result->arg_types[0],
+               NULL);
 
   result->vtable_index        = vtable_index;
   result->method              = method;