[Kaffe] found cause of bug method invocation, patch included!

Moses DeJong dejong at cs.umn.edu
Tue Feb 23 23:22:37 PST 1999


On Sun, 7 Feb 1999, Godmar Back wrote:

> > 
> > I am not sure what the "right" way to fix this is. Does someone that
> > knows a little more about the Kaffe internals comment about the best
> > way to fix this for little and big endian machines?
> 
>  Alexandre had also suspected that it's a endianness problem.  He promised
> to look into it.
> 
> 	- Godmar
> 



Big news!

I have been able to fix the endian problems with JNI and
reflection in Kaffe. I can not take credit for the idea
behind the fix as Christophe Lizzi <lizzi at csti.fr> from
the japhar JVM project gets the credit for that, but I
have implemented the fix for kaffe and created a
patch. Here is a little background on the problem.


Say you have this C code.

#include <stdio.h>

union jvalue {
  char          z;
  char		b;
  char		c; 
  short		s;
  int		i;
  long		j;
  float		f;
  double        d;
  void*		l;
};

typedef union jvalue jvalue;

void main(int argc, char ** argv) {
  jvalue var;
  char val;

  var.i = 1;

  val = var.z;

  /* endian fix */
  /* val = (char) var.i; */

  printf("var.z is \"%d\"\n", ((int) val));
}


On a little endian system var.z would return
1 but on a big endian system it will return 0.
The fix is to use the commented out code which
will convert an int to a char properly on both
big endian and little endian systems.


Here is an example java program that does not
work under Kaffe on a big endian system. With
the patch included below it will work correctly.



import java.lang.reflect.*;

public class ReflectedByteBug4 {
    public static void main(String[] argv) throws Exception {
	Method m1 = ReflectedByteBug4.class.getMethod("maxByteObjectMethod", null);
	System.out.println("m1 is " + m1);

	Method m2 = ReflectedByteBug4.class.getMethod("minByteObjectMethod", null);
	System.out.println("m2 is " + m2);


	Byte tb = (Byte) m1.invoke(null,null);
	Byte fb = (Byte) m2.invoke(null,null);

	if (tb.byteValue() != Byte.MAX_VALUE) {
	    throw new Exception("byteValue() != Byte.MAX_VALUE");
	}

	if (fb.byteValue() != Byte.MIN_VALUE) {
	    throw new Exception("byteValue() != Byte.MIN_VALUE");
	}

	System.out.println("OK");
    }

    public static byte maxByteObjectMethod() {
	return Byte.MAX_VALUE;
    }

    public static byte minByteObjectMethod() {
	return Byte.MIN_VALUE;
    }
}



/*
JDK

% java ReflectedByteBug4
m1 is public static byte ReflectedByteBug4.maxByteObjectMethod()
m2 is public static byte ReflectedByteBug4.minByteObjectMethod()
OK

*/


/*
Kaffe before patch

% kaffe ReflectedByteBug4
m1 is public static byte ReflectedByteBug4.maxByteObjectMethod()
m2 is public static byte ReflectedByteBug4.minByteObjectMethod()
java.lang.Exception: byteValue() != Byte.MAX_VALUE
        at java.lang.Throwable.<init>(Throwable.java:37)
        at java.lang.Exception.<init>(Exception.java:21)
        at ReflectedByteBug4.main(ReflectedByteBug4.java:16)


*/


/*
Kaffe after patch

% kaffe ReflectedByteBug4
m1 is public static byte ReflectedByteBug4.maxByteObjectMethod()
m2 is public static byte ReflectedByteBug4.minByteObjectMethod()
OK

*/







Ok, here is the patch. Note that this patch does 3 things.

1) Fixes the endian problems.
2) Changes uses of jbool to jboolean in jni.c and kaffeh program
3) Fixes wrong number of arguments problem in libraries/clib/native/Runtime.c


I hope that helps
Mo DeJong
dejong at cs.umn.edu






Index: kaffe/kaffeh/sigs.c
===================================================================
RCS file: /home/cvspublic/kaffe/kaffe/kaffeh/sigs.c,v
retrieving revision 1.2
diff -u -r1.2 sigs.c
--- sigs.c	1998/12/11 01:10:10	1.2
+++ sigs.c	1999/02/24 08:09:46
@@ -116,7 +116,7 @@
 		break;
 	case 'Z':
 		arg = 1;
