Christoph,

> > Here is a patch that fix broken jlongs on bigendian architectures.
> > It has been tested on Sparc and PowerPC platforms, and also works on x86.
> > This fix can be applied against release 0.07.
> >

> cool.  i'll ifdef them and check them in tonight. 

The patch produces correct results on both little endian and big endian 
platforms. So, it is not absolutely required to add 
#ifndef/#else/#endif WORDS_BIGENDIAN...

More generally, I noticed in various files several statements
like the following one:

     jvalue.i = some_value;
     ...
     returned_value = jvalue.z; /* or jvalue.b, jvalue.c, etc... */

I think this reduces portability because such statements assume
implicit allignment and indianess rules that may be platform-dependent.
In most cases, the included patch just corrects some of these constructs
to get correct results on both big and little endian hosts.

> Can you please forward the other fixes (for jbooleans and jbytes)?


The following patch includes the one posted yesterday. It fixes
jbooleans, jbytes, jchars. jshort, jlongs and jdoubles. It has been
tested on Sparc and PowerPC hosts, and it also works correctly on x86 hosts.

This fix can be applied against Japhar release 0.07. Sorry, i do not use
the latest CVS snapshot.


diff -u include/op_stack.h.ini include/op_stack.h
--- include/op_stack.h.ini      Mon Feb 22 11:49:14 1999
+++ include/op_stack.h  Tue Feb 23 18:29:54 1999
@@ -244,7 +244,7 @@
 
   /*  assert(item.tag == SIG_JBYTE);*/
 
-  *value = stack_value.b;
+  *value = (jbyte) stack_value.i; /* was pushed as jint */
 
   JAVARLOG2(OPSTACK_LOG, 1, "    Popping byte off operand stack %p, value is 
%d\n", s, *value);
 }
@@ -261,7 +261,7 @@
 
   /*  assert(item.tag == SIG_JCHAR);*/
 
-  *value = stack_value.c;
+  *value = (jchar) stack_value.i; /* was pushed as jint */
 
   JAVARLOG3(OPSTACK_LOG, 1, "    Popping char off operand stack %p, value is %d 
(%c)\n",
            s,
@@ -280,7 +280,7 @@
 
   /*  assert(item.tag == SIG_JSHORT);*/
 
-  *value = stack_value.s;
+  *value = (jshort) stack_value.i; /* was pushed as jint */
 
   JAVARLOG2(OPSTACK_LOG, 1, "    Popping short off operand stack %p, value is 
%d\n", s, *value);
 }
@@ -297,7 +297,7 @@
 
   /*  assert(item.tag == SIG_JBOOLEAN);*/
 
-  *value = stack_value.z;
+  *value = (jboolean) stack_value.i; /* was pushed as jint */
 
   JAVARLOG2(OPSTACK_LOG, 1, "    Popping boolean off operand stack %p, value is 
%s\n", 
            s, *value == 0 ? "False" : "True");
@@ -343,11 +343,11 @@
 
   assert (s != NULL);
 
-  val2.i = (jint)*(--s->stack_top);
-  val1.i = (jint)*(--s->stack_top);
+  val2.i = (juint)*(--s->stack_top);
+  val1.i = (juint)*(--s->stack_top);
 
-  *value = (jlong)val1.i << 32;
-  *value |= val2.j & 0xffffffff;
+  *value = (jlong)(juint)val1.i << 32;
+  *value |= (jlong)(juint)val2.i;
 
   JAVARLOG2(OPSTACK_LOG, 1, "    Popping long off operand stack %p, value is 
%ld\n", s, *value);
 }
@@ -392,11 +392,11 @@
 
   val.j = 0;
 
-  val2.i = (jint)*(--s->stack_top);
-  val1.i = (jint)*(--s->stack_top);
+  val2.i = (juint)*(--s->stack_top);
+  val1.i = (juint)*(--s->stack_top);
 
-  val.j = (jlong)val1.i << 32;
-  val.j |= val2.j & 0xffffffff;
+  val.j = (jlong)(juint)val1.i << 32;
+  val.j |= (jlong)(juint)val2.i;
 
   *value = val.d;
 
@@ -495,6 +495,22 @@
   else if (tag == SIG_JLONG)
     {
       op_stack_pop_long(env, s, &value->j);
+    }
+  else if (tag == SIG_JBOOLEAN)
+    {
+      op_stack_pop_boolean(env, s, &value->z);
+    }
+  else if (tag == SIG_JBYTE)
+    {
+      op_stack_pop_byte(env, s, &value->b);
+    }
+  else if (tag == SIG_JCHAR)
+    {
+      op_stack_pop_char(env, s, &value->c);
+    }
+  else if (tag == SIG_JSHORT)
+    {
+      op_stack_pop_short(env, s, &value->s);
     }
   else
     {


diff -u lib/libruntime/nativeglue.c.ini lib/librunime/nativeglue.c
--- lib/libruntime/nativeglue.c.ini     Tue Feb 23 19:02:52 1999
+++ lib/libruntime/nativeglue.c Tue Feb 23 17:09:28 1999
@@ -345,6 +345,19 @@
 
   THREAD_INFO(new_frame)->return_value.value = args[0];
 
+  {
+    SigPrimType* tag = &THREAD_INFO(new_frame)->return_value.tag;
+    if(*tag == SIG_JCHAR
+       || *tag == SIG_JBYTE
+       || *tag == SIG_JSHORT
+       || *tag == SIG_JBOOLEAN) {
+         /* returned value is stored as a jint; neglecting to correct 
+            return_value.tag induces an incorrect promotion to jint 
+            in op_stack_push_value() on bigendian hosts */
+         *tag = SIG_JINT;
+       }
+  }
+
   maybe_push_return_value(new_frame);
   
   /* then pop the frame off */



Hope this helps,

--Christophe

Reply via email to