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]

PATCH: ffi_call argument/return types



I found while testing on SPARC that libffi assumes return types can hold
at least an int.  When returning bytes to libjava, libffi writes to the
jvalue union as if it were an int, so accessing the jbyte member of the
union doesn't produce the correct results.

I worked around it by removing members smaller than jint from the jvalue
union.  Instead they are casted to/from int.

Tested on sparc-sun-solaris2.7, i686-pc-linux-gnu and
alpha-unknown-linux-gnu.  I've written some reflection tests which I can
commit to the testsuite as well.

2001-08-14  Jeff Sturm  <jsturm@one-point.com>

	* jni.cc (array_from_valist): Cast subword arguments to `jint'.
	* include/jni.h (jvalue): Remove z,b,s,c members.
	* java/lang/reflect/natMethod.cc (get_ffi_type): Handle
	boolean with ffi_type_sint8.
	(_Jv_CallAnyMethodA): Remove COPY macro.  Directly assign
	members of jvalue union.  Cast subword arguments to `jint'.
	Remove VAL macro; cast subword return values to their respective
	type.

Index: jni.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni.cc,v
retrieving revision 1.48
diff -u -r1.48 jni.cc
--- jni.cc	2001/08/02 22:12:40	1.48
+++ jni.cc	2001/08/14 13:03:55
@@ -656,9 +656,9 @@
   for (int i = 0; i < arg_types->length; ++i)
     {
       if (arg_elts[i] == JvPrimClass (byte))
-	values[i].b = va_arg (vargs, jbyte);
+	values[i].i = (jint) va_arg (vargs, jbyte);
       else if (arg_elts[i] == JvPrimClass (short))
-	values[i].s = va_arg (vargs, jshort);
+	values[i].i = (jint) va_arg (vargs, jshort);
       else if (arg_elts[i] == JvPrimClass (int))
 	values[i].i = va_arg (vargs, jint);
       else if (arg_elts[i] == JvPrimClass (long))
@@ -668,9 +668,9 @@
       else if (arg_elts[i] == JvPrimClass (double))
 	values[i].d = va_arg (vargs, jdouble);
       else if (arg_elts[i] == JvPrimClass (boolean))
-	values[i].z = va_arg (vargs, jboolean);
+	values[i].i = (jint) va_arg (vargs, jboolean);
       else if (arg_elts[i] == JvPrimClass (char))
-	values[i].c = va_arg (vargs, jchar);
+	values[i].i = (jint) va_arg (vargs, jchar);
       else
 	{
 	  // An object.
Index: include/jni.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jni.h,v
retrieving revision 1.14
diff -u -r1.14 jni.h
--- jni.h	2001/04/27 16:09:10	1.14
+++ jni.h	2001/08/14 13:03:57
@@ -107,10 +107,6 @@
 
 typedef union jvalue
 {
-  jboolean z;
-  jbyte    b;
-  jchar    c;
-  jshort   s;
   jint     i;
   jlong    j;
   jfloat   f;
Index: java/lang/reflect/natMethod.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natMethod.cc,v
retrieving revision 1.22
diff -u -r1.22 natMethod.cc
--- natMethod.cc	2001/06/02 08:49:31	1.22
+++ natMethod.cc	2001/08/14 13:03:58
@@ -133,16 +133,7 @@
   else if (klass == JvPrimClass (double))
     r = &ffi_type_double;
   else if (klass == JvPrimClass (boolean))
-    {
-      // On some platforms a bool is a byte, on others an int.
-      if (sizeof (jboolean) == sizeof (jbyte))
-	r = &ffi_type_sint8;
-      else
-	{
-	  JvAssert (sizeof (jboolean) == sizeof (jint));
-	  r = &ffi_type_sint32;
-	}
-    }
+    r = &ffi_type_sint8;
   else if (klass == JvPrimClass (char))
     r = &ffi_type_uint16;
   else
@@ -466,12 +457,6 @@
   jobject *argelts = args == NULL ? NULL : elements (args);
   jvalue argvals[param_count];
 
-#define COPY(Where, What, Type) \
-  do { \
-    Type val = (What); \
-    memcpy ((Where), &val, sizeof (Type)); \
-  } while (0)
-
   for (int i = 0; i < param_count; ++i)
     {
       jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
@@ -483,35 +468,31 @@
 	    throw new java::lang::IllegalArgumentException;
 	    
 	  if (paramelts[i] == JvPrimClass (boolean))
-	    COPY (&argvals[i],
-		  ((java::lang::Boolean *) argelts[i])->booleanValue(),
-		  jboolean);
+	    argvals[i].i = (jint) ((java::lang::Boolean *) argelts[i])->booleanValue();
 	  else if (paramelts[i] == JvPrimClass (char))
-	    COPY (&argvals[i],
-		  ((java::lang::Character *) argelts[i])->charValue(),
-		  jchar);
+	    argvals[i].i = (jint) ((java::lang::Character *) argelts[i])->charValue();
           else
 	    {
 	      java::lang::Number *num = (java::lang::Number *) argelts[i];
 	      if (paramelts[i] == JvPrimClass (byte))
-		COPY (&argvals[i], num->byteValue(), jbyte);
+		argvals[i].i = (jint) num->byteValue();
 	      else if (paramelts[i] == JvPrimClass (short))
-		COPY (&argvals[i], num->shortValue(), jshort);
+		argvals[i].i = (jint) num->shortValue();
 	      else if (paramelts[i] == JvPrimClass (int))
-		COPY (&argvals[i], num->intValue(), jint);
+		argvals[i].i = (jint) num->intValue();
 	      else if (paramelts[i] == JvPrimClass (long))
-		COPY (&argvals[i], num->longValue(), jlong);
+		argvals[i].j = (jlong) num->longValue();
 	      else if (paramelts[i] == JvPrimClass (float))
-		COPY (&argvals[i], num->floatValue(), jfloat);
+		argvals[i].f = (jfloat) num->floatValue();
 	      else if (paramelts[i] == JvPrimClass (double))
-		COPY (&argvals[i], num->doubleValue(), jdouble);
+		argvals[i].d = (jdouble) num->doubleValue();
 	    }
 	}
       else
 	{
 	  if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
 	    throw new java::lang::IllegalArgumentException;
-	  COPY (&argvals[i], argelts[i], jobject);
+	  argvals[i].l = (jobject) argelts[i];
 	}
     }
 
@@ -528,25 +509,24 @@
     throw ex;
 
   jobject r;
-#define VAL(Wrapper, Field)  (new Wrapper (ret_value.Field))
   if (is_constructor)
     r = ret_value.l;
   else  if (return_type == JvPrimClass (byte))
-    r = VAL (java::lang::Byte, b);
+    r = new ::java::lang::Byte ((jbyte) ret_value.i);
   else if (return_type == JvPrimClass (short))
-    r = VAL (java::lang::Short, s);
+    r = new ::java::lang::Short ((jshort) ret_value.i);
   else if (return_type == JvPrimClass (int))
-    r = VAL (java::lang::Integer, i);
+    r = new ::java::lang::Integer ((jint) ret_value.i);
   else if (return_type == JvPrimClass (long))
-    r = VAL (java::lang::Long, j);
+    r = new ::java::lang::Long ((jlong) ret_value.j);
   else if (return_type == JvPrimClass (float))
-    r = VAL (java::lang::Float, f);
+    r = new ::java::lang::Float ((jfloat) ret_value.f);
   else if (return_type == JvPrimClass (double))
-    r = VAL (java::lang::Double, d);
+    r = new ::java::lang::Double ((jdouble) ret_value.d);
   else if (return_type == JvPrimClass (boolean))
-    r = VAL (java::lang::Boolean, z);
+    r = new ::java::lang::Boolean ((jboolean) ret_value.i);
   else if (return_type == JvPrimClass (char))
-    r = VAL (java::lang::Character, c);
+    r = new ::java::lang::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]