-		strcpy(fp, "jbool");
+		strcpy(fp, "jboolean");
 		break;
 	case 'V':
 		arg = 0;
Index: kaffe/kaffevm/jni.c
===================================================================
RCS file: /home/cvspublic/kaffe/kaffe/kaffevm/jni.c,v
retrieving revision 1.31
diff -u -r1.31 jni.c
--- jni.c	1999/02/16 22:33:47	1.31
+++ jni.c	1999/02/24 08:09:48
@@ -581,10 +581,10 @@
 	callMethodV(m, o->dtable->method[m->idx], obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.z);
+	return ((jboolean) retval.i);
 }
 
-jbool
+jboolean
 Kaffe_CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID meth, ...)
 {
 	va_list args;
@@ -600,7 +600,7 @@
 	return (ret);
 }
 
-jbool
+jboolean
 Kaffe_CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID meth, jvalue* args)
 {
 	jvalue retval;
@@ -616,7 +616,7 @@
 	callMethodA(m, o->dtable->method[m->idx], obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.z);
+	return ((jboolean) retval.i);
 }
 
 jbyte
@@ -635,7 +635,7 @@
 	callMethodV(m, o->dtable->method[m->idx], obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.b);
+	return ((jbyte) retval.i);
 }
 
 jbyte
@@ -670,7 +670,7 @@
 	callMethodA(m, o->dtable->method[m->idx], obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.b);
+	return ((jbyte) retval.i);
 }
 
 jchar
@@ -689,7 +689,7 @@
 	callMethodV(m, o->dtable->method[m->idx], obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.c);
+	return ((jchar) retval.i);
 }
 
 jchar
@@ -724,7 +724,7 @@
 	callMethodA(m, o->dtable->method[m->idx], obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.c);
+	return ((jchar) retval.i);
 }
 
 jshort
@@ -743,7 +743,7 @@
 	callMethodV(m, o->dtable->method[m->idx], obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.s);
+	return ((jshort) retval.i);
 }
 
 jshort
@@ -778,7 +778,7 @@
 	callMethodA(m, o->dtable->method[m->idx], obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.s);
+	return ((jshort) retval.i);
 }
 
 jint
@@ -1114,10 +1114,10 @@
 	callMethodV(m, JNI_METHOD_CODE(m), obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.z);
+	return ((jboolean) retval.i);
 }
 
-jbool
+jboolean
 Kaffe_CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass cls, jmethodID meth, ...)
 {
 	va_list args;
@@ -1133,7 +1133,7 @@
 	return (ret);
 }
 
-jbool
+jboolean
 Kaffe_CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass cls, jmethodID meth, jvalue* args)
 {
 	jvalue retval;
@@ -1148,7 +1148,7 @@
 	callMethodA(m, JNI_METHOD_CODE(m), obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.z);
+	return ((jboolean) retval.i);
 }
 
 jbyte
@@ -1166,7 +1166,7 @@
 	callMethodV(m, JNI_METHOD_CODE(m), obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.b);
+	return ((jbyte) retval.i);
 }
 
 jbyte
@@ -1200,7 +1200,7 @@
 	callMethodA(m, JNI_METHOD_CODE(m), obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.b);
+	return ((jbyte) retval.i);
 }
 
 jchar
@@ -1218,7 +1218,7 @@
 	callMethodV(m, JNI_METHOD_CODE(m), obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.c);
+	return ((jchar) retval.i);
 }
 
 jchar
@@ -1252,7 +1252,7 @@
 	callMethodA(m, JNI_METHOD_CODE(m), obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.c);
+	return ((jchar) retval.i);
 }
 
 jshort
@@ -1270,7 +1270,7 @@
 	callMethodV(m, JNI_METHOD_CODE(m), obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.s);
+	return ((jshort) retval.i);
 }
 
 jshort
@@ -1304,7 +1304,7 @@
 	callMethodA(m, JNI_METHOD_CODE(m), obj, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.s);
+	return ((jshort) retval.i);
 }
 
 jint
@@ -1851,7 +1851,7 @@
 	return (retval.l);
 }
 
