Lazy checkcast and instanceof.
[cacao.git] / src / vm / jit / parse.c
index 19c94d045c0ab34c0171723ffeb0f144d4a17366..8667ff12537956e79c432bbbff64a80539000309 100644 (file)
@@ -1,4 +1,4 @@
-/* vm/jit/parse.c - parser for JavaVM to intermediate code translation
+/* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
 
    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
@@ -29,8 +29,9 @@
    Changes: Carolyn Oates
             Edwin Steiner
             Joseph Wenninger
+            Christian Thalinger
 
-   $Id: parse.c 1971 2005-03-01 20:06:36Z carolyn $
+   $Id: parse.c 2272 2005-04-11 15:49:51Z twisti $
 
 */
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
+#include "vm/linker.h"
 #include "vm/loader.h"
+#include "vm/resolve.h"
 #include "vm/options.h"
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
 #include "vm/tables.h"
+#include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/inline/parseRT.h"
@@ -68,269 +72,6 @@ bool DEBUG4 = false;  /*opcodes for parse.c*/
 #define debug_writebranch if (DEBUG2==true) printf("op:: %s i: %d label_index[i]: %d label_index=0x%p\n",opcode_names[opcode], i, label_index[i], (void *)label_index);
 #define debug_writebranch1
 
-
-/* function descriptor2typesL ***************************************************
-
-       decodes a already checked method descriptor. The parameter count, the
-       return type and the argument types are stored in the passed methodinfo.
-        gets and saves classptr for object ref.s
-
-*******************************************************************************/               
-
-classSetNode *descriptor2typesL(methodinfo *m)
-{
-       int debugInfo = 0;
-       int i;
-       u1 *types, *tptr;
-       int pcount, c;
-       char *utf_ptr;
-       classinfo** classtypes;
-       char *class; 
-       char *desc;
-       classSetNode *p=NULL;
-       if (debugInfo >= 1) {
-               printf("In descriptor2typesL >>>\t"); fflush(stdout);
-               utf_display(m->class->name); printf(".");
-               method_display(m);fflush(stdout);
-       }
-
-       pcount = 0;
-       desc =       MNEW (char, 256); 
-       types = DMNEW (u1, m->descriptor->blength); 
-       classtypes = MNEW (classinfo*, m->descriptor->blength+1);
-       m->returnclass = NULL;
-       tptr = types;
-       if (!(m->flags & ACC_STATIC)) {
-               *tptr++ = TYPE_ADR;
-               if (debugInfo >= 1) {
-                       printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
-               }
-               classtypes[pcount] = m->class;
-               p = addClassCone(p,  m->class);
-               pcount++;
-       }
-
-       utf_ptr = m->descriptor->text + 1;
-       strcpy (desc,utf_ptr);
-   
-       while ((c = *desc++) != ')') {
-               pcount++;
-               switch (c) {
-               case 'B':
-               case 'C':
-               case 'I':
-               case 'S':
-               case 'Z':  *tptr++ = TYPE_INT;
-                       break;
-               case 'J':  *tptr++ = TYPE_LNG;
-                       break;
-               case 'F':  *tptr++ = TYPE_FLT;
-                       break;
-               case 'D':  *tptr++ = TYPE_DBL;
-                       break;
-               case 'L':  *tptr++ = TYPE_ADR;
-                       /* get class string */
-                       class = strtok(desc,";");
-                       desc = strtok(NULL,"\0");
-                       /* get/save classinfo ptr */
-                       classtypes[pcount-1] = class_get(utf_new_char(class));
-                       p = addClassCone(p,  class_get(utf_new_char(class)));
-                       if (debugInfo >= 1) {
-                               printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
-                               printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
-                               utf_display(classtypes[pcount-1]->name);
-                       }
-                       break;
-               case '[':  *tptr++ = TYPE_ADR;
-                       while (c == '[')
-                               c = *desc++;
-                       /* get class string */
-                       if (c == 'L') {
-                               class = strtok(desc,";");
-                               desc = strtok(NULL,"\0");
-                               /* get/save classinfo ptr */
-                               classtypes[pcount-1] = class_get(utf_new_char(class));
-                               p= addClassCone(p,  class_get(utf_new_char(class)));
-                               if (debugInfo >= 1) {
-                                       printf("[Param#%i 's class type is: %s\n",pcount-1,class);
-                                       printf("[classtypes[%i]=",pcount-1);fflush(stdout);
-                                       utf_display(classtypes[pcount-1]->name);
-                                       printf("\n");
-                               }
-                       }
-                       else
-                               classtypes[pcount-1] = NULL;
-                       break;
-               default:   
-                       panic("Ill formed methodtype-descriptor");
-               }
-       }
-
-       /* compute return type */
-       switch (*desc++) {
-       case 'B':
-       case 'C':
-       case 'I':
-       case 'S':
-       case 'Z':  m->returntype = TYPE_INT;
-               break;
-       case 'J':  m->returntype = TYPE_LNG;
-               break;
-       case 'F':  m->returntype = TYPE_FLT;
-               break;
-       case 'D':  m->returntype = TYPE_DBL;
-               break;
-       case '[':
-               m->returntype = TYPE_ADR;
-               c = *desc;
-               while (c == '[') {
-                       c = *desc++;
-                       }
-               if (c != 'L') break;
-               c = *desc;
-               if (c == 'L')
-                       *(desc++); 
-       case 'L':  
-               m->returntype = TYPE_ADR;
-                         
-               /* get class string */
-               class = strtok(desc,";");
-               m->returnclass = class_get(utf_new_char(class));
-               if (m->returnclass == NULL) {
-                       printf("class=<%s>\t",class); fflush(stdout);
-                       panic ("return class not found");
-               }
-               break;
-       case 'V':  m->returntype = TYPE_VOID;
-               break;
-
-       default:   panic("Ill formed methodtype-descriptor-ReturnType");
-       }
-
-       m->paramcount = pcount;
-       m->paramtypes = types;
-       m->paramclass = classtypes;
-
-       if (debugInfo >=1) {
-               if (pcount > 0) {
-                       for (i=0; i< m->paramcount; i++) {
-                       if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
-                                       printf("Param #%i is:\t",i);
-                                       utf_display(m->paramclass[i]->name);
-                                       printf("\n");
-                               }
-                       }
-               }
-               if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) { 
-                       printf("\tReturn Type is:\t"); fflush(stdout);
-                       utf_display(m->returnclass->name);
-                       printf("\n");
-               }
-
-               printf("params2types: START  results in a set \n");
-               printf("param2types: A Set size=%i=\n",sizeOfSet(p));
-               printSet(p);
-       }
-
-       return p;
-}
-
-
-
-/* function descriptor2types ***************************************************
-
-       decodes a already checked method descriptor. The parameter count, the
-       return type and the argument types are stored in the passed methodinfo.
-
-*******************************************************************************/               
-
-void descriptor2types(methodinfo *m)
-{
-       u1 *types, *tptr;
-       int pcount, c;
-       char *utf_ptr;
-       pcount = 0;
-       types = DMNEW(u1, m->descriptor->blength); 
-       
-       tptr = types;
-       if (!(m->flags & ACC_STATIC)) {
-               *tptr++ = TYPE_ADR;
-               pcount++;
-       }
-
-       utf_ptr = m->descriptor->text + 1;
-   
-       while ((c = *utf_ptr++) != ')') {
-               pcount++;
-               switch (c) {
-               case 'B':
-               case 'C':
-               case 'I':
-               case 'S':
-               case 'Z':
-                       *tptr++ = TYPE_INT;
-                       break;
-               case 'J':
-                       *tptr++ = TYPE_LNG;
-                       break;
-               case 'F':
-                       *tptr++ = TYPE_FLT;
-                       break;
-               case 'D':
-                       *tptr++ = TYPE_DBL;
-                       break;
-               case 'L':
-                       *tptr++ = TYPE_ADR;
-                       while (*utf_ptr++ != ';');
-                       break;
-               case '[':
-                       *tptr++ = TYPE_ADR;
-                       while (c == '[')
-                               c = *utf_ptr++;
-                       if (c == 'L')
-                               while (*utf_ptr++ != ';') /* skip */;
-                       break;
-               default:
-                       panic("Ill formed methodtype-descriptor");
-               }
-       }
-
-       /* compute return type */
-
-       switch (*utf_ptr++) {
-       case 'B':
-       case 'C':
-       case 'I':
-       case 'S':
-       case 'Z':
-               m->returntype = TYPE_INT;
-               break;
-       case 'J':
-               m->returntype = TYPE_LNG;
-               break;
-       case 'F':
-               m->returntype = TYPE_FLT;
-               break;
-       case 'D':
-               m->returntype = TYPE_DBL;
-               break;
-       case '[':
-       case 'L':
-               m->returntype = TYPE_ADR;
-               break;
-       case 'V':
-               m->returntype = TYPE_VOID;
-               break;
-       default:
-               panic("Ill formed methodtype-descriptor");
-       }
-
-       m->paramcount = pcount;
-       m->paramtypes = types;
-}
-
-
-
 /*******************************************************************************
 
        function 'parse' scans the JavaVM code and generates intermediate code
@@ -699,7 +440,7 @@ SHOWOPCODE(DEBUG4)
                pushconstantitem:
 
                        if (i >= inline_env->method->class->cpcount) 
-                               panic ("Attempt to access constant outside range");
+                               error("Attempt to access constant outside range: %d >= %d", i, inline_env->method->class->cpcount);
 
                        switch (inline_env->method->class->cptags[i]) {
                        case CONSTANT_Integer:
@@ -919,43 +660,79 @@ SHOWOPCODE(DEBUG4)
                        OP(ICMD_CHECKASIZE);
                        i = code_get_u2(p + 1,inline_env->method);
                        {
-                               classinfo *component =
-                                       (classinfo *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+                               classinfo *component;
+                               constant_classref *compr;
+                               constant_classref *cr;
+                               classinfo         *c;
+
+#if defined(__X86_64__)
+                               compr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+
+                               if (!(cr = class_get_classref_multiarray_of(1, compr)))
+                                       return NULL;
 
-                               if (!class_load(component))
+                               if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &c))
                                        return NULL;
 
-                               if (!class_link(component))
+                               if (c) {
+                                       LOADCONST_A_BUILTIN(c->vftbl);
+                                       BUILTIN2(BUILTIN_newarray, TYPE_ADR, currentline);
+
+                               } else {
+                                       LOADCONST_A_BUILTIN(cr);
+                                       BUILTIN2(asm_BUILTIN_newarray, TYPE_ADR, currentline);
+                               }
+                               s_count++;
+#else
+                               cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+
+                               if (!resolve_classref(inline_env->method,
+                                                       cr,resolveEager,true,&component))
                                        return NULL;
 
-                               LOADCONST_A_BUILTIN(class_array_of(component)->vftbl);
-/*                             LOADCONST_A_BUILTIN(component); */
+                               c = class_array_of(component,true);
+                               if (!c)
+                                       return NULL;
+                               LOADCONST_A_BUILTIN(c->vftbl);
                                s_count++;
                                BUILTIN2(BUILTIN_newarray, TYPE_ADR, currentline);
