Include main.h for compiler switches.
[cacao.git] / jit / parse.c
index 5fd31c4bfadafb29a208b80eea535f77bda44707..4968afe3b4979d2ef242b74c78683f5c10623efd 100644 (file)
@@ -27,8 +27,9 @@
    Author: Andreas Krall
 
    Changes: Carolyn Oates
+            Edwin Steiner
 
-   $Id: parse.c 655 2003-11-20 14:52:00Z carolyn $
+   $Id: parse.c 843 2004-01-05 00:50:24Z twisti $
 
 */
 
@@ -36,6 +37,7 @@
 #include <string.h>
 #include "parse.h"
 #include "global.h"
+#include "main.h"
 #include "jit.h"
 #include "parseRT.h"
 #include "inline.h"
@@ -65,52 +67,6 @@ u1  *rt_jcode;           /* pointer to start of JavaVM-code            */
 #define debug_writebranch
 
 
-
-/* functionc compiler_addinitclass *********************************************
-
-       add class into the list of classes to initialize
-
-*******************************************************************************/
-                                
-void compiler_addinitclass(classinfo *c)
-{
-       classinfo *cl;
-
-       if (c->initialized) return;
-       
-       cl = chain_first(uninitializedclasses);
-       if (cl == c)
-               return;
-       
-       if (cl == class)
-               cl = chain_next(uninitializedclasses);
-       for (;;) {
-               if (cl == c)
-                       return;
-               if (cl == NULL) {
-                       if (runverbose) {
-                               sprintf(logtext, "compiler_addinitclass: ");
-                               utf_sprint(logtext+strlen(logtext), c->name);
-                               dolog();
-                       }
-                       chain_addlast(uninitializedclasses, c);
-                       return;
-               }
-               if (c < cl) {
-                       if (runverbose) {
-                               sprintf(logtext, "compiler_addinitclass: ");
-                               utf_sprint(logtext+strlen(logtext), c->name);
-                               dolog();
-                       }
-                       chain_addbefore(uninitializedclasses, c);
-                       return;
-               }
-               cl = chain_next(uninitializedclasses);
-       }
-}                       
-
-
-
 /* function descriptor2typesL ***************************************************
 
        decodes a already checked method descriptor. The parameter count, the
@@ -389,6 +345,26 @@ void descriptor2types(methodinfo *m)
 #define BUILTIN3(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
                        iptr->val.a=(v);PINC
 
+#define INDEX_ONEWORD(num)                                                                             \
+       do { if((num)<0 || (num)>=maxlocals)                                            \
+                       panic("Invalid local variable index"); } while (0)
+#define INDEX_TWOWORD(num)                                                                             \
+       do { if((num)<0 || ((num)+1)>=maxlocals)                                        \
+                       panic("Invalid local variable index"); } while (0)
+
+#define OP1LOAD(o,o1)                                                  \
+       do {if (o == ICMD_LLOAD || o == ICMD_DLOAD)     \
+                       INDEX_TWOWORD(o1);                                      \
+               else                                                                    \
+                       INDEX_ONEWORD(o1);                                      \
+               OP1(o,o1);} while(0)
+
+#define OP1STORE(o,o1)                                                         \
+       do {if (o == ICMD_LSTORE || o == ICMD_DSTORE)   \
+                       INDEX_TWOWORD(o1);                                              \
+               else                                                                            \
+                       INDEX_ONEWORD(o1);                                              \
+               OP1(o,o1);} while(0)
 
 /* block generating and checking macros */
 
@@ -410,6 +386,7 @@ void descriptor2types(methodinfo *m)
         } \
     } while (0)
 
