This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Re: PATCH: libffi vs. SPARC (again)
- From: Bryce McKinlay <bryce at waitaki dot otago dot ac dot nz>
- To: Jeff Sturm <jsturm at one-point dot com>
- Cc: tromey at redhat dot com, java-patches at gcc dot gnu dot org, green at redhat dot com
- Date: Sat, 17 Nov 2001 00:50:24 +1300
- Subject: Re: PATCH: libffi vs. SPARC (again)
- References: <Pine.LNX.4.10.10111160040480.30383-100000@mars.deadcafe.org>
Jeff Sturm wrote
>Libffi does promote sub-word return values, regardless of rtype. (It does
>not assume arguments are similarly promoted by the caller, which seems
>like an inconsistency.)
>
Okay, I misunderstood the problem. The only problem with libffi is that
this behaviour isn't documented other than in the ffitest source. I
agree its an inconsistency, but does make some sense, since it would
presumably it would make the big-endian ports more complex and less
efficient to not to promote the return value. And it isn't hard to deal
with as long as you're aware of it.
>Yes. _Jv_CallAnyMethodA passed a (struct jvalue *) to ffi_call, then
>looks at (result->b). It is the same as if it passed a (jbyte *) to
>ffi_call. In other words, _Jv_CallAnyMethodA assumes the return value is
>_not_ promoted.
>
... and therein lies the problem. A classic endian bug!
>For that matter, the return value is not always 32-bit (i.e. "jint") as
>Hans pointed out. A "long" return value would suffice for most targets
>including LP64, but not P64 (which Microsoft is using for their 64-bit OS,
>unfortunately). In any case, "double", "float" and "long long" need
>special treatment, and we need a portable way to declare a return value
>with the correct wordsize.
>
I'm not sure I follow. The rule is that types that are smaller than int
will get promoted to int. Types that are equal/larger than int will be
stored in the native way. As long as all 64-bit CPUs are little endian
then there is no problem! Or am I missing something?
Anyway, here's my take on a fix. What do you think?
regards
Bryce.
2001-11-17 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Narrow sub-int
return types correctly as they are promoted to int by libffi.
Index: natMethod.cc
===================================================================
RCS file: /cvs/gcc/egcs/libjava/java/lang/reflect/natMethod.cc,v
retrieving revision 1.24
diff -u -r1.24 natMethod.cc
--- natMethod.cc 2001/10/02 13:44:32 1.24
+++ natMethod.cc 2001/11/16 11:46:09
@@ -537,25 +537,29 @@
throw ex;
jobject r;
-#define VAL(Wrapper, Field) (new Wrapper (ret_value.Field))
+
+ using namespace java::lang;
+
+ // If the return value is smaller than int, it will be promoted to int by
+ // ffi_call. So we must narrow it to the correct type.
if (is_constructor)
r = ret_value.l;
else if (return_type == JvPrimClass (byte))
- r = VAL (java::lang::Byte, b);
+ r = new Byte ((jbyte) ret_value.i);
else if (return_type == JvPrimClass (short))
- r = VAL (java::lang::Short, s);
+ r = new Short ((jshort) ret_value.i);
else if (return_type == JvPrimClass (int))
- r = VAL (java::lang::Integer, i);
+ r = new Integer (ret_value.i);
else if (return_type == JvPrimClass (long))
- r = VAL (java::lang::Long, j);
+ r = new Long (ret_value.j);
else if (return_type == JvPrimClass (float))
- r = VAL (java::lang::Float, f);
+ r = new Float (ret_value.f);
else if (return_type == JvPrimClass (double))
- r = VAL (java::lang::Double, d);
+ r = new Double (ret_value.d);
else if (return_type == JvPrimClass (boolean))
- r = VAL (java::lang::Boolean, z);
+ r = new Boolean ((jboolean) ret_value.i);
else if (return_type == JvPrimClass (char))
- r = VAL (java::lang::Character, c);
+ r = new Character ((jchar) ret_value.i);
else if (return_type == JvPrimClass (void))
r = NULL;
else