This is the mail archive of the java-patches@gcc.gnu.org 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]
Other format: [Raw text]

Re: PATCH: libffi vs. SPARC (again)


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

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