-jbool
+jboolean
 Kaffe_CallStaticBooleanMethodV(JNIEnv* env, jclass cls, jmethodID meth, va_list args)
 {
 	jvalue retval;
@@ -1866,10 +1866,10 @@
 	callMethodV(m, JNI_METHOD_CODE(m), 0, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.z);
+	return ((jboolean) retval.i);
 }
 
-jbool
+jboolean
 Kaffe_CallStaticBooleanMethod(JNIEnv* env, jclass cls, jmethodID meth, ...)
 {
 	va_list args;
@@ -1885,7 +1885,7 @@
 	return (ret);
 }
 
-jbool
+jboolean
 Kaffe_CallStaticBooleanMethodA(JNIEnv* env, jclass cls, jmethodID meth, jvalue* args)
 {
 	jvalue retval;
@@ -1900,7 +1900,7 @@
 	callMethodA(m, JNI_METHOD_CODE(m), 0, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.z);
+	return ((jboolean) retval.i);
 }
 
 jbyte
@@ -1918,7 +1918,7 @@
 	callMethodV(m, JNI_METHOD_CODE(m), 0, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.b);
+	return ((jbyte) retval.i);
 }
 
 jbyte
@@ -1952,7 +1952,7 @@
 	callMethodA(m, JNI_METHOD_CODE(m), 0, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.b);
+	return ((jbyte) retval.i);
 }
 
 jchar
@@ -1970,7 +1970,7 @@
 	callMethodV(m, JNI_METHOD_CODE(m), 0, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.c);
+	return ((jchar) retval.i);
 }
 
 jchar
@@ -2004,7 +2004,7 @@
 	callMethodA(m, JNI_METHOD_CODE(m), 0, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.c);
+	return ((jchar) retval.i);
 }
 
 jshort
@@ -2022,7 +2022,7 @@
 	callMethodV(m, JNI_METHOD_CODE(m), 0, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.s);
+	return ((jshort) retval.i);
 }
 
 jshort
@@ -2056,7 +2056,7 @@
 	callMethodA(m, JNI_METHOD_CODE(m), 0, args, &retval);
 
 	END_EXCEPTION_HANDLING();
-	return (retval.s);
+	return ((jshort) retval.i);
 }
 
 jint
Index: libraries/clib/native/Runtime.c
===================================================================
RCS file: /home/cvspublic/kaffe/libraries/clib/native/Runtime.c,v
retrieving revision 1.11
diff -u -r1.11 Runtime.c
--- Runtime.c	1999/02/24 06:01:13	1.11
+++ Runtime.c	1999/02/24 08:09:54
@@ -33,7 +33,7 @@
 extern char* libraryPath;
 extern size_t gc_heap_limit;
 extern size_t gc_heap_total;
-extern jbool runFinalizerOnExit;
+extern jboolean runFinalizerOnExit;
 
 
 /*
@@ -73,7 +73,7 @@
 /*
  * Load in a library file.
  */
-jbool
+jboolean
 java_lang_Runtime_loadFileInternal(struct Hjava_lang_Runtime* this, struct Hjava_lang_String* s1)
 {
 	char lib[MAXPATHLEN];
@@ -153,7 +153,7 @@
  * Enable/disable tracing of instructions.
  */
 void
-java_lang_Runtime_traceInstructions(struct Hjava_lang_Runtime* this, jbool on)
+java_lang_Runtime_traceInstructions(struct Hjava_lang_Runtime* this, jboolean on)
 {
 	if (on == true) {
 		SignalError("java.lang.RuntimeException", "Cannot trace instructions");   
@@ -164,7 +164,7 @@
  * Enable/disable tracing of method calls.
  */
 void
-java_lang_Runtime_traceMethodCalls(struct Hjava_lang_Runtime* this, jbool on)
+java_lang_Runtime_traceMethodCalls(struct Hjava_lang_Runtime* this, jboolean on)
 {
 	if (on == true) {
 		SignalError("java.lang.RuntimeException", "Cannot trace method calls");   
@@ -175,7 +175,7 @@
  * Inform the runtime that it must run the finalizer when it exits.
  */
 void
-java_lang_Runtime_runFinalizersOnExit(jbool on)
+java_lang_Runtime_runFinalizersOnExit(struct Hjava_lang_Runtime* rt, jboolean on)
 {
 	runFinalizerOnExit = on;
 }



More information about the kaffe mailing list