+#endif
                        }
                        OP(ICMD_CHECKEXCEPTION);
                        break;
 
                case JAVA_MULTIANEWARRAY:
                        inline_env->method->isleafmethod = false;
-                       i = code_get_u2(p + 1,inline_env->method);
+                       i = code_get_u2(p + 1, inline_env->method);
                        {
+                               classinfo *component;
+                               classinfo *c;
+                           constant_classref *cr;
                                vftbl_t *arrayvftbl;
-                               s4 v = code_get_u1(p + 3,inline_env->method);
+                               s4 v = code_get_u1(p + 3, inline_env->method);
 
-                               
+#if defined(__X86_64__)
+                               cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+
+                               if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &c))
+                                       return NULL;
+
+                               if (c) {
+                                       OP2AT(opcode, v, c->vftbl, BUILTIN_nmultianewarray, currentline);
+
+                               } else {
+                                       OP2AT(opcode, v, cr, asm_BUILTIN_multianewarray, currentline);
+                               }
+#else
 /*                             vftbl *arrayvftbl = */
 /*                                     ((classinfo *) class_getconstant(class, i, CONSTANT_Class))->vftbl; */
 /*                             OP2A(opcode, v, arrayvftbl,currentline); */
 
                                
-                               classinfo *component =
-                                       (classinfo *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+                               cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
 
-                               if (!class_load(component))
-                                       return NULL;
-
-                               if (!class_link(component))
+                               if (!resolve_classref_or_classinfo(inline_env->method,
+                                                       CLASSREF_OR_CLASSINFO(cr),resolveEager,true,&component))
                                        return NULL;
 
                                arrayvftbl = component->vftbl;
@@ -964,6 +741,7 @@ SHOWOPCODE(DEBUG4)
 /*                             classinfo *arrayclass = */
 /*                                     (classinfo *) class_getconstant(class, i, CONSTANT_Class); */
 /*                             OP2A(opcode, v, arrayclass, currentline); */
+#endif
                        }
                        break;
 
