From a82244f012d6c61bc27634963b5e7c25c72a16ed Mon Sep 17 00:00:00 2001 From: tromey Date: Wed, 16 Feb 2000 00:07:34 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31995 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/ChangeLog | 10 ++++++++++ libjava/include/java-interp.h | 10 +++++++++- libjava/jni.cc | 21 ++++++++++++++++++--- libjava/resolve.cc | 39 ++++++++++++++++++++++++++++++++++----- 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 30b8ee9..2f27224 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,5 +1,15 @@ 2000-02-15 Tom Tromey + * 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'. diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h index 8111d40..a0ca347 100644 --- a/libjava/include/java-interp.h +++ b/libjava/include/java-interp.h @@ -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 *); diff --git a/libjava/jni.cc b/libjava/jni.cc index 0d78b32..26f3b04 100644 --- a/libjava/jni.cc +++ b/libjava/jni.cc @@ -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 { diff --git a/libjava/resolve.cc b/libjava/resolve.cc index 0d39de1..634c08f 100644 --- a/libjava/resolve.cc +++ b/libjava/resolve.cc @@ -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; -- 2.7.4