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)




On Sat, 17 Nov 2001, Bryce McKinlay wrote:
> 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.

I agree.

> I'm not sure I follow. The rule is that types that are smaller than int 
> will get promoted to int.

Not exactly.  I had assumed that too, before I realized the
declaration of "rint" isn't necessarily "int" (in ffitest.c):

#if defined(ALPHA) || defined(IA64) || defined(SPARC64) || (defined(MIPS)
&& (_MIPS_SIM == _ABIN32))
  long long rint;
#else
  int rint;
#endif

That's ugly, for a library that's intended to be portable.  I think we
could declare the return value "long" instead and it should work almost
anywhere.  It'd be better I guess if libffi supplied a typedef for this.

> 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?

Hans pointed out that sparc64 is big-endian.  (There may be others... does
anyone run ia64 in big-endian mode?)

> Anyway, here's my take on a fix. What do you think?

1) promoted return value may not be jint, e.g. sparc64

2) does this fix JNI, or just reflection?


Here's what I'm testing now:

2001-11-16  Jeff Sturm  <jsturm@one-point.com>

	* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA):
	Narrow subword return values to the proper type.

Index: natMethod.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natMethod.cc,v
retrieving revision 1.24
diff -u -p -r1.24 natMethod.cc
--- natMethod.cc	2001/10/02 13:44:32	1.24
+++ natMethod.cc	2001/11/16 13:43:46
@@ -420,6 +420,7 @@ _Jv_CallAnyMethodA (jobject obj,
       p += tsize;
     }
 
+
   // FIXME: initialize class here.
 
   using namespace java::lang;
@@ -429,7 +430,69 @@ _Jv_CallAnyMethodA (jobject obj,
 
   try
     {
-      ffi_call (&cif, (void (*)()) meth->ncode, result, values);
+      // Since ffi_call returns integer values promoted to a word, use
+      // a narrowing conversion for jbyte, jchar, etc. results.
+      // Note that boolean is handled either by the FFI_TYPE_SINT8 or
+      // FFI_TYPE_SINT32 case.
+      // FIXME - "long" may not be the same as a word.
+      switch (rtype->type)
+	{
+	case FFI_TYPE_VOID:
+	  ffi_call (&cif, (void (*)()) meth->ncode, NULL, values);
+	  break;
+	case FFI_TYPE_SINT8:
+	  {
+	    long result_word;
+	    ffi_call (&cif, (void (*)()) meth->ncode, &result_word, values);
+	    result->b = (jbyte)result_word;
+	  }
+	  break;
+	case FFI_TYPE_SINT16:
+	  {
+	    long result_word;
+	    ffi_call (&cif, (void (*)()) meth->ncode, &result_word, values);
+	    result->s = (jshort)result_word;
+	  }
+	  break;
+	case FFI_TYPE_UINT16:
+	  {
+	    long result_word;
+	    ffi_call (&cif, (void (*)()) meth->ncode, &result_word, values);
+	    result->c = (jchar)result_word;
+	  }
+	  break;
+	case FFI_TYPE_SINT32:
+	  {
+	    long result_word;
+	    ffi_call (&cif, (void (*)()) meth->ncode, &result_word, values);
+	    result->i = (jint)result_word;
+	  }
+	  break;
+	case FFI_TYPE_SINT64:
+	  {
+	    long result_word;
+	    ffi_call (&cif, (void (*)()) meth->ncode, &result_word, values);
+	    result->j = (jlong)result_word;
+	  }
+	  break;
+	case FFI_TYPE_FLOAT:
+	  {
+	    float float_result;
+	    ffi_call (&cif, (void (*)()) meth->ncode, &float_result, values);
+	    result->f = (jfloat)float_result;
+	  }
+	  break;
+	case FFI_TYPE_DOUBLE:
+	  {
+	    double double_result;
+	    ffi_call (&cif, (void (*)()) meth->ncode, &double_result, values);
+	    result->d = (jdouble)double_result;
+	  }
+	  break;
+	default:
+	  JvFail ("Unknown ffi_call return type");
+	  break;
+	}
     }
   catch (Throwable *ex2)
     {


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