@@ -1115,8 +893,10 @@ SHOWOPCODE(DEBUG4)
 
                                        /* check if the lookup table is sorted correctly */
                                        
-                                       if (i && (j <= prevvalue))
-                                               panic("invalid LOOKUPSWITCH: table not sorted");
+                                       if (i && (j <= prevvalue)) {
+                                               *exceptionptr = new_verifyerror(m, "Unsorted lookup switch");
+                                               return NULL;
+                                       }
                                        prevvalue = j;
 
                                        /* target */
@@ -1210,22 +990,49 @@ SHOWOPCODE(DEBUG4)
                        BUILTIN3(BUILTIN_aastore, TYPE_VOID, currentline);
                        break;
 
-               case JAVA_PUTSTATIC:
                case JAVA_GETSTATIC:
-                       i = code_get_u2(p + 1,inline_env->method);
+               case JAVA_PUTSTATIC:
+#if defined(__X86_64__)
+               case JAVA_GETFIELD:
+               case JAVA_PUTFIELD:
+#endif
+                       i = code_get_u2(p + 1, inline_env->method);
                        {
-                               constant_FMIref *fr;
-                               fieldinfo *fi;
+                               constant_FMIref  *fr;
+                               unresolved_field *uf;
+                               fieldinfo        *fi;
+                               classinfo        *c;
 
                                fr = class_getconstant(inline_env->method->class, i, CONSTANT_Fieldref);
+#if defined(__X86_64__)
+                               OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
 
-                               if (!class_load(fr->class))
+                               if (!(uf = create_unresolved_field(inline_env->method->class,
+                                                                                                  inline_env->method,
+                                                                                                  iptr,
+                                                                                                  NULL)))
                                        return NULL;
 
-                               if (!class_link(fr->class))
+                               /* store unresolved_field pointer */
+
+                               iptr->target = uf;
+
+                               /* only with -noverify, otherwise the typechecker does this */
+
+                               if (!opt_verify) {
+                                       if (!resolve_field(uf, resolveLazy, &fi))
+                                               return NULL;
+
+                                       iptr->val.a = fi;
+                               }
+                               PINC;
+#else
+                               {
+                               classinfo *frclass;
+                               if (!resolve_classref(inline_env->method,fr->classref,resolveEager,true,&frclass))
                                        return NULL;
 
-                               fi = class_resolvefield(fr->class,
+                               fi = class_resolvefield(frclass,
                                                                                fr->name,
                                                                                fr->descriptor,
                                                                                inline_env->method->class,
@@ -1238,25 +1045,25 @@ SHOWOPCODE(DEBUG4)
                                if (!fi->class->initialized) {
                                        inline_env->method->isleafmethod = false;
                                }
+                               }
+#endif
                        }
                        break;
 
+#if !defined(__X86_64__)
                case JAVA_PUTFIELD:
                case JAVA_GETFIELD:
                        i = code_get_u2(p + 1,inline_env->method);
                        {
                                constant_FMIref *fr;
                                fieldinfo *fi;
+                               classinfo *frclass;
 
                                fr = class_getconstant(inline_env->method->class, i, CONSTANT_Fieldref);
-
-                               if (!class_load(fr->class))
-                                       return NULL;
-
-                               if (!class_link(fr->class))
+                               if (!resolve_classref(inline_env->method,fr->classref,resolveEager,true,&frclass))
                                        return NULL;
 
-                               fi = class_resolvefield(fr->class,
+                               fi = class_resolvefield(frclass,
                                                                                fr->name,
                                                                                fr->descriptor,
                                                                                inline_env->method->class,
@@ -1268,27 +1075,51 @@ SHOWOPCODE(DEBUG4)
                                OP2A(opcode, fi->type, fi, currentline);
                        }
                        break;
+#endif
 
 
                        /* method invocation *****/
 
                case JAVA_INVOKESTATIC:
-                       i = code_get_u2(p + 1,inline_env->method);
+                       i = code_get_u2(p + 1, inline_env->method);
                        {
                                constant_FMIref *mr;
                                methodinfo *mi;
-                               
+                               unresolved_method *um;
+                               classinfo *mrclass;
+
                                inline_env->method->isleafmethod = false;
 
                                mr = class_getconstant(inline_env->method->class, i, CONSTANT_Methodref);
+#if defined(__X86_64__)
+                               OP2A_NOINC(opcode, mr->parseddesc.md->paramcount, mr, currentline);
+
+                               um = create_unresolved_method(inline_env->method->class,
+                                                                                         inline_env->method,
+                                                                                         iptr,
+                                                                                         NULL);
 
-                               if (!class_load(mr->class))
+                               if (!um)
                                        return NULL;
 
-                               if (!class_link(mr->class))
+                               /* store the unresolved_method pointer */
+
+                               iptr->target = um;
+
+                               /* only with -noverify, otherwise the typechecker does this */
+
+                               if (!opt_verify) {
+                                       if (!resolve_method(um, resolveLazy, &mi))
+                                               return NULL;
+
+                                       iptr->val.a = mi;
+                               }
+                               PINC;
+#else
+                               if (!resolve_classref(inline_env->method,mr->classref,resolveEager,true,&mrclass))
                                        return NULL;
 
-                               mi = class_resolveclassmethod(mr->class,
+                               mi = class_resolveclassmethod(mrclass,
                                                                                          mr->name,
                                                                                          mr->descriptor,
                                                                                          inline_env->method->class,
@@ -1299,7 +1130,7 @@ SHOWOPCODE(DEBUG4)
 
 if (DEBUG4==true) { 
        method_display_w_class(mi); 
-       printf("\tINVOKE STATIC\n");
+       printf("\tINVOKE STAT\n");
         fflush(stdout);}
 
                                if (!(mi->flags & ACC_STATIC)) {
@@ -1308,29 +1139,53 @@ if (DEBUG4==true) {
                                        return NULL;
                                }
 
-                               descriptor2types(mi);
+                               method_descriptor2types(mi);
                                OP2A(opcode, mi->paramcount, mi, currentline);
+#endif
                        }
                        break;
 
                case JAVA_INVOKESPECIAL:
                case JAVA_INVOKEVIRTUAL:
-                       i = code_get_u2(p + 1,inline_env->method);
+                       i = code_get_u2(p + 1, inline_env->method);
                        {
                                constant_FMIref *mr;
                                methodinfo *mi;
+                               unresolved_method *um;
+                               classinfo *mrclass;
 
                                inline_env->method->isleafmethod = false;
 
                                mr = class_getconstant(inline_env->method->class, i, CONSTANT_Methodref);
+#if defined(__X86_64__)
+                               OP2A_NOINC(opcode, mr->parseddesc.md->paramcount + 1, mr, currentline);
+
+                               um = create_unresolved_method(inline_env->method->class,
+                                                                                         inline_env->method,
+                                                                                         iptr,
+                                                                                         NULL);
 
-                               if (!class_load(mr->class))
+                               if (!um)
                                        return NULL;
 
-                               if (!class_link(mr->class))
+                               /* store the unresolved_method* */
+
+                               iptr->target = um;
+
+                               /* only with -noverify, otherwise the typechecker does this */
+
+                               if (!opt_verify) {
+                                       if (!resolve_method(um, resolveLazy, &mi))
+                                               return NULL;
+
+                                       iptr->val.a = mi;
+                               }
+                               PINC;
+#else
+                               if (!resolve_classref(inline_env->method,mr->classref,resolveEager,true,&mrclass))
                                        return NULL;
 
-                               mi = class_resolveclassmethod(mr->class,
+                               mi = class_resolveclassmethod(mrclass,
                                                                                          mr->name,
                                                                                          mr->descriptor,
                                                                                          inline_env->method->class,
@@ -1350,8 +1205,9 @@ if (DEBUG4==true) {
                                        return NULL;
                                }
 
-                               descriptor2types(mi);
+                               method_descriptor2types(mi);
                                OP2A(opcode, mi->paramcount, mi, currentline);
+#endif
                        }
                        break;
 
@@ -1360,18 +1216,41 @@ if (DEBUG4==true) {
                        {
                                constant_FMIref *mr;
                                methodinfo *mi;
+                               classinfo *mrclass;
+                               unresolved_method *um;
                                
                                inline_env->method->isleafmethod = false;
 
                                mr = class_getconstant(inline_env->method->class, i, CONSTANT_InterfaceMethodref);
+#if defined(__X86_64__)
+                               OP2A_NOINC(opcode, mr->parseddesc.md->paramcount + 1, mr, currentline);
+
+                               um = create_unresolved_method(inline_env->method->class,
+                                                                                         inline_env->method,
+                                                                                         iptr,
+                                                                                         NULL);
 
-                               if (!class_load(mr->class))
+                               if (!um)
                                        return NULL;
 
-                               if (!class_link(mr->class))
+                               /* store the unresolved_method* */
+
+                               iptr->target = um;
+
+                               /* only with -noverify, otherwise the typechecker does this */
+
+                               if (!opt_verify) {
+                                       if (!resolve_method(um, resolveLazy, &mi))
+                                               return NULL;
+
+                                       iptr->val.a = mi;
+                               }
+                               PINC;
+#else
+                               if (!resolve_classref(inline_env->method,mr->classref,resolveEager,true,&mrclass))
                                        return NULL;
 
-                               mi = class_resolveinterfacemethod(mr->class,
+                               mi = class_resolveinterfacemethod(mrclass,
                                                                                                  mr->name,
                                                                                                  mr->descriptor,
                                                                                                  inline_env->method->class,
@@ -1389,35 +1268,83 @@ if (DEBUG4==true) {
        method_display_w_class(mi); 
        printf("\tINVOKE INTERFACE\n");
         fflush(stdout);}
-                               descriptor2types(mi);
+
+                               method_descriptor2types(mi);
                                OP2A(opcode, mi->paramcount, mi, currentline);
+#endif
                        }
                        break;
 
                        /* miscellaneous object operations *******/
 
                case JAVA_NEW:
-                       i = code_get_u2(p + 1,inline_env->method);
-                       LOADCONST_A_BUILTIN(class_getconstant(inline_env->method->class, i, CONSTANT_Class));
-                       s_count++;
-                       BUILTIN1(BUILTIN_new, TYPE_ADR, currentline);
-                       OP(ICMD_CHECKEXCEPTION);
+                       {
+                               constant_classref *cr;
+                               classinfo         *cls;
+                               
+#if defined(__X86_64__)
+                               i = code_get_u2(p + 1, inline_env->method);
+                               cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+
+                               if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &cls))
+                                       return NULL;
+
+                               /* <clinit> can throw an exception over native code */
+
+                               if (cls && cls->initialized) {
+                                       LOADCONST_A_BUILTIN(cls);
+                                       BUILTIN1(BUILTIN_new, TYPE_ADR, currentline);
+
+                               } else {
+                                       LOADCONST_A_BUILTIN(cr);
+                                       BUILTIN1((functionptr) asm_builtin_new, TYPE_ADR, currentline);
+                               }
+
+                               s_count++;
+                               OP(ICMD_CHECKEXCEPTION);
+#else
+                               i = code_get_u2(p + 1,inline_env->method);
+                               cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+                               if (!resolve_classref(inline_env->method,cr,resolveEager,true,&cls))
+                                       return NULL;
+                               LOADCONST_A_BUILTIN(cls);
+                               s_count++;
+                               BUILTIN1(BUILTIN_new, TYPE_ADR, currentline);
+                               OP(ICMD_CHECKEXCEPTION);
+#endif
+                       }
                        break;
 
                case JAVA_CHECKCAST:
-                       i = code_get_u2(p + 1,inline_env->method);
+                       i = code_get_u2(p + 1, inline_env->method);
                        {
-                               classinfo *cls =
-                                       (classinfo *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+                               constant_classref *cr;
+                               classinfo *cls;
+                               
+                               cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
 
-                               if (!cls->loaded)
-                                       if (!class_load(cls))
-                                               return NULL;
+#if defined(__X86_64__)
+                               if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &cls))
+                                       return NULL;
 
-                               if (!cls->linked)
-                                       if (!class_link(cls))
+                               if (cr->name->text[0] == '[') {
+                                       if (!resolve_classref(inline_env->method, cr, resolveEager, true, &cls))
                                                return NULL;
 
+                                       /* array type cast-check */
+                                       LOADCONST_A_BUILTIN(cls->vftbl);
+                                       s_count++;
+                                       BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR, currentline);
+
+                               } else {
+                                       /* object type cast-check */
+                                       OP2AT(opcode, 1, cls, cr, currentline);
+                               }
+#else
+                               if (!resolve_classref(inline_env->method,
+                                                       cr,resolveEager,true,&cls))
+                                       return NULL;
+
                                if (cls->vftbl->arraydesc) {
                                        /* array type cast-check */
                                        LOADCONST_A_BUILTIN(cls->vftbl);
@@ -1432,23 +1359,40 @@ if (DEBUG4==true) {
                                          +                                             */
                                        OP2A(opcode, 1, cls, currentline);
                                }
+#endif
                        }
                        break;
 
                case JAVA_INSTANCEOF:
                        i = code_get_u2(p + 1,inline_env->method);
                        {
-                               classinfo *cls =
-                                       (classinfo *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+                               constant_classref *cr;
+                               classinfo *cls;
+                               
+                               cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
 
-                               if (!cls->loaded)
-                                       if (!class_load(cls))
-                                               return NULL;
+#if defined(__X86_64__)
+                               if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &cls))
+                                       return NULL;
 
-                               if (!cls->linked)
-                                       if (!class_link(cls))
+                               if (cr->name->text[0] == '[') {
+                                       if (!resolve_classref(inline_env->method, cr, resolveEager, true, &cls))
                                                return NULL;
 
+                                       /* array type cast-check */
+                                       LOADCONST_A_BUILTIN(cls->vftbl);
+                                       s_count++;
+                                       BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT, currentline);
+
+                               } else {
+                                       /* object type cast-check */
+                                       OP2AT(opcode, 1, cls, cr, currentline);
+                               }
+#else
+                               if (!resolve_classref(inline_env->method,
+                                                       cr,resolveEager,true,&cls))
+                                       return NULL;
+
                                if (cls->vftbl->arraydesc) {
                                        /* array type cast-check */
                                        LOADCONST_A_BUILTIN(cls->vftbl);
@@ -1463,6 +1407,7 @@ if (DEBUG4==true) {
                                          +                                             */
                                        OP2A(opcode, 1, cls, currentline);
                                }
+#endif
                        }
                        break;