+/* bound_check1 is used for the inclusive ends of exception handler ranges */
 #define bound_check1(i) \
     do { \
         if (i < 0 || i > cumjcodelength) { \
@@ -427,8 +404,8 @@ static xtable* fillextable(xtable* extable, exceptiontable *raw_extable, int exc
                return extable;
        
        b_count = *block_count;
+
        for (i = 0; i < exceptiontablelength; i++) {
-                                                                
                p = raw_extable[i].startpc;
                if (label_index != NULL) p = label_index[p];
                extable[i].startpc = p;
@@ -436,6 +413,8 @@ static xtable* fillextable(xtable* extable, exceptiontable *raw_extable, int exc
                block_insert(p);
                
                p = raw_extable[i].endpc;
+               if (p <= raw_extable[i].startpc)
+                       panic("Invalid exception handler range");
                if (label_index != NULL) p = label_index[p];
                extable[i].endpc = p;
                bound_check1(p);
@@ -451,8 +430,9 @@ static xtable* fillextable(xtable* extable, exceptiontable *raw_extable, int exc
                extable[i].catchtype  = raw_extable[i].catchtype;
 
                extable[i].next = NULL;
-               extable[i].down = &extable[i+1];
-               }
+               extable[i].down = &extable[i + 1];
+       }
+
        *block_count = b_count;
        return &extable[i];  /* return the next free xtable* */
 }
@@ -479,9 +459,20 @@ void parse()
        int *label_index = NULL;    /* label redirection table                    */
        int firstlocal = 0;         /* first local variable of method             */
        xtable* nextex;             /* points next free entry in extable          */
+       u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
 
        bool useinltmp;
 
+       if (compileverbose) {
+               char logtext[MAXLOGTEXT];
+               sprintf(logtext, "Parsing: ");
+               utf_sprint(logtext+strlen(logtext), method->class->name);
+               strcpy(logtext+strlen(logtext), ".");
+               utf_sprint(logtext+strlen(logtext), method->name);
+               utf_sprint(logtext+strlen(logtext), method->descriptor);
+               log_text(logtext);
+       }
+
        /* INLINING */
        if (useinlining) {
                label_index = inlinfo->label_index;
@@ -523,11 +514,16 @@ void parse()
        /* 1 additional for end ipc and 3 for loop unrolling */
        
        block_index = DMNEW(int, cumjcodelength + 4);
+       instructionstart = DMNEW(u1, cumjcodelength + 4);
+       memset(instructionstart,0,sizeof(u1) * (cumjcodelength + 4));
 
        /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
        /* additional MONITOREXITS are reached by branches which are 3 bytes */
        
        iptr = instr = DMNEW(instruction, cumjcodelength + 5);
+
+       /* XXX zero fields in the instructions loop? */
+       memset(iptr,0,sizeof(instruction) * (cumjcodelength + 5));
        
        /* initialize block_index table (unrolled four times) */
 
@@ -584,7 +580,11 @@ void parse()
 
        for (p = 0, gp = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
          
-               /* DEBUG          printf("p:%d gp:%d ",p,gp); */
+               /* DEBUG XXX */   /*printf("p:%d gp:%d ",p,gp);*/
+
+               /* mark this position as a valid instruction start */
+               if (!iswide)
+                       instructionstart[p] = 1;
 
                /*INLINING*/
                if ((useinlining) && (gp == nextgp)) {
@@ -593,6 +593,8 @@ void parse()
 
                        opcode = code_get_u1(p);
                        nextp = p += jcommandsize[opcode];
+                       if (nextp > jcodelength)
+                               panic("Unexpected end of bytecode");
                        tmpinlinf = list_first(inlinfo->inlinedmethods);
                        firstlocal = tmpinlinf->firstlocal;
                        label_index = tmpinlinf->label_index;
@@ -648,6 +650,8 @@ void parse()
                }
 
                nextp = p + jcommandsize[opcode];   /* compute next instruction start */
+               if (nextp > jcodelength)
+                       panic("Unexpected end of bytecode");
                s_count += stackreq[opcode];            /* compute stack element count    */
 
                switch (opcode) {
@@ -745,42 +749,42 @@ void parse()
                                nextp = p + 3;
                                iswide = false;
                        }
-                       OP1(opcode, i + firstlocal);
+                       OP1LOAD(opcode, i + firstlocal);
                        break;
 
                case JAVA_ILOAD_0:
                case JAVA_ILOAD_1:
                case JAVA_ILOAD_2:
                case JAVA_ILOAD_3:
-                       OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
+                       OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
                        break;
 
                case JAVA_LLOAD_0:
                case JAVA_LLOAD_1:
                case JAVA_LLOAD_2:
                case JAVA_LLOAD_3:
-                       OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
+                       OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
                        break;
 
                case JAVA_FLOAD_0:
                case JAVA_FLOAD_1:
                case JAVA_FLOAD_2:
                case JAVA_FLOAD_3:
-                       OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
+                       OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
                        break;
 
                case JAVA_DLOAD_0:
                case JAVA_DLOAD_1:
                case JAVA_DLOAD_2:
                case JAVA_DLOAD_3:
-                       OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
+                       OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
                        break;
 
                case JAVA_ALOAD_0:
                case JAVA_ALOAD_1:
                case JAVA_ALOAD_2:
                case JAVA_ALOAD_3:
-                       OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
+                       OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
                        break;
 
                        /* storing stack values into local variables */
@@ -797,42 +801,42 @@ void parse()
                                iswide = false;
                                nextp = p + 3;
                        }
-                       OP1(opcode, i + firstlocal);
+                       OP1STORE(opcode, i + firstlocal);
                        break;
 
                case JAVA_ISTORE_0:
                case JAVA_ISTORE_1:
                case JAVA_ISTORE_2:
                case JAVA_ISTORE_3:
-                       OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
+                       OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
                        break;
 
                case JAVA_LSTORE_0:
                case JAVA_LSTORE_1:
                case JAVA_LSTORE_2:
                case JAVA_LSTORE_3:
-                       OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
+                       OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
                        break;
 
                case JAVA_FSTORE_0:
                case JAVA_FSTORE_1:
                case JAVA_FSTORE_2:
                case JAVA_FSTORE_3:
-                       OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
+                       OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
                        break;
 
                case JAVA_DSTORE_0:
                case JAVA_DSTORE_1:
                case JAVA_DSTORE_2:
                case JAVA_DSTORE_3:
-                       OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
+                       OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
                        break;
 
                case JAVA_ASTORE_0:
                case JAVA_ASTORE_1:
                case JAVA_ASTORE_2:
                case JAVA_ASTORE_3:
-                       OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
+                       OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
                        break;
 
                case JAVA_IINC:
@@ -849,6 +853,7 @@ void parse()
                                        iswide = false;
                                        nextp = p + 5;
                                }
+                               INDEX_ONEWORD(i + firstlocal);
                                OP2I(opcode, i + firstlocal, v);
                        }
                        break;
@@ -866,28 +871,28 @@ void parse()
                        OP2I(ICMD_CHECKASIZE, 0, 0);
                        switch (code_get_s1(p + 1)) {
                        case 4:
-                               BUILTIN1((functionptr) builtin_newarray_boolean, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_boolean, TYPE_ADR);
                                break;
                        case 5:
-                               BUILTIN1((functionptr) builtin_newarray_char, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_char, TYPE_ADR);
                                break;
                        case 6:
-                               BUILTIN1((functionptr) builtin_newarray_float, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_float, TYPE_ADR);
                                break;
                        case 7:
-                               BUILTIN1((functionptr) builtin_newarray_double, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_double, TYPE_ADR);
                                break;
                        case 8:
-                               BUILTIN1((functionptr) builtin_newarray_byte, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_byte, TYPE_ADR);
                                break;
                        case 9:
-                               BUILTIN1((functionptr) builtin_newarray_short, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_short, TYPE_ADR);
                                break;
                        case 10:
-                               BUILTIN1((functionptr) builtin_newarray_int, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_int, TYPE_ADR);
                                break;
                        case 11:
-                               BUILTIN1((functionptr) builtin_newarray_long, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_long, TYPE_ADR);
                                break;
                        default: panic("Invalid array-type to create");
                        }
@@ -896,25 +901,13 @@ void parse()
                case JAVA_ANEWARRAY:
                        OP2I(ICMD_CHECKASIZE, 0, 0);
                        i = code_get_u2(p + 1);
-                       /* array or class type ? */
-                       if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
-                               s_count++;
-                               LOADCONST_A(class_getconstant(class, i,
-                                                                                         CONSTANT_Arraydescriptor));
-#if defined(__I386__)
-                               BUILTIN2((functionptr) asm_builtin_newarray_array, TYPE_ADR);
-#else
-                               BUILTIN2((functionptr) builtin_newarray_array, TYPE_ADR);
-#endif
-                       }
-                       else {
-                               LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+                       {
+                                       classinfo *component = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
+                                       LOADCONST_A(class_array_of(component)->vftbl);
+
                                s_count++;
-#if defined(__I386__)
-                               BUILTIN2((functionptr) asm_builtin_anewarray, TYPE_ADR);
-#else
-                               BUILTIN2((functionptr) builtin_anewarray, TYPE_ADR);
-#endif
+
+                               BUILTIN2(BUILTIN_newarray, TYPE_ADR);
                        }
                        break;
 
@@ -923,9 +916,8 @@ void parse()
                        i = code_get_u2(p + 1);
                        {
                                int v = code_get_u1(p + 3);
-                               constant_arraydescriptor *desc =
-                                   class_getconstant (class, i, CONSTANT_Arraydescriptor);
-                               OP2A(opcode, v, desc);
+                               vftbl *arrayvftbl = ((classinfo*)class_getconstant (class, i, CONSTANT_Class))->vftbl;
+                               OP2A(opcode, v, arrayvftbl);                    
                        }
                        break;
 
@@ -986,7 +978,7 @@ void parse()
                          break;
                          }*/
 
-                       OP1(opcode, i + firstlocal);
+                       OP1LOAD(opcode, i + firstlocal);
                        break;
 
                case JAVA_IRETURN:
@@ -1021,9 +1013,12 @@ void parse()
                        {
                                s4 num, j;
                                s4 *tablep;
+                               s4 prevvalue;
 
                                blockend = true;
                                nextp = ALIGN((p + 1), 4);
+                               if (nextp + 8 > jcodelength)
+                                       panic("Unexpected end of bytecode");
                                if (!useinlining) {
                                        tablep = (s4*)(jcode + nextp);
 
@@ -1052,6 +1047,9 @@ void parse()
                                tablep++;
                                nextp += 4;
 
+                               if (nextp + 8*(num) > jcodelength)
+                                       panic("Unexpected end of bytecode");
+
                                for (i = 0; i < num; i++) {
                                        /* value */
 
@@ -1060,6 +1058,12 @@ void parse()
                                        tablep++;
                                        nextp += 4;
 
+                                       /* check if the lookup table is sorted correctly */
+                                       
+                                       if (i && (j <= prevvalue))
+                                               panic("invalid LOOKUPSWITCH: table not sorted");
+                                       prevvalue = j;
+
                                        /* target */
 
                                        j = p + code_get_s4(nextp);
@@ -1083,6 +1087,8 @@ void parse()
 
                                blockend = true;
                                nextp = ALIGN((p + 1), 4);
+                               if (nextp + 12 > jcodelength)
+                                       panic("Unexpected end of bytecode");
                                if (!useinlining) {
                                        tablep = (s4*)(jcode + nextp);
 
@@ -1118,7 +1124,12 @@ void parse()
                                tablep++;
                                nextp += 4;
 
-                               num -= j;
+                               num -= j;  /* difference of upper - lower */
+                               if (num < 0)
+                                       panic("invalid TABLESWITCH: upper bound < lower bound");
+
+                               if (nextp + 4*(num+1) > jcodelength)
+                                       panic("Unexpected end of bytecode");
 
                                for (i = 0; i <= num; i++) {
                                        j = p + code_get_s4(nextp);
@@ -1138,7 +1149,7 @@ void parse()
                        /* load and store of object fields *******************/
 
                case JAVA_AASTORE:
-                       BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
+                       BUILTIN3(BUILTIN_aastore, TYPE_VOID);
                        break;
 
                case JAVA_PUTSTATIC:
@@ -1147,9 +1158,8 @@ void parse()
                        {
                                constant_FMIref *fr;
                                fieldinfo *fi;
-                               fr = class_getconstant (class, i, CONSTANT_Fieldref);
-                               fi = class_findfield (fr->class, fr->name, fr->descriptor);
-                               compiler_addinitclass (fr->class);
+                               fr = class_getconstant(class, i, CONSTANT_Fieldref);
+                               fi = class_findfield(fr->class, fr->name, fr->descriptor);
                                OP2A(opcode, fi->type, fi);
                        }
                        break;
@@ -1176,7 +1186,7 @@ void parse()
                                methodinfo *mi;
                                
                                mr = class_getconstant (class, i, CONSTANT_Methodref);
-                               mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+                               mi = class_fetchmethod (mr->class, mr->name, mr->descriptor);
                                /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
                                        /*RTAprint*/    {printf(" method name =");
                                        /*RTAprint*/    utf_display(mi->class->name); printf(".");
@@ -1197,9 +1207,9 @@ void parse()
                        {
                                constant_FMIref *mr;
                                methodinfo *mi;
-                               
+
                                mr = class_getconstant (class, i, CONSTANT_Methodref);
-                               mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+                               mi = class_fetchmethod (mr->class, mr->name, mr->descriptor);
                                /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
                                        /*RTAprint*/    {printf(" method name =");
                                        method_display(mi);
@@ -1222,7 +1232,7 @@ void parse()
                                methodinfo *mi;
                                
                                mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
-                               mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+                               mi = class_fetchmethod (mr->class, mr->name, mr->descriptor);
                                if (mi->flags & ACC_STATIC)
                                        panic ("Static/Nonstatic mismatch calling static method");
                                descriptor2types(mi);
@@ -1238,55 +1248,63 @@ void parse()
 
                        LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
                        s_count++;
-                       BUILTIN1((functionptr) builtin_new, TYPE_ADR);
+                       BUILTIN1(BUILTIN_new, TYPE_ADR);
                        break;
 
                case JAVA_CHECKCAST:
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+                       isleafmethod = false;
+#endif
                        i = code_get_u2(p+1);
+                               {
+                                       classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
+                                       if (cls->vftbl->arraydesc) {
+                                               /* array type cast-check */
+                                               LOADCONST_A(cls->vftbl);
+                                               s_count++;
+                                               BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR);
+                                       }
+                                       else { /* object type cast-check */
+                                               /*
++                                                LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
++                                                s_count++;
++                                                BUILTIN2(BUILTIN_checkcast, TYPE_ADR);
++                                              */
+                                               OP2A(opcode, 1, cls);
+                                       }
+                               }
 
-                       /* array type cast-check */
-                       if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
-                               LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
-                               s_count++;
-                               BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
-                       }
-                       else { /* object type cast-check */
-                               /*
-                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
-                                 s_count++;
-                                 BUILTIN2((functionptr) asm_builtin_checkcast, TYPE_ADR);
-                               */
-                               OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
-                       }
                        break;
 
                case JAVA_INSTANCEOF:
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+                       isleafmethod = false;
+#endif
                        i = code_get_u2(p+1);
 
-                       /* array type cast-check */
-                       if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
-                               LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
-                               s_count++;
-#if defined(__I386__)
-                               BUILTIN2((functionptr) asm_builtin_arrayinstanceof, TYPE_INT);
-#else
-                               BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
-#endif
-                       }
-                       else { /* object type cast-check */
-                               /*
-                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
-                                 s_count++;
-                                 BUILTIN2((functionptr) builtin_instanceof, TYPE_INT);
-                               */
-                               OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
-                       }
+                               {
+                                       classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
+                                       if (cls->vftbl->arraydesc) {
+                                               /* array type cast-check */
+                                               LOADCONST_A(cls->vftbl);
+                                               s_count++;
+                                               BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT);
+                                       }
+                                       else { /* object type cast-check */
+                                               /*
+                                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+                                                 s_count++;
+                                                 BUILTIN2(BUILTIN_instanceof, TYPE_INT);
++                                              */
+                                               OP2A(opcode, 1, cls);
+                                       }
+                               }
                        break;
 
                case JAVA_MONITORENTER:
 #ifdef USE_THREADS
                        if (checksync) {
-                               BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+                               BUILTIN1(BUILTIN_monitorenter, TYPE_VOID);
                        } else
 #endif
                                {
@@ -1297,7 +1315,7 @@ void parse()
                case JAVA_MONITOREXIT:
 #ifdef USE_THREADS
                        if (checksync) {
-                               BUILTIN1((functionptr) asm_builtin_monitorexit, TYPE_VOID);
+                               BUILTIN1(BUILTIN_monitorexit, TYPE_VOID);
                        }
                        else
 #endif
@@ -1328,7 +1346,7 @@ void parse()
 #if defined(__I386__)
                        OP(opcode);
 #else
-                       BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
+                       BUILTIN2(BUILTIN_frem, TYPE_FLOAT);
 #endif
                        break;
 
@@ -1336,14 +1354,14 @@ void parse()
 #if defined(__I386__)
                        OP(opcode);
 #else
-                       BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
+                       BUILTIN2(BUILTIN_drem, TYPE_DOUBLE);
 #endif
                        break;
 
                case JAVA_F2I:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
-                               BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
+                               BUILTIN1(BUILTIN_f2i, TYPE_INT);
                        } else
 #endif
                                {
@@ -1354,7 +1372,7 @@ void parse()
                case JAVA_F2L:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
-                               BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
+                               BUILTIN1(BUILTIN_f2l, TYPE_LONG);
                        } else 
 #endif
                                {
@@ -1365,7 +1383,7 @@ void parse()
                case JAVA_D2I:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
-                               BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
+                               BUILTIN1(BUILTIN_d2i, TYPE_INT);
                        } else
 #endif
                                {
@@ -1376,7 +1394,7 @@ void parse()
                case JAVA_D2L:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
-                               BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
+                               BUILTIN1(BUILTIN_d2l, TYPE_LONG);
                        } else
 #endif
                                {
@@ -1388,6 +1406,7 @@ void parse()
                        panic("Illegal opcode Breakpoint encountered");
                        break;
 
+                 case 186: /* unused opcode */
                case 203:
                case 204:
                case 205:
@@ -1441,8 +1460,8 @@ void parse()
                case 253:
                case 254:
                case 255:
-                       printf("Illegal opcode %d at instr %d", opcode, ipc);
-                       panic("encountered");
+                       printf("Illegal opcode %d at instr %d\n", opcode, ipc);
+                       panic("Illegal opcode encountered");
                        break;
 
                default:
@@ -1450,6 +1469,10 @@ void parse()
                        break;
                                
                } /* end switch */
+
+               /* If WIDE was used correctly, iswide should have been reset by now. */
+               if (iswide && opcode != JAVA_WIDE)
+                       panic("Illegal instruction: WIDE before incompatible opcode");
                
                /* INLINING */
                  
@@ -1471,7 +1494,7 @@ void parse()
        } /* end for */
 
        if (p != jcodelength)
-               panic("Command-sequence crosses code-boundary");
+               panic("Command-sequence crosses code-boundary"); /* XXX change message */
 
        if (!blockend)
                panic("Code does not end with branch/return/athrow - stmt");    
@@ -1518,6 +1541,10 @@ void parse()
 
                for (p = 0; p < cumjcodelength; p++) {
                        if (block_index[p] & 1) {
+                               /* check if this block starts at the beginning of an instruction */
+                               if (!instructionstart[p])
+                                       panic("Branch into middle of instruction");
+                               /* allocate the block */
                                bptr->iinstr = instr + (block_index[p] >> 1);
                                bptr->debug_nr = c_debug_nr++;
                                if (b_count != 0)