Commit 0da021f5 by Tom Tromey Committed by Tom Tromey

re PR libgcj/11951 (natMethod.cc (_Jv_CallAnyMethodA) should clear ffi_result before ffi_call)

	PR libgcj/11951:
	* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Returns
	void.  Throw VirtualMachineError if ffi fails.  Initialize return
	value.  Added is_jni_call argument; only wrap exception if not a
	JNI call.  Use descriptive message if operation not supported.
	(_Jv_GetTypesFromSignature): Use declaring class' loader to find
	array class.
	* include/jvm.h (_Jv_CallAnyMethodA): Updated declaration.
	* jni.cc (_Jv_JNI_CallAnyMethodV): Updated for new form of
	_Jv_CallAnyMethodA.
	(_Jv_JNI_CallAnyMethodA): Likewise.
	(_Jv_JNI_CallAnyVoidMethodV): Likewise.
	(_Jv_JNI_CallAnyVoidMethodA): Likewise.

From-SVN: r70544
parent cd069836
2003-08-18 Tom Tromey <tromey@redhat.com>
PR libgcj/11951:
* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Returns
void. Throw VirtualMachineError if ffi fails. Initialize return
value. Added is_jni_call argument; only wrap exception if not a
JNI call. Use descriptive message if operation not supported.
(_Jv_GetTypesFromSignature): Use declaring class' loader to find
array class.
* include/jvm.h (_Jv_CallAnyMethodA): Updated declaration.
* jni.cc (_Jv_JNI_CallAnyMethodV): Updated for new form of
_Jv_CallAnyMethodA.
(_Jv_JNI_CallAnyMethodA): Likewise.
(_Jv_JNI_CallAnyVoidMethodV): Likewise.
(_Jv_JNI_CallAnyVoidMethodA): Likewise.
2003-08-13 Tom Tromey <tromey@redhat.com> 2003-08-13 Tom Tromey <tromey@redhat.com>
* gij.cc (help): Document -? and -X. * gij.cc (help): Document -? and -X.
......
...@@ -335,13 +335,14 @@ extern jobject _Jv_CallAnyMethodA (jobject obj, jclass return_type, ...@@ -335,13 +335,14 @@ extern jobject _Jv_CallAnyMethodA (jobject obj, jclass return_type,
jobjectArray args); jobjectArray args);
union jvalue; union jvalue;
extern jthrowable _Jv_CallAnyMethodA (jobject obj, extern void _Jv_CallAnyMethodA (jobject obj,
jclass return_type, jclass return_type,
jmethodID meth, jmethodID meth,
jboolean is_constructor, jboolean is_constructor,
JArray<jclass> *parameter_types, JArray<jclass> *parameter_types,
jvalue *args, jvalue *args,
jvalue *result); jvalue *result,
jboolean is_jni_call = true);
extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims) extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
__attribute__((__malloc__)); __attribute__((__malloc__));
......
...@@ -31,6 +31,7 @@ details. */ ...@@ -31,6 +31,7 @@ details. */
#include <java/lang/IllegalArgumentException.h> #include <java/lang/IllegalArgumentException.h>
#include <java/lang/NullPointerException.h> #include <java/lang/NullPointerException.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h> #include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/VirtualMachineError.h>
#include <java/lang/Class.h> #include <java/lang/Class.h>
#include <gcj/method.h> #include <gcj/method.h>
#include <gnu/gcj/RawData.h> #include <gnu/gcj/RawData.h>
...@@ -309,9 +310,8 @@ _Jv_GetTypesFromSignature (jmethodID method, ...@@ -309,9 +310,8 @@ _Jv_GetTypesFromSignature (jmethodID method,
break; break;
} }
// FIXME: 2'nd argument should be "current loader"
while (--num_arrays >= 0) while (--num_arrays >= 0)
type = _Jv_GetArrayClass (type, 0); type = _Jv_GetArrayClass (type, loader);
// ARGPTR can be NULL if we are processing the return value of a // ARGPTR can be NULL if we are processing the return value of a
// call from Constructor. // call from Constructor.
if (argPtr) if (argPtr)
...@@ -328,14 +328,15 @@ _Jv_GetTypesFromSignature (jmethodID method, ...@@ -328,14 +328,15 @@ _Jv_GetTypesFromSignature (jmethodID method,
// to a `jvalue' (see jni.h); for a void method this should be NULL. // to a `jvalue' (see jni.h); for a void method this should be NULL.
// This function returns an exception (if one was thrown), or NULL if // This function returns an exception (if one was thrown), or NULL if
// the call went ok. // the call went ok.
jthrowable void
_Jv_CallAnyMethodA (jobject obj, _Jv_CallAnyMethodA (jobject obj,
jclass return_type, jclass return_type,
jmethodID meth, jmethodID meth,
jboolean is_constructor, jboolean is_constructor,
JArray<jclass> *parameter_types, JArray<jclass> *parameter_types,
jvalue *args, jvalue *args,
jvalue *result) jvalue *result,
jboolean is_jni_call)
{ {
#ifdef USE_LIBFFI #ifdef USE_LIBFFI
JvAssert (! is_constructor || ! obj); JvAssert (! is_constructor || ! obj);
...@@ -409,15 +410,11 @@ _Jv_CallAnyMethodA (jobject obj, ...@@ -409,15 +410,11 @@ _Jv_CallAnyMethodA (jobject obj,
if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, param_count, if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, param_count,
rtype, argtypes) != FFI_OK) rtype, argtypes) != FFI_OK)
{ throw new java::lang::VirtualMachineError(JvNewStringLatin1("internal error: ffi_prep_cif failed"));
// FIXME: throw some kind of VirtualMachineError here.
}
using namespace java::lang; using namespace java::lang;
using namespace java::lang::reflect; using namespace java::lang::reflect;
Throwable *ex = NULL;
union union
{ {
ffi_arg i; ffi_arg i;
...@@ -427,17 +424,51 @@ _Jv_CallAnyMethodA (jobject obj, ...@@ -427,17 +424,51 @@ _Jv_CallAnyMethodA (jobject obj,
jdouble d; jdouble d;
} ffi_result; } ffi_result;
switch (rtype->type)
{
case FFI_TYPE_VOID:
break;
case FFI_TYPE_SINT8:
result->b = 0;
break;
case FFI_TYPE_SINT16:
result->s = 0;
break;
case FFI_TYPE_UINT16:
result->c = 0;
break;
case FFI_TYPE_SINT32:
result->i = 0;
break;
case FFI_TYPE_SINT64:
result->j = 0;
break;
case FFI_TYPE_FLOAT:
result->f = 0;
break;
case FFI_TYPE_DOUBLE:
result->d = 0;
break;
case FFI_TYPE_POINTER:
result->l = 0;
break;
default:
JvFail ("Unknown ffi_call return type");
break;
}
try try
{ {
ffi_call (&cif, (void (*)()) meth->ncode, &ffi_result, values); ffi_call (&cif, (void (*)()) meth->ncode, &ffi_result, values);
} }
catch (Throwable *ex2) catch (Throwable *ex)
{ {
// FIXME: this is wrong for JNI. But if we just return the // For JNI we just throw the real error. For reflection, we
// exception, then the non-JNI cases won't be able to // wrap the underlying method's exception in an
// distinguish it from exceptions we might generate ourselves. // InvocationTargetException.
// Sigh. if (! is_jni_call)
ex = new InvocationTargetException (ex2); ex = new InvocationTargetException (ex);
throw ex;
} }
// Since ffi_call returns integer values promoted to a word, use // Since ffi_call returns integer values promoted to a word, use
...@@ -481,11 +512,8 @@ _Jv_CallAnyMethodA (jobject obj, ...@@ -481,11 +512,8 @@ _Jv_CallAnyMethodA (jobject obj,
break; break;
} }
} }
return ex;
#else #else
throw new java::lang::UnsupportedOperationException; throw new java::lang::UnsupportedOperationException(JvNewStringLatin1("reflection not available in this build"));
return 0;
#endif // USE_LIBFFI #endif // USE_LIBFFI
} }
...@@ -562,16 +590,9 @@ _Jv_CallAnyMethodA (jobject obj, ...@@ -562,16 +590,9 @@ _Jv_CallAnyMethodA (jobject obj,
} }
jvalue ret_value; jvalue ret_value;
java::lang::Throwable *ex = _Jv_CallAnyMethodA (obj, _Jv_CallAnyMethodA (obj, return_type, meth, is_constructor,
return_type, parameter_types, argvals, &ret_value,
meth, false);
is_constructor,
parameter_types,
argvals,
&ret_value);
if (ex)
throw ex;
jobject r; jobject r;
#define VAL(Wrapper, Field) (new Wrapper (ret_value.Field)) #define VAL(Wrapper, Field) (new Wrapper (ret_value.Field))
......
...@@ -777,12 +777,9 @@ static T ...@@ -777,12 +777,9 @@ static T
return_type = klass; return_type = klass;
jvalue result; jvalue result;
jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, _Jv_CallAnyMethodA (obj, return_type, id,
style == constructor, style == constructor,
arg_types, args, &result); arg_types, args, &result);
if (ex != NULL)
env->ex = ex;
// We cheat a little here. FIXME. // We cheat a little here. FIXME.
return wrap_value (env, * (T *) &result); return wrap_value (env, * (T *) &result);
...@@ -847,12 +844,9 @@ static T ...@@ -847,12 +844,9 @@ static T
} }
jvalue result; jvalue result;
jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, _Jv_CallAnyMethodA (obj, return_type, id,
style == constructor, style == constructor,
arg_types, arg_copy, &result); arg_types, arg_copy, &result);
if (ex != NULL)
env->ex = ex;
// We cheat a little here. FIXME. // We cheat a little here. FIXME.
return wrap_value (env, * (T *) &result); return wrap_value (env, * (T *) &result);
...@@ -893,12 +887,9 @@ static void ...@@ -893,12 +887,9 @@ static void
if (style == constructor) if (style == constructor)
return_type = klass; return_type = klass;
jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, _Jv_CallAnyMethodA (obj, return_type, id,
style == constructor, style == constructor,
arg_types, args, NULL); arg_types, args, NULL);
if (ex != NULL)
env->ex = ex;
} }
catch (jthrowable t) catch (jthrowable t)
{ {
...@@ -947,12 +938,9 @@ static void ...@@ -947,12 +938,9 @@ static void
arg_copy[i].l = unwrap (args[i].l); arg_copy[i].l = unwrap (args[i].l);
} }
jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, _Jv_CallAnyMethodA (obj, return_type, id,
style == constructor, style == constructor,
arg_types, args, NULL); arg_types, args, NULL);
if (ex != NULL)
env->ex = ex;
} }
catch (jthrowable t) catch (jthrowable t)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment