[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