Did not compile on alpha
[cacao.git] / jit / parse.c
index 15874fb0987ec181acb33f6d4566845bcd4b056c..b6867ec3eb94abb664adca6924d7b0c0bd927804 100644 (file)
@@ -27,8 +27,9 @@
    Author: Andreas Krall
 
    Changes: Carolyn Oates
+            Edwin Steiner
 
-   $Id: parse.c 669 2003-11-23 14:04:20Z edwin $
+   $Id: parse.c 730 2003-12-11 21:23:31Z edwin $
 
 */
 
@@ -89,18 +90,20 @@ void compiler_addinitclass(classinfo *c)
                        return;
                if (cl == NULL) {
                        if (runverbose) {
+                               char logtext[MAXLOGTEXT];
                                sprintf(logtext, "compiler_addinitclass: ");
                                utf_sprint(logtext+strlen(logtext), c->name);
-                               dolog();
+                               log_text(logtext);
                        }
                        chain_addlast(uninitializedclasses, c);
                        return;
                }
                if (c < cl) {
                        if (runverbose) {
+                               char logtext[MAXLOGTEXT];
                                sprintf(logtext, "compiler_addinitclass: ");
                                utf_sprint(logtext+strlen(logtext), c->name);
-                               dolog();
+                               log_text(logtext);
                        }
                        chain_addbefore(uninitializedclasses, c);
                        return;
@@ -389,6 +392,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 +433,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) { \
@@ -479,9 +503,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 +558,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 +624,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 +637,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 +694,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 +793,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 +845,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 +897,7 @@ void parse()
                                        iswide = false;
                                        nextp = p + 5;
                                }
+                               INDEX_ONEWORD(i + firstlocal);
                                OP2I(opcode, i + firstlocal, v);
                        }
                        break;
@@ -866,28 +915,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");
                        }
@@ -902,11 +951,7 @@ void parse()
 
                                s_count++;
 
-#if defined(__I386__)
-                                       BUILTIN2((functionptr) asm_builtin_newarray, TYPE_ADR);
-#else
-                                       BUILTIN2((functionptr)builtin_newarray, TYPE_ADR);
-#endif
+                               BUILTIN2(BUILTIN_newarray, TYPE_ADR);
                        }
                        break;
 
@@ -977,7 +1022,7 @@ void parse()
                          break;
                          }*/
 
-                       OP1(opcode, i + firstlocal);
+                       OP1LOAD(opcode, i + firstlocal);
                        break;
 
                case JAVA_IRETURN:
@@ -1015,6 +1060,8 @@ void parse()
 
                                blockend = true;
                                nextp = ALIGN((p + 1), 4);
+                               if (nextp + 8 > jcodelength)
+                                       panic("Unexpected end of bytecode");
                                if (!useinlining) {
                                        tablep = (s4*)(jcode + nextp);
 
@@ -1043,6 +1090,9 @@ void parse()
                                tablep++;
                                nextp += 4;
 
+                               if (nextp + 8*(num) > jcodelength)
+                                       panic("Unexpected end of bytecode");
+
                                for (i = 0; i < num; i++) {
                                        /* value */
 
@@ -1074,6 +1124,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);
 
@@ -1111,6 +1163,9 @@ void parse()
 
                                num -= j;
 
+                               if (nextp + 4*(num+1) > jcodelength)
+                                       panic("Unexpected end of bytecode");
+
                                for (i = 0; i <= num; i++) {
                                        j = p + code_get_s4(nextp);
                                        if (useinlining)
@@ -1129,7 +1184,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:
@@ -1167,7 +1222,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(".");
@@ -1188,9 +1243,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);
@@ -1213,7 +1268,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);
@@ -1229,7 +1284,7 @@ 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:
@@ -1238,15 +1293,15 @@ void parse()
                                        classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
                                        if (cls->vftbl->arraydesc) {
                                                /* array type cast-check */
-                                               LOADCONST_A(cls->vftbl->arraydesc);
+                                               LOADCONST_A(cls->vftbl);
                                                s_count++;
-                                               BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
+                                               BUILTIN2(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);
++                                                BUILTIN2(BUILTIN_checkcast, TYPE_ADR);
 +                                              */
                                                OP2A(opcode, 1, cls);
                                        }
@@ -1261,19 +1316,15 @@ void parse()
                                        classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
                                        if (cls->vftbl->arraydesc) {
                                                /* array type cast-check */
-                                               LOADCONST_A(cls->vftbl->arraydesc);
+                                               LOADCONST_A(cls->vftbl);
                                                s_count++;
-  #if defined(__I386__)
-                                               BUILTIN2((functionptr) asm_builtin_arrayinstanceof, TYPE_INT);
-  #else
-                                               BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
-  #endif
+                                               BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT);
                                        }
                                        else { /* object type cast-check */
                                                /*
                                                  LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
                                                  s_count++;
-                                                 BUILTIN2((functionptr) builtin_instanceof, TYPE_INT);
+                                                 BUILTIN2(BUILTIN_instanceof, TYPE_INT);
 +                                              */
                                                OP2A(opcode, 1, cls);
                                        }
@@ -1283,7 +1334,7 @@ void parse()
                case JAVA_MONITORENTER:
 #ifdef USE_THREADS
                        if (checksync) {
-                               BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+                               BUILTIN1(BUILTIN_monitorenter, TYPE_VOID);
                        } else
 #endif
                                {
@@ -1294,7 +1345,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
@@ -1325,7 +1376,7 @@ void parse()
 #if defined(__I386__)
                        OP(opcode);
 #else
-                       BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
+                       BUILTIN2(BUILTIN_frem, TYPE_FLOAT);
 #endif
                        break;
 
@@ -1333,14 +1384,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
                                {
@@ -1351,7 +1402,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
                                {
@@ -1362,7 +1413,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
                                {
@@ -1373,7 +1424,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
                                {
@@ -1439,7 +1490,7 @@ void parse()
                case 254:
                case 255:
                        printf("Illegal opcode %d at instr %d", opcode, ipc);
-                       panic("encountered");
+                       panic("Illegal opcode encountered");
                        break;
 
                default:
@@ -1447,6 +1498,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 */
                  
@@ -1468,7 +1523,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");    
@@ -1515,6 +1570,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)