* src/vm/jit/arm/codegen.c: Remove hack for return value in float registers.
[cacao.git] / src / vm / jit / intrp / java.vmg
index 06e18b335ebb6bf20e1684c90f636a2728225359..597d23077990256e7e8952ab1d2eea08a8dfd62a 100644 (file)
@@ -54,6 +54,7 @@
 \E s" u1 *"                single data-stack type-prefix addr
 \E s" functionptr"         single data-stack type-prefix af
 \E s" methodinfo *"        single data-stack type-prefix am
+\E s" fieldinfo *"         single data-stack type-prefix afi
 \E s" Cell *"              single data-stack type-prefix acell
 \E s" Inst *"              single data-stack type-prefix ainst
 \E s" unresolved_field *"  single data-stack type-prefix auf
 \ 
 \ */
 
+\ stack cache setup
+
+\E register IPTOS Cell
+\E register spTOS Cell
+
+\E create IPregs IPTOS ,
+\E create regs spTOS ,
+
+\E IPregs 1 0 stack-state IPss1
+\E regs 1 0 stack-state ss0
+
+\ the first of these is the default state
+\E state S0
+
+\E ss0 data-stack S0 set-ss
+
+\E IPss1 inst-stream S0 set-ss
+
+\E data-stack to cache-stack
+\E here 1 cache-states 2! s0 ,
+
+\ !! the following should be automatic
+\E S0 to state-default
+\E state-default to state-in
+\E state-default to state-out
+
+\E s" codegendata *" threaded-code-pointer-type 2!
+
 \ This is stub code for methods that we have not yet translated.
 \ Initially, the code for each method is set to this stub. The
 \ first time the method is called, the code in the stub runs, which
@@ -124,27 +153,52 @@ LCONST ( #l -- l ) opt
 
 ACONST ( #aRef -- aRef ) opt
 
-ILOAD ( #bLocal -- vResult ) 0x15
+ACONST1 ( #aRef #acrUnused -- aRef ) opt
+
+PATCHER_ACONST ( #aRef #acr ... -- )
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_aconst((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
+  THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(ACONST1);
+SET_IP(IP - 3);
+patchersuper_rewrite(IP);
+
+ILOAD ( #vLocal -- vResult ) 0x15
 {
-  vResult = access_local_int(bLocal);
+  vResult = access_local_int(vLocal);
 }
 
-LLOAD ( #bLocal -- lResult ) 0x16
+LLOAD ( #vLocal -- lResult ) 0x16
 {
-  vm_twoCell2l(access_local_cell(bLocal), access_local_cell(bLocal+1), lResult);
+  vm_twoCell2l(access_local_cell(vLocal), access_local_cell(vLocal-SIZEOF_VOID_P), lResult);
 }
 
-ALOAD ( #bLocal -- aRef ) 0x19
+ALOAD ( #vLocal -- aRef ) 0x19
 {
-  aRef = (java_objectheader *)access_local_cell(bLocal);
+  aRef = (java_objectheader *)access_local_cell(vLocal);
 }
 
-IALOAD ( aArray iIndex -- iResult ) 0x2e
+IALOAD ( aArray iIndex -- vResult ) 0x2e
 {
   CHECK_NULL_PTR(aArray);
   CHECK_OUT_OF_BOUNDS(aArray, iIndex);
   ;
-  iResult = access_array_int(aArray, iIndex);
+  vResult = access_array_int(aArray, iIndex);
+}
+
+FALOAD ( aArray iIndex -- fResult ) 0x2e
+{
+  CHECK_NULL_PTR(aArray);
+  CHECK_OUT_OF_BOUNDS(aArray, iIndex);
+  ;
+  fResult = access_array_float(aArray, iIndex);
 }
 
 LALOAD ( aArray iIndex -- lResult ) 0x2f
@@ -163,43 +217,43 @@ AALOAD ( aArray iIndex -- aRef ) 0x32
   aRef = access_array_addr(aArray, iIndex);
 }
 
-BALOAD ( aArray iIndex -- iResult ) 0x33
+BALOAD ( aArray iIndex -- vResult ) 0x33
 {
   CHECK_NULL_PTR(aArray);
   CHECK_OUT_OF_BOUNDS(aArray, iIndex);
   ;
-  iResult = access_array_byte(aArray, iIndex);
+  vResult = access_array_byte(aArray, iIndex);
 }
 
-CALOAD ( aArray iIndex -- iResult ) 0x34
+CALOAD ( aArray iIndex -- vResult ) 0x34
 {
   CHECK_NULL_PTR(aArray);
   CHECK_OUT_OF_BOUNDS(aArray, iIndex);
   ;
-  iResult = access_array_char(aArray, iIndex);
+  vResult = access_array_char(aArray, iIndex);
 }
 
-SALOAD ( aArray iIndex -- iResult ) 0x35
+SALOAD ( aArray iIndex -- vResult ) 0x35
 {
   CHECK_NULL_PTR(aArray);
   CHECK_OUT_OF_BOUNDS(aArray, iIndex);
   ;
-  iResult = access_array_short(aArray, iIndex);
+  vResult = access_array_short(aArray, iIndex);
 }
 
-ISTORE ( #bLocal vValue -- ) 0x36
+ISTORE ( #vLocal vValue -- ) 0x36
 {
-  access_local_int(bLocal) = vValue;
+  access_local_int(vLocal) = vValue;
 }
 
-LSTORE ( #bLocal lValue -- ) 0x37
+LSTORE ( #vLocal lValue -- ) 0x37
 {
-  vm_l2twoCell(lValue, access_local_cell(bLocal), access_local_cell(bLocal+1));
+  vm_l2twoCell(lValue, access_local_cell(vLocal), access_local_cell(vLocal-SIZEOF_VOID_P));
 }
 
-ASTORE ( #bLocal aRef -- ) 0x3a
+ASTORE ( #vLocal aRef -- ) 0x3a
 {
-  access_local_cell(bLocal) = (Cell)aRef;
+  access_local_cell(vLocal) = (Cell)aRef;
 }
 
 IASTORE ( aArray iIndex iValue -- ) 0x4f
@@ -210,6 +264,14 @@ IASTORE ( aArray iIndex iValue -- ) 0x4f
   access_array_int(aArray, iIndex) = iValue;
 }
 
+FASTORE ( aArray iIndex fValue -- ) 0x4f
+{
+  CHECK_NULL_PTR(aArray);
+  CHECK_OUT_OF_BOUNDS(aArray, iIndex);
+  ;
+  access_array_float(aArray, iIndex) = fValue;
+}
+
 LASTORE ( aArray iIndex lValue -- ) 0x50
 {
   CHECK_NULL_PTR(aArray);
@@ -223,7 +285,7 @@ AASTORE ( aArray iIndex aRef -- ) 0x53
   CHECK_NULL_PTR(aArray);
   CHECK_OUT_OF_BOUNDS(aArray, iIndex);
   if (!builtin_canstore((java_objectarray *)aArray, aRef))
-       THROW(arraystoreexception);
+      THROW(arraystoreexception);
   access_array_addr(aArray, iIndex) = aRef;
 }
 
@@ -261,14 +323,14 @@ DUP2_X2 ( vValue4 vValue3 vValue2 vValue1 -- vValue2 vValue1 vValue4 vValue3 vVa
 
 SWAP ( vValue2 vValue1 -- vValue1 vValue2 ) 0x5f
 
-IADD ( iValue1 iValue2 -- iResult ) 0x60
+IADD ( vValue1 vValue2 -- vResult ) 0x60
 {
-  iResult = iValue1 + iValue2;
+  vResult = vValue2 + vValue1;
 }
 
 LADD ( lValue1 lValue2 -- lResult ) 0x61
 {
-  lResult = lValue1 + lValue2;
+  lResult = lValue2 + lValue1;
 }
 
 FADD ( fValue1 fValue2 -- fResult ) 0x62
@@ -281,9 +343,9 @@ DADD ( dValue1 dValue2 -- dResult ) 0x63
   dResult = dValue1 + dValue2;
 }
 
-ISUB ( iValue1 iValue2 -- iResult ) 0x64
+ISUB ( vValue1 vValue2 -- vResult ) 0x64
 {
-  iResult = iValue1 - iValue2;
+  vResult = vValue1 - vValue2;
 }
 
 LSUB ( lValue1 lValue2 -- lResult ) 0x65
@@ -301,9 +363,9 @@ DSUB ( dValue1 dValue2 -- dResult ) 0x67
   dResult = dValue1 - dValue2;
 }
 
-IMUL ( iValue1 iValue2 -- iResult ) 0x68
+IMUL ( vValue1 vValue2 -- vResult ) 0x68
 {
-  iResult = iValue1 * iValue2;
+  vResult = vValue1 * vValue2;
 }
 
 LMUL ( lValue1 lValue2 -- lResult ) 0x69
@@ -325,7 +387,10 @@ IDIV ( iValue1 iValue2 -- iResult ) 0x6c
 {
   CHECK_ZERO_DIVISOR(iValue2);
   ;
-  iResult = iValue1 / iValue2;
+  if (iValue1 == 0x80000000 && iValue2 == -1)
+    iResult=iValue1;
+  else
+    iResult = iValue1 / iValue2;
 }
 
 IDIVPOW2 ( i1 #ishift -- i2 ) opt
@@ -338,8 +403,10 @@ IDIVPOW2 ( i1 #ishift -- i2 ) opt
 LDIV ( lValue1 lValue2 -- lResult ) 0x6d
 {
   CHECK_ZERO_DIVISOR(lValue2);
-  ;
-  lResult = lValue1 / lValue2;
+  if (lValue1 == 0x8000000000000000LL && lValue2 == -1)
+    lResult=lValue1;
+  else
+    lResult = lValue1 / lValue2;
 }
 
 LDIVPOW2 ( l1 #ishift -- l2 )
@@ -363,7 +430,10 @@ DDIV ( dValue1 dValue2 -- dResult ) 0x6f
 IREM ( iValue1 iValue2 -- iResult ) 0x70
 {
   CHECK_ZERO_DIVISOR(iValue2);
-  iResult = iValue1 % iValue2;
+  if (iValue1 == 0x80000000 && iValue2 == -1)
+    iResult=0;
+  else
+    iResult = iValue1 % iValue2;
 }
 
 IREMPOW2 ( i1 #imask -- i2 )
@@ -376,7 +446,10 @@ i2 = i1-x;
 LREM ( lValue1 lValue2 -- lResult ) 0x71
 {
   CHECK_ZERO_DIVISOR(lValue2);
-  lResult = lValue1 % lValue2;
+  if (lValue1 == 0x8000000000000000LL && lValue2 == -1)
+    lResult=0;
+  else
+    lResult = lValue1 % lValue2;
 }
 
 LREMPOW2 ( l1 #lmask -- l2 )
@@ -396,9 +469,9 @@ DREM ( dValue1 dValue2 -- dResult ) 0x73
   dResult = builtin_drem(dValue1, dValue2);
 }
 
-INEG ( iValue -- iResult ) 0x74
+INEG ( vValue -- vResult ) 0x74
 {
-  iResult = -iValue;
+  vResult = -vValue;
 }
 
 LNEG ( lValue -- lResult ) 0x75
@@ -416,14 +489,14 @@ DNEG ( dValue -- dResult ) 0x77
   dResult = -dValue;
 }
 
-ISHL ( iValue1 iValue2 -- iResult ) 0x78
+ISHL ( vValue1 vValue2 -- vResult ) 0x78
 {
-  iResult = iValue1 << (iValue2 & 31);
+  vResult = vValue1 << (vValue2 & 31);
 }
 
-LSHL ( lValue1 iValue2 -- lResult ) 0x79
+LSHL ( lValue1 vValue2 -- lResult ) 0x79
 {
-  lResult = lValue1 << (iValue2 & 63);
+  lResult = lValue1 << (vValue2 & 63);
 }
 
 ISHR ( iValue1 iValue2 -- iResult ) 0x7a
@@ -436,19 +509,19 @@ LSHR ( lValue1 iValue2 -- lResult ) 0x7b
   lResult = lValue1 >> (iValue2 & 63);
 }
 
-IUSHR ( iValue1 iValue2 -- iResult ) 0x7c
+IUSHR ( iValue1 vValue2 -- iResult ) 0x7c
 {
-  iResult = ((unsigned) iValue1) >> (iValue2 & 31);
+  iResult = ((unsigned) iValue1) >> (vValue2 & 31);
 }
 
-LUSHR ( lValue1 iValue2 -- lResult ) 0x7d
+LUSHR ( lValue1 vValue2 -- lResult ) 0x7d
 {
-  lResult = (unsigned long long) lValue1 >> (iValue2 & 63);
+  lResult = (unsigned long long) lValue1 >> (vValue2 & 63);
 }
 
-IAND ( iValue1 iValue2 -- iResult ) 0x7e
+IAND ( vValue1 vValue2 -- vResult ) 0x7e
 {
-  iResult = iValue1 & iValue2;
+  vResult = vValue1 & vValue2;
 }
 
 LAND ( lValue1 lValue2 -- lResult ) 0x7f
@@ -456,9 +529,9 @@ LAND ( lValue1 lValue2 -- lResult ) 0x7f
   lResult = lValue1 & lValue2;
 }
 
-IOR ( iValue1 iValue2 -- iResult ) 0x80
+IOR ( vValue1 vValue2 -- vResult ) 0x80
 {
-  iResult = iValue1 | iValue2;
+  vResult = vValue1 | vValue2;
 }
 
 LOR ( lValue1 lValue2 -- lResult ) 0x81
@@ -466,9 +539,9 @@ LOR ( lValue1 lValue2 -- lResult ) 0x81
   lResult = lValue1 | lValue2;
 }
 
-IXOR ( iValue1 iValue2 -- iResult ) 0x82
+IXOR ( vValue1 vValue2 -- vResult ) 0x82
 {
-  iResult = iValue1 ^ iValue2;
+  vResult = vValue1 ^ vValue2;
 }
 
 LXOR ( lValue1 lValue2 -- lResult ) 0x83
@@ -476,10 +549,9 @@ LXOR ( lValue1 lValue2 -- lResult ) 0x83
   lResult = lValue1 ^ lValue2;
 }
 
-IINC ( #bIndex #iConst  -- ) 0x84
+IINC ( #vOffset #iConst  -- ) 0x84
 {
-  access_local_int((unsigned)bIndex) =
-                 access_local_int((unsigned)bIndex) + iConst;
+  access_local_int(vOffset) += iConst;
 }
 
 I2L ( iValue -- lValue ) 0x85
@@ -558,19 +630,19 @@ INT2SHORT ( iValue -- iResult ) 0x93
   iResult = (iValue << 16) >> 16; /* XXX: try "(s2)iValue" */
 }
 
-LCMP ( lValue1 lValue2 -- iResult ) 0x94
+LCMP ( lValue1 lValue2 -- vResult ) 0x94
 {
-  iResult = lValue1 < lValue2 ? -1 : lValue1 > lValue2 ? 1 : 0;
+  vResult = lValue1 < lValue2 ? -1 : lValue1 > lValue2 ? 1 : 0;
 }
 
-FCMPL ( fValue1 fValue2 -- iResult ) 0x95
+FCMPL ( fValue1 fValue2 -- vResult ) 0x95
 {
-  iResult = builtin_fcmpl(fValue1, fValue2);
+  vResult = builtin_fcmpl(fValue1, fValue2);
 }
 
-FCMPG ( fValue1 fValue2 -- iResult ) 0x96
+FCMPG ( fValue1 fValue2 -- vResult ) 0x96
 {
-  iResult = builtin_fcmpg(fValue1, fValue2);
+  vResult = builtin_fcmpg(fValue1, fValue2);
 }
 
 DCMPL ( dValue1 dValue2 -- iResult ) 0x97
@@ -586,123 +658,123 @@ DCMPG ( dValue1 dValue2 -- iResult ) 0x98
 IFEQ ( #ainstTarget iValue -- ) 0x99
 {
   if ( iValue == 0 ) {
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
   }
 }
 
 IFNE ( #ainstTarget iValue -- ) 0x9a
 {
   if ( iValue != 0 ) {
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
   }
 }
 
 IFLT ( #ainstTarget iValue -- ) 0x9b
 {
   if ( iValue < 0 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IFGE ( #ainstTarget iValue -- ) 0x9c
 {
   if ( iValue >= 0 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IFGT ( #ainstTarget iValue -- ) 0x9d
 {
   if ( iValue > 0 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IFLE ( #ainstTarget iValue -- ) 0x9e
 {
   if ( iValue <= 0 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_ICMPEQ ( #ainstTarget iValue1 iValue2 -- ) 0x9f
 {
   if ( iValue1 == iValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_ICMPNE  ( #ainstTarget iValue1 iValue2 -- ) 0xa0
 {
   if ( iValue1 != iValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_ICMPLT  ( #ainstTarget iValue1 iValue2 -- ) 0xa1
 {
   if ( iValue1 < iValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_ICMPGE  ( #ainstTarget iValue1 iValue2 -- ) 0xa2
 {
   if ( iValue1 >= iValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_ICMPGT  ( #ainstTarget iValue1 iValue2 -- ) 0xa3
 {
   if ( iValue1 > iValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_ICMPLE  ( #ainstTarget iValue1 iValue2 -- ) 0xa4
 {
   if ( iValue1 <= iValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_LCMPEQ ( #ainstTarget lValue1 lValue2 -- ) opt
 {
   if ( lValue1 == lValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_LCMPNE  ( #ainstTarget lValue1 lValue2 -- ) opt
 {
   if ( lValue1 != lValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_LCMPLT  ( #ainstTarget lValue1 lValue2 -- ) opt
 {
   if ( lValue1 < lValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_LCMPGE  ( #ainstTarget lValue1 lValue2 -- ) opt
 {
   if ( lValue1 >= lValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_LCMPGT  ( #ainstTarget lValue1 lValue2 -- ) opt
 {
   if ( lValue1 > lValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_LCMPLE  ( #ainstTarget lValue1 lValue2 -- ) opt
 {
   if ( lValue1 <= lValue2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_ACMPEQ  ( #ainstTarget aRef1 aRef2 -- ) 0xa5
 {
   if ( aRef1 == aRef2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 IF_ACMPNE  ( #ainstTarget aRef1 aRef2 -- ) 0xa6
 {
   if ( aRef1 != aRef2 )
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
 }
 
 GOTO (  #ainstTarget -- ) 0xa7
@@ -719,10 +791,10 @@ JSR (  #ainstTarget -- ainstRA ) 0xa8
   SET_IP(ainstTarget);
 }
 
-RET ( #bIndex -- ) 0xa9
+RET ( #vOffset -- ) 0xa9
 {
   Inst * saved_ip;
-  saved_ip = access_local_ref((unsigned) bIndex);
+  saved_ip = access_local_ref(vOffset);
   SET_IP(saved_ip);
 }
 
@@ -730,10 +802,10 @@ TABLESWITCH ( #iLow #iRange #addrSegment #iOffset #ainstDefault iIndex -- ) 0xaa
 {
   s4 idx = iIndex - iLow;
   if ( ((u4) idx) >= iRange ) {
-    SET_IP(ainstDefault); INST_TAIL;
+    SET_IP(ainstDefault);
   }
   else {
-    SET_IP(((Inst **)(addrSegment+iOffset))[idx]); INST_TAIL;
+    SET_IP(((Inst **)(addrSegment+iOffset))[idx]);
   }
 }
 
@@ -742,10 +814,13 @@ LOOKUPSWITCH ( #iNpairs #addrSegment #iOffset #ainstDefault iKey -- ) 0xab
   /* Note: This code should use a binary search, as
      the table is sorted. Note also, we reversed the order
      of the parms */
-  unsigned i;
-  for ( i = 0; i < iNpairs; i++ ) {
-    Cell *table = (Cell *)(addrSegment+iOffset);
-    if ( iKey == (s4)(table[2 * i]) ) {
+  int i;
+
+  i = iNpairs;
+
+  while (--i >= 0) {
+    Cell *table = (Cell *) (addrSegment+iOffset);
+    if (iKey == (s4) (table[2 * i])) {
       SET_IP((Inst *)(table[2 * i + 1])); INST_TAIL;
     }
   }
@@ -776,237 +851,340 @@ LOOKUPSWITCH ( #iNpairs #addrSegment #iOffset #ainstDefault iKey -- ) 0xab
 \       stack0 ;once there is something on the stack
 \       ...
 
-IRETURN ( #iIndexFP vValue -- vResult ) 0xac
+IRETURN ( #vOffsetFP ... vValue -- vResult ) 0xac
 {
   Inst *new_ip;
-  new_ip = (Inst *)access_local_cell(iIndexFP + 1);
-  sp = fp;
-  fp = (Cell *)access_local_cell(iIndexFP);
+  MAYBE_UNUSED Cell *currentsp = sp;
+  new_ip = (Inst *) access_local_cell(vOffsetFP - SIZEOF_VOID_P);
+  sp = fp + 1;
+  fp = (Cell *) access_local_cell(vOffsetFP);
+  CLEARSTACK(currentsp - 6, sp - 1);
   vResult = vValue;
   SET_IP(new_ip);
 }
 
-LRETURN ( #iIndexFP lValue -- lResult ) 0xad
+LRETURN ( #vOffsetFP ... lValue -- lResult ) 0xad
 {
-  Inst *new_ip = (Inst *)access_local_cell(iIndexFP + 1);
-  sp = fp - 1;
-  fp = (Cell *)access_local_cell(iIndexFP);
+  Inst *new_ip;
+  MAYBE_UNUSED Cell *currentsp = sp;
+  new_ip = (Inst *) access_local_cell(vOffsetFP - SIZEOF_VOID_P);
+  sp = fp + 1;
+  fp = (Cell *) access_local_cell(vOffsetFP);
+  CLEARSTACK(currentsp - 7, sp - 2);
   lResult = lValue;
   SET_IP(new_ip);
 }
 
-RETURN ( #iIndexFP -- ) 0xb1
+RETURN ( #vOffsetFP ... -- ) 0xb1
 {
   Inst *new_ip;
-  IF_spTOS(sp[0] = spTOS);
-  new_ip = (Inst *)access_local_cell(iIndexFP + 1);
-  sp = fp+1;
-  fp = (Cell *)access_local_cell(iIndexFP);
+  MAYBE_UNUSED Cell *currentsp = sp;
+  new_ip = (Inst *) access_local_cell(vOffsetFP - SIZEOF_VOID_P);
+  sp = fp + 1;
+  fp = (Cell *) access_local_cell(vOffsetFP);
+  CLEARSTACK(currentsp - 5, sp - 1);
   SET_IP(new_ip);
-  IF_spTOS(spTOS = sp[0]);
 }
 
-GETSTATIC_CELL ( #addr #auf -- vResult ) opt
+GETSTATIC_CELL ( #addr #afi -- vResult ) opt
 {
   vResult = *(Cell *)addr;
 }
 
-GETSTATIC_INT ( #addr #auf -- iResult ) opt
+GETSTATIC_INT ( #addr #afi -- iResult ) opt
 {
   iResult = *(s4 *)addr;
 }
 
-GETSTATIC_LONG ( #addr #auf -- lResult ) opt
+GETSTATIC_FLOAT ( #addr #afi -- fResult ) opt
+{
+  fResult = *(float *)addr;
+}
+
+GETSTATIC_LONG ( #addr #afi -- lResult ) opt
 {
   lResult = *((s8 *) addr);
 }
 
-PUTSTATIC_CELL ( #addr #auf vValue -- ) opt
+PUTSTATIC_CELL ( #addr #afi vValue -- ) opt
 {
   *((Cell *) addr) = vValue;
 }
 
-PUTSTATIC_INT ( #addr #auf iValue -- ) opt
+PUTSTATIC_INT ( #addr #afi iValue -- ) opt
 {
   *((s4 *) addr) = iValue;
 }
 
-PUTSTATIC_LONG ( #addr #auf lValue -- ) opt
+PUTSTATIC_FLOAT ( #addr #afi fValue -- ) opt
+{
+  *((float *) addr) = fValue;
+}
+
+PUTSTATIC_LONG ( #addr #afi lValue -- ) opt
 {
   *((s8 *) addr) = lValue;
 }
 
-GETFIELD_CELL ( #iOffset #auf aRef -- vResult ) opt
+GETFIELD_CELL ( #vOffset #afi aRef -- vResult ) opt
 {
   CHECK_NULL_PTR(aRef);
-  vResult = *((Cell *) (((u1 *)aRef) + iOffset));
+  vResult = *((Cell *) (((u1 *)aRef) + vOffset));
 }
 
-GETFIELD_INT ( #iOffset #auf aRef -- iResult ) opt
+GETFIELD_INT ( #vOffset #afi aRef -- iResult ) opt
 {
   CHECK_NULL_PTR(aRef);
-  iResult = *((s4 *) (((u1 *)aRef) + iOffset));
+  iResult = *((s4 *) (((u1 *)aRef) + vOffset));
 }
 
-GETFIELD_LONG ( #iOffset #auf aRef -- lResult ) opt
+GETFIELD_FLOAT ( #vOffset #afi aRef -- fResult ) opt
 {
   CHECK_NULL_PTR(aRef);
-  lResult = *((s8 *) (((u1 *)aRef) + iOffset));
+  fResult = *((float *) (((u1 *) aRef) + vOffset));
 }
 
+GETFIELD_LONG ( #vOffset #afi aRef -- lResult ) opt
+{
+  CHECK_NULL_PTR(aRef);
+  lResult = *((s8 *) (((u1 *)aRef) + vOffset));
+}
 
-PUTFIELD_CELL ( #iOffset #auf aRef vValue -- ) opt
+
+PUTFIELD_CELL ( #vOffset #afi aRef vValue -- ) opt
 {
   CHECK_NULL_PTR(aRef);
-  *((Cell *) (((u1 *)aRef) + iOffset)) = vValue;
+  *((Cell *) (((u1 *)aRef) + vOffset)) = vValue;
 }
 
-PUTFIELD_INT ( #iOffset #auf aRef iValue -- ) opt
+PUTFIELD_INT ( #vOffset #afi aRef iValue -- ) opt
 {
   CHECK_NULL_PTR(aRef);
-  *((s4 *) (((u1 *)aRef) + iOffset)) = iValue;
+  *((s4 *) (((u1 *)aRef) + vOffset)) = iValue;
 }
 
-PUTFIELD_LONG ( #iOffset #auf aRef lValue -- ) opt
+PUTFIELD_FLOAT ( #vOffset #afi aRef fValue -- ) opt
 {
   CHECK_NULL_PTR(aRef);
-  *((s8 *) (((u1 *)aRef) + iOffset)) = lValue;
+  *((float *) (((u1 *)aRef) + vOffset)) = fValue;
+}
+
+PUTFIELD_LONG ( #vOffset #afi aRef lValue -- ) opt
+{
+  CHECK_NULL_PTR(aRef);
+  *((s8 *) (((u1 *)aRef) + vOffset)) = lValue;
 }
 
 \ !! called methods have the number of locals at offset -1.
 \ methods are always called indirectly through the codeptr in the stub 
 \   (see createcompilerstub and TRANSLATE).
 
-INVOKEVIRTUAL ( #iOffset #iNargs #aum -- acelloldfp ainstoldip ) 0xd8
+INVOKEVIRTUAL ( #vOffset #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xd8
 {
-  java_objectheader *aRef = (java_objectheader *)(sp[iNargs + 1]); /* corrected for sp change by vmg */
+  java_objectheader *aRef = (java_objectheader *)(sp[iNargs - 1]);
   char *v;
   Inst **stub;
   Inst *target;
   CHECK_NULL_PTR(aRef);
   v = (char *)(aRef->vftbl);
-  stub = *(Inst ***)(v+iOffset);
+  stub = *(Inst ***)(v+vOffset);
   target = *stub;
   acelloldfp = fp;
   ainstoldip = IP;
-  fp = sp + 1 + iNargs;
-  sp = fp - MAXLOCALS(stub) - 1;
+  fp = sp - 1 + iNargs;
+  sp = fp - FRAMESIZE(stub) + 1;
   SET_IP(target);
 }
 
-INVOKESTATIC ( #aaTarget #iNargs #aum -- acelloldfp ainstoldip ) 0xb8
+INVOKESTATIC ( #aaTarget #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xb8
 /* an indirect pointer to target is passed to avoid references to uncompiled code */
 {
   Inst *target = *aaTarget;
   acelloldfp = fp;
   ainstoldip = IP;
-  /* sp is already updated by the generator, so we have to compensate for that */
-  fp = sp + 1 + iNargs; /* !! scale nargs at translation time */
-  sp = fp - MAXLOCALS(aaTarget) - 1;
+  fp = sp - 1 + iNargs; /* !! scale nargs at translation time */
+  sp = fp - FRAMESIZE(aaTarget) + 1;
   SET_IP(target);
 }
 
-INVOKESPECIAL ( #aaTarget #iNargs #aum -- acelloldfp ainstoldip ) 0xb7
+INVOKESPECIAL ( #aaTarget #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xb7
 /* an indirect pointer to target is passed to avoid references to uncompiled code */
 {
-  java_objectheader *aRef = (java_objectheader *)(sp[iNargs + 1]); /* corrected for sp change by vmg */
+  java_objectheader *aRef = (java_objectheader *)(sp[iNargs - 1]);
   Inst *target = *aaTarget;
   CHECK_NULL_PTR(aRef);
   acelloldfp = fp;
   ainstoldip = IP;
-  /* sp is already updated by the generator, so we have to compensate for that */
-  fp = sp + 1 + iNargs; /* !! scale nargs at translation time */
-  sp = fp - MAXLOCALS(aaTarget) - 1;
+  fp = sp - 1 + iNargs; /* !! scale nargs at translation time */
+  sp = fp - FRAMESIZE(aaTarget) + 1;
   SET_IP(target);
 }
 
-INVOKEINTERFACE ( #iInterfaceOffset #iOffset #iNargs #aum -- acelloldfp ainstoldip ) 0xd8
+INVOKEINTERFACE ( #iInterfaceOffset #vOffset #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xd8
 {
   java_objectheader *aRef;
   char   *v, *t;
   Inst **stub;
   Inst *target;
   ;
-  aRef = (java_objectheader *)sp[iNargs + 1];
+  aRef = (java_objectheader *)sp[iNargs - 1];
   CHECK_NULL_PTR(aRef);
   v = (char *)(aRef->vftbl);
   t = *(char **)(v + iInterfaceOffset);
-  stub = *(Inst ***)(t+iOffset);
+  stub = *(Inst ***)(t+vOffset);
   target = *stub;
   acelloldfp = fp;
   ainstoldip = IP;
-  fp = sp + 1 + iNargs;
-  sp = fp - MAXLOCALS(stub) - 1;
+  fp = sp - 1 + iNargs;
+  sp = fp - FRAMESIZE(stub) + 1;
   SET_IP(target);
 }
 
 \ the BUILTIN functions like NEW get their parameters on the stack
 \ instead of through immediate arguments.
 
-NEW ( aClass -- aRef ) 0xbb
+\ !! do we need to synchronize the stack here?
+\ !! if so, is global_sp right?
+
+NEW ( ... aClass -- ... aRef ) 0xbb
 {
-  /* fprintf(stderr,"new: class %lx, class-state=%d\n",(long)aClass,((Hjava_lang_Class*)aClass)->state); */
-  global_sp=sp;
-  aRef = builtin_new((classinfo *)aClass);
+  global_sp = sp;
+  aRef = builtin_new((classinfo *) aClass);
+  if (aRef == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
   CLEAR_global_sp;
 }
 
 \ !! use a macro
 
-NEWARRAY_BOOLEAN ( iSize -- aArray )
-global_sp=sp;
-aArray = (java_arrayheader *)builtin_newarray_boolean(iSize);
-CLEAR_global_sp;
+NEWARRAY_BOOLEAN ( ... iSize -- ... aArray )
+{
+  global_sp = sp;
+  aArray = (java_arrayheader *) builtin_newarray_boolean(iSize);
+  if (aArray == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
+  CLEAR_global_sp;
+}
 
-NEWARRAY_CHAR ( iSize -- aArray )
-global_sp=sp;
-aArray = (java_arrayheader *)builtin_newarray_char(iSize);
-CLEAR_global_sp;
+NEWARRAY_BYTE ( ... iSize -- ... aArray )
+{
+  global_sp = sp;
+  aArray = (java_arrayheader *) builtin_newarray_byte(iSize);
+  if (aArray == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
+  CLEAR_global_sp;
+}
 
-NEWARRAY_FLOAT ( iSize -- aArray )
-global_sp=sp;
-aArray = (java_arrayheader *)builtin_newarray_float(iSize);
-CLEAR_global_sp;
+NEWARRAY_CHAR ( ... iSize -- ... aArray )
+{
+  global_sp = sp;
+  aArray = (java_arrayheader *) builtin_newarray_char(iSize);
+  if (aArray == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
+  CLEAR_global_sp;
+}
 
-NEWARRAY_DOUBLE ( iSize -- aArray )
-global_sp=sp;
-aArray = (java_arrayheader *)builtin_newarray_double(iSize);
-CLEAR_global_sp;
+NEWARRAY_SHORT ( ... iSize -- ... aArray )
+{
+  global_sp = sp;
+  aArray = (java_arrayheader *) builtin_newarray_short(iSize);
+  if (aArray == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
+  CLEAR_global_sp;
+}
 
-NEWARRAY_BYTE ( iSize -- aArray )
-global_sp=sp;
-aArray = (java_arrayheader *)builtin_newarray_byte(iSize);
-CLEAR_global_sp;
+NEWARRAY_INT ( ... iSize -- ... aArray )
+{
+  global_sp = sp;
+  aArray = (java_arrayheader *) builtin_newarray_int(iSize);
+  if (aArray == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
+  CLEAR_global_sp;
+}
 
-NEWARRAY_SHORT ( iSize -- aArray )
-global_sp=sp;
-aArray = (java_arrayheader *)builtin_newarray_short(iSize);
-CLEAR_global_sp;
+NEWARRAY_LONG ( ... iSize -- ... aArray )
+{
+  global_sp = sp;
+  aArray = (java_arrayheader *) builtin_newarray_long(iSize);
+  if (aArray == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
+  CLEAR_global_sp;
+}
 
-NEWARRAY_INT ( iSize -- aArray )
-global_sp=sp;
-aArray = (java_arrayheader *)builtin_newarray_int(iSize);
-CLEAR_global_sp;
+NEWARRAY_FLOAT ( ... iSize -- ... aArray )
+{
+  global_sp = sp;
+  aArray = (java_arrayheader *) builtin_newarray_float(iSize);
+  if (aArray == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
+  CLEAR_global_sp;
+}
 
-NEWARRAY_LONG ( iSize -- aArray )
-global_sp=sp;
-aArray = (java_arrayheader *)builtin_newarray_long(iSize);
-CLEAR_global_sp;
+NEWARRAY_DOUBLE ( ... iSize -- ... aArray )
+{
+  global_sp = sp;
+  aArray = (java_arrayheader *) builtin_newarray_double(iSize);
+  if (aArray == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
+  CLEAR_global_sp;
+}
 
-NEWARRAY ( iSize avftbl -- aArray ) 0xbd
+NEWARRAY ( ... iSize aClass -- ... aArray )
 {
-  global_sp=sp;
-  aArray = (java_arrayheader *)builtin_newarray(iSize, (vftbl_t *)avftbl);
+  global_sp = sp;
+  aArray = (java_arrayheader *) builtin_newarray(iSize, aClass);
+  if (aArray == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
+  }
   CLEAR_global_sp;
 }
 
-ARRAYLENGTH ( aArray -- iResult ) 0xbe
+ARRAYLENGTH ( aArray -- iResult )
 {
   CHECK_NULL_PTR(aArray);
   iResult = length_array(aArray);
 }
 
-ATHROW ( aRef -- aRef1 ) 0xbf
+ATHROW ( ... aRef -- ... aRef1 )
 {
   Cell *new_sp, *new_fp;
   Inst *new_ip;
@@ -1014,426 +1192,830 @@ ATHROW ( aRef -- aRef1 ) 0xbf
   goto athrow;
 throw:
   CLEAR_global_sp;
-  /* IF_spTOS(sp[0] = spTOS); */
   aRef = *exceptionptr;
   *exceptionptr = NULL;
 athrow:
-  new_ip = builtin_throw(IP,aRef,fp,&new_sp,&new_fp);
-  if (new_ip==NULL) {
+  new_ip = intrp_asm_handle_exception(IP, aRef, fp, &new_sp, &new_fp);
+  if (new_ip == NULL) {
     /* !! sp = new_sp; ? */
-    IF_spTOS(sp[0] = spTOS);  /* !! correct? even for superinstructions? */
-    global_sp = sp;
+    global_sp = sp - 1;
     SUPER_END; /* ATHROW may end a basic block */
     return aRef;
   }
   SET_IP(new_ip);
   aRef1 = aRef;
-  sp=new_sp-1;
-  fp=new_fp;
-  /* IF_spTOS(spTOS = sp[0]); */
+  sp = new_sp;
+  fp = new_fp;
 }
 
 CHECKCAST ( #aClass #acr aRef -- aRef ) 0xc0
 {
-  if (!builtin_checkcast((java_objectheader *)aRef, (classinfo *)aClass))
-    THROW(classcastexception);
+  if (!builtin_checkcast(aRef, (classinfo *) aClass))
+    THROW_CLASSCASTEXCEPTION(aRef);
 }
 
-ARRAYCHECKCAST ( #avftbl #acr aRef -- aRef ) 0xc0
+ARRAYCHECKCAST ( #aClass #acr aRef -- aRef ) 0xc0
 {
-  if (!builtin_arraycheckcast(aRef, avftbl))
-    THROW(classcastexception);
+  if (!builtin_arraycheckcast(aRef, aClass))
+    THROW_CLASSCASTEXCEPTION(aRef);
 }
 
-INSTANCEOF ( #aClass #acr aRef  -- iResult ) 0xc1
+PATCHER_ARRAYCHECKCAST ( #avftbl #acr ... -- ) 0xc0
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_builtin_arraycheckcast((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
+  THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(ARRAYCHECKCAST);
+SET_IP(IP - 3);
+patchersuper_rewrite(IP);
+
+INSTANCEOF ( #aClass #acr aRef  -- iResult )
 {
   iResult = builtin_instanceof(aRef, aClass);
 }
 
-ARRAYINSTANCEOF ( aRef avftbl  -- iResult ) 0xc1
+ARRAYINSTANCEOF ( aRef aClass  -- iResult )
 {
-  iResult = builtin_arrayinstanceof(aRef, avftbl);
+  iResult = builtin_arrayinstanceof(aRef, aClass);
 }
 
-MONITORENTER ( aRef -- ) 0xc2
+MONITORENTER ( aRef -- )
 {
-#if defined(USE_THREADS)
-  /* CHECK_NULL_PTR(aRef); is now done explicitly */
-  builtin_monitorenter(aRef);
+#if defined(ENABLE_THREADS)
+  /* CHECK_NULL_PTR(aRef); is now done explicitly inside lock_monitor_enter */
+  global_sp = sp;
+  if (!lock_monitor_enter(aRef))
+       THROW0;
+  CLEAR_global_sp;
 #endif
 }
 
-MONITOREXIT ( aRef -- ) 0xc3
+MONITOREXIT ( aRef -- )
 {
-#if defined(USE_THREADS)
-  /* CHECK_NULL_PTR(aRef); cannot happen */
-  builtin_monitorexit(aRef);
+#if defined(ENABLE_THREADS)
+  global_sp = sp;
+  if (!lock_monitor_exit(aRef))
+       THROW0;
+  CLEAR_global_sp;
 #endif
 }
 
-CHECKNULL ( aRef -- aRef ) 0xc3
+CHECKNULL ( aRef -- aRef )
 {
   CHECK_NULL_PTR(aRef);
 }
 
-MULTIANEWARRAY ( #avftbl #iSize #acr -- aRef ) 197
+MULTIANEWARRAY ( #aClass #iSize #acr ... -- aRef )
 {
-  long dims[iSize];
+  long *dims;
   int i;
-  IF_spTOS(sp[0] = spTOS);
-  for (i=0; i<iSize; i++) {
-    dims[i]=sp[iSize-i-1];
+
+  dims = MNEW(long, iSize);
+
+  for (i = 0; i < iSize; i++) {
+    dims[i] = sp[iSize - i - 1];
+  }
+  global_sp = sp;
+  aRef = (java_objectheader *) builtin_multianewarray(iSize, aClass, dims);
+
+  MFREE(dims, long, iSize);
+
+  if (aRef == NULL) {
+    global_sp = sp;
+    *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
+    CLEAR_global_sp;
+    THROW0;
   }
-  global_sp=sp;
-  aRef = (java_objectheader *)builtin_multianewarray(iSize, avftbl, dims);
   CLEAR_global_sp;
   sp += iSize;
-  IF_spTOS(spTOS = sp[0]);
 }
 
 IFNULL ( #ainstTarget aRef -- )  0xc6
 {
   if ( aRef == NULL ) {
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
   }
 }
 
 IFNONNULL ( #ainstTarget aRef -- ) 0xc7
 {
   if ( aRef != NULL ) {
-    SET_IP(ainstTarget); INST_TAIL;
+    SET_IP(ainstTarget);
   }
 }
 
-\ patchers for stuff that is unknown at compile time (unloaded classes)
+\ patchers for resolving fields
 
-PATCHER_GETSTATIC_INT ( #aRef #auf -- )
+PATCHER_GETSTATIC_INT ( #aRef #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putstatic((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
 IP[-3] = INST_ADDR(GETSTATIC_INT);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_GETSTATIC_LONG ( #aRef #auf -- )
+PATCHER_GETSTATIC_FLOAT ( #aRef #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putstatic((u1 *)(IP-3)))
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic((u1 *)(IP-3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
   THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(GETSTATIC_LONG);
+IP[-3] = INST_ADDR(GETSTATIC_FLOAT);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_GETSTATIC_CELL ( #aRef #auf -- )
+PATCHER_GETSTATIC_LONG ( #aRef #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putstatic((u1 *)(IP-3)))
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
   THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(GETSTATIC_LONG);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+PATCHER_GETSTATIC_CELL ( #aRef #auf ... -- )
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
 IP[-3] = INST_ADDR(GETSTATIC_CELL);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+\ patchers for statically initializing classes
 
-PATCHER_PUTSTATIC_INT ( #aRef #auf -- )
+PATCHER_GETSTATIC_CLINIT_INT ( #aRef #afi ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putstatic((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(PUTSTATIC_INT);
+IP[-3] = INST_ADDR(GETSTATIC_INT);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_PUTSTATIC_LONG ( #aRef #auf -- )
+PATCHER_GETSTATIC_CLINIT_FLOAT ( #aRef #afi ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putstatic((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic_clinit((u1 *)(IP-3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(PUTSTATIC_LONG);
+IP[-3] = INST_ADDR(GETSTATIC_FLOAT);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_PUTSTATIC_CELL ( #aRef #auf -- )
+PATCHER_GETSTATIC_CLINIT_LONG ( #aRef #afi ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putstatic((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(PUTSTATIC_CELL);
+IP[-3] = INST_ADDR(GETSTATIC_LONG);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_GETFIELD_INT ( #iOffset #auf -- )
+PATCHER_GETSTATIC_CLINIT_CELL ( #aRef #afi ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putfield((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(GETFIELD_INT);
+IP[-3] = INST_ADDR(GETSTATIC_CELL);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+\ patchers for resolving fields
 
-PATCHER_GETFIELD_LONG ( #iOffset #auf -- )
+PATCHER_PUTSTATIC_INT ( #aRef #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putfield((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(GETFIELD_LONG);
+IP[-3] = INST_ADDR(PUTSTATIC_INT);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_GETFIELD_CELL ( #iOffset #auf -- )
+PATCHER_PUTSTATIC_FLOAT ( #aRef #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putfield((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic((u1 *)(IP-3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(GETFIELD_CELL);
+IP[-3] = INST_ADDR(PUTSTATIC_FLOAT);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_PUTFIELD_INT ( #iOffset #auf -- )
+PATCHER_PUTSTATIC_LONG ( #aRef #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putfield((u1 *)(IP-3)))
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
   THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(PUTSTATIC_LONG);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+PATCHER_PUTSTATIC_CELL ( #aRef #auf ... -- )
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(PUTFIELD_INT);
+IP[-3] = INST_ADDR(PUTSTATIC_CELL);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+\ patchers for statically initializing classes
 
-PATCHER_PUTFIELD_LONG ( #iOffset #auf -- )
+PATCHER_PUTSTATIC_CLINIT_INT ( #aRef #afi ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putfield((u1 *)(IP-3)))
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
   THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(PUTSTATIC_INT);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+PATCHER_PUTSTATIC_CLINIT_FLOAT ( #aRef #afi ... -- )
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic_clinit((u1 *)(IP-3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(PUTFIELD_LONG);
+IP[-3] = INST_ADDR(PUTSTATIC_FLOAT);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_PUTFIELD_CELL ( #iOffset #auf -- )
+PATCHER_PUTSTATIC_CLINIT_LONG ( #aRef #afi ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_get_putfield((u1 *)(IP-3)))
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
   THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(PUTSTATIC_LONG);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+PATCHER_PUTSTATIC_CLINIT_CELL ( #aRef #afi ... -- )
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(PUTFIELD_CELL);
+IP[-3] = INST_ADDR(PUTSTATIC_CELL);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-NEW1 ( #aClass acrUnused -- aRef ) 0xbb
-{
-  /* fprintf(stderr,"new: class %lx, class-state=%d\n",(long)aClass,((Hjava_lang_Class*)aClass)->state); */
-  global_sp=sp;
-  aRef = builtin_new((classinfo *)aClass);
-  CLEAR_global_sp;
-}
+\ patchers for resolving fields
 
-PATCHER_NEW ( #aClass -- )
-/* the unresolved class is in the cell right before this VM instruction;
-   our code generator guarantees thus */
+PATCHER_GETFIELD_INT ( #vOffset #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_builtin_new((u1 *)(IP-2)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putfield((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-2] = INST_ADDR(NEW1);
-SET_IP(IP-2);
-
-NEWARRAY1 ( iSize #avftbl avftblUnused -- aRef ) 0xbd
-{
-  global_sp=sp;
-  aRef = (java_objectheader *)builtin_newarray(iSize, (vftbl_t *)avftbl);
-  CLEAR_global_sp;
-}
+IP[-3] = INST_ADDR(GETFIELD_INT);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_NEWARRAY ( #avftbl -- )
-/* the unresolved class is in the cell right before this VM instruction;
-   our code generator guarantees thus */
+PATCHER_GETFIELD_FLOAT ( #vOffset #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_builtin_newarray((u1 *)(IP-2)))
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putfield((u1 *)(IP-3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
   THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(GETFIELD_FLOAT);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+PATCHER_GETFIELD_LONG ( #vOffset #auf ... -- )
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putfield((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-2] = INST_ADDR(NEWARRAY1);
-SET_IP(IP-2);
+IP[-3] = INST_ADDR(GETFIELD_LONG);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_MULTIANEWARRAY ( #avftbl #iSize #acr -- )
+PATCHER_GETFIELD_CELL ( #vOffset #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_builtin_multianewarray((u1 *)(IP-4)))
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putfield((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
   THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(GETFIELD_CELL);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+PATCHER_PUTFIELD_INT ( #vOffset #auf ... -- )
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putfield((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-4] = INST_ADDR(MULTIANEWARRAY);
-SET_IP(IP-4);
+IP[-3] = INST_ADDR(PUTFIELD_INT);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-ARRAYINSTANCEOF1 ( aRef #avftbl avftblUnused -- iResult ) 0xc1
-{
-  iResult = builtin_arrayinstanceof(aRef, avftbl);
-}
+PATCHER_PUTFIELD_FLOAT ( #vOffset #auf ... -- )
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putfield((u1 *)(IP-3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
+  THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(PUTFIELD_FLOAT);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_ARRAYINSTANCEOF ( #avftbl -- )
-/* the unresolved class is in the cell right before this VM instruction;
-   our code generator guarantees thus */
+PATCHER_PUTFIELD_LONG ( #vOffset #auf ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_builtin_newarray((u1 *)(IP-2)))
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putfield((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
   THROW0;
+STORE_ORDER_BARRIER();
+IP[-3] = INST_ADDR(PUTFIELD_LONG);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
+
+PATCHER_PUTFIELD_CELL ( #vOffset #auf ... -- )
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_get_putfield((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-2] = INST_ADDR(ARRAYINSTANCEOF1);
-SET_IP(IP-2);
+IP[-3] = INST_ADDR(PUTFIELD_CELL);
+SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_INVOKESTATIC ( #aaTarget #iNargs #aum -- ) 0xd8
+\ other patchers for lazy resolving
+
+PATCHER_MULTIANEWARRAY ( #aClass #iSize #acr ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_invokestatic_special((u1 *)(IP-4)))
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_builtin_multianewarray((u1 *) (IP - 4));
+stacktrace_remove_stackframeinfo(&sfi);
+CLEAR_global_sp;
+if (!result)
   THROW0;
+STORE_ORDER_BARRIER();
+IP[-4] = INST_ADDR(MULTIANEWARRAY);
+SET_IP(IP - 4);
+patchersuper_rewrite(IP);
+
+PATCHER_INVOKESTATIC ( #aaTarget #iNargs #aum ... -- ) 0xd8
+stackframeinfo sfi;
+bool result;
+global_sp = sp;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_invokestatic_special((u1 *) (IP - 4));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
 IP[-4] = INST_ADDR(INVOKESTATIC);
 SET_IP(IP-4);
+patchersuper_rewrite(IP);
 
-PATCHER_INVOKESPECIAL ( #aaTarget #iNargs #aum -- ) 0xd8
+PATCHER_INVOKESPECIAL ( #aaTarget #iNargs #aum ... -- ) 0xd8
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_invokestatic_special((u1 *)(IP-4)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_invokestatic_special((u1 *) (IP - 4));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
 IP[-4] = INST_ADDR(INVOKESPECIAL);
 SET_IP(IP-4);
+patchersuper_rewrite(IP);
 
-PATCHER_INVOKEVIRTUAL ( #iOffset #iNargs #aum -- ) 0xd8
+PATCHER_INVOKEVIRTUAL ( #vOffset #iNargs #aum ... -- ) 0xd8
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_invokevirtual((u1 *)(IP-4)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_invokevirtual((u1 *) (IP - 4));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
 IP[-4] = INST_ADDR(INVOKEVIRTUAL);
 SET_IP(IP-4);
+patchersuper_rewrite(IP);
 
-PATCHER_INVOKEINTERFACE ( #iInterfaceoffset #iOffset #iNargs #aum -- ) 0xd8
+PATCHER_INVOKEINTERFACE ( #iInterfaceoffset #vOffset #iNargs #aum ... -- ) 0xd8
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_invokeinterface((u1 *)(IP-5)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_invokeinterface((u1 *) (IP - 5));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
 IP[-5] = INST_ADDR(INVOKEINTERFACE);
 SET_IP(IP-5);
+patchersuper_rewrite(IP);
 
-PATCHER_CHECKCAST ( #aClass #acr -- ) 0xc
+PATCHER_CHECKCAST ( #aClass #acr ... -- ) 0xc
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_checkcast_instanceof((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_checkcast_instanceof((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
 IP[-3] = INST_ADDR(CHECKCAST);
 SET_IP(IP-3);
+patchersuper_rewrite(IP);
 
-PATCHER_ARRAYCHECKCAST ( #avftbl #acr -- ) 0xc0
+PATCHER_INSTANCEOF ( #aClass #acr ... -- ) 0xc1
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_builtin_arraycheckcast((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_checkcast_instanceof((u1 *) (IP - 3));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
-STORE_ORDER_BARRIER();
-IP[-3] = INST_ADDR(ARRAYCHECKCAST);
-SET_IP(IP-3);
-
-PATCHER_INSTANCEOF ( #aClass #acr -- ) 0xc1
-global_sp = sp;
-if (!patcher_checkcast_instanceof((u1 *)(IP-3)))
+if (!result)
   THROW0;
-CLEAR_global_sp;
 STORE_ORDER_BARRIER();
 IP[-3] = INST_ADDR(INSTANCEOF);
 SET_IP(IP-3);
-
-\ CHECKEXCEPTION could be integrated into NEW etc., but that's not as
-\ nice to maintain.
-
-CHECKEXCEPTION ( aRef -- aRef )
-if (aRef==NULL)
-  THROW0;
+patchersuper_rewrite(IP);
 
 \ This is stub code for methods that we have not yet translated.
 \ Initially, the code for each method is set to this stub. The
 \ first time the method is called, the code in the stub runs, which
 \ translates the bytecode, and replaces the stub with the threaded code.
 
-TRANSLATE ( #am -- )
+TRANSLATE ( #am ... --  )
 {
   Inst *codeptr;
+  stackframeinfo sfi;
+  Cell *acelloldfp;
+  Inst *ainstoldip;
   ;
-  IF_spTOS(sp[0] = spTOS);
+  vm_Cell2acell(sp[1],acelloldfp);
+  vm_Cell2ainst(sp[0],ainstoldip);
   global_sp = sp;
-  codeptr = (Inst *)jit_compile(am);
+  stacktrace_create_extern_stackframeinfo(&sfi, NULL, (u1 *) acelloldfp, (u1 *) ainstoldip, (u1 *) ainstoldip);
+  codeptr = (Inst *) jit_compile(am);
+  stacktrace_remove_stackframeinfo(&sfi);
+  if (codeptr == NULL) {
+    fp = acelloldfp;
+    SET_IP(ainstoldip); /* set up ip and fp for throw */
+    THROW0;
+  }
   CLEAR_global_sp;
   IP[-4] = codeptr;
   SET_IP(codeptr);
 }
 
-NATIVECALL ( #am #af acelloldfp ainstoldip -- )
-sp = nativecall(af, am, sp);
-IF_spTOS(spTOS = sp[0]);
+NATIVECALL ( #am #af #addrcif ... acelloldfp ainstoldip -- )
+sp = nativecall(af, am, sp, ainstoldip, acelloldfp, addrcif);
 fp = acelloldfp;
 SET_IP(ainstoldip);
+if (*exceptionptr)
+  THROW0;
+
 
-TRACENATIVECALL ( #am #af acelloldfp ainstoldip -- )
-sp = nativecall(af, am, sp);
-IF_spTOS(spTOS = sp[0]);
+TRACENATIVECALL ( #am #af #addrcif ... acelloldfp ainstoldip -- )
+sp = nativecall(af, am, sp, ainstoldip, acelloldfp, addrcif);
 fp = acelloldfp;
 SET_IP(ainstoldip);
 {
-Cell v = spTOS;
-functionptr fp = codegen_findmethod((functionptr)(IP-1));
-methodinfo *m = ((methodinfo **) fp)[-1];
+Cell v = sp[0];
 float f;
 vm_Cell2f(v,f);
-builtin_displaymethodstop(m, (s8)v, f, f);
+#if !defined(NDEBUG)
+builtin_verbosecall_exit((s8) v, f, f, am);
+#endif
 }
+if (*exceptionptr)
+  THROW0;
 
-PATCHER_NATIVECALL ( #am #af -- )
-#if !defined(ENABLE_STATICVM)
+PATCHER_NATIVECALL ( #am #af #addrcif ... -- )
+stackframeinfo sfi;
+bool result;
 global_sp = sp;
-if (!patcher_resolve_native((u1 *)(IP-3)))
-  THROW0;
+stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
+result = intrp_patcher_resolve_native((u1 *) (IP - 4));
+stacktrace_remove_stackframeinfo(&sfi);
 CLEAR_global_sp;
+if (!result)
+  THROW0;
 STORE_ORDER_BARRIER();
-IP[-3] = runverbose ? INST_ADDR(TRACENATIVECALL) : INST_ADDR(NATIVECALL);
-SET_IP(IP-3);
-#else
-assert(false);
+IP[-4] = opt_verbosecall ? INST_ADDR(TRACENATIVECALL) : INST_ADDR(NATIVECALL);
+SET_IP(IP - 4);
+patchersuper_rewrite(IP);
+
+TRACECALL ( #am -- )
+#if !defined(NDEBUG)
+#if SIZEOF_VOID_P == 4
+{
+    s8 args[TRACE_ARGS_NUM];
+    int i;
+    int ofs = 0;
+    typedesc *params = am->parseddesc->paramtypes;
+    for (i=0; i < TRACE_ARGS_NUM; ++i, ++params) {
+        if (IS_2_WORD_TYPE(params->type)) {
+            vm_twoCell2l(access_local_cell(ofs), access_local_cell(ofs - SIZEOF_VOID_P), args[i]);
+            ofs -= 2*SIZEOF_VOID_P;
+        }
+        else {
+            args[i] = access_local_cell(ofs);
+            ofs -= SIZEOF_VOID_P;
+        }
+    }
+    builtin_verbosecall_enter(args[0], args[1], args[2], args[3],  
+#if TRACE_ARGS_NUM > 4
+                              args[4], args[5],
 #endif
-
-TRACECALL ( -- )
-functionptr f = codegen_findmethod((functionptr)(IP-1));
-methodinfo *m = ((methodinfo **) f)[-1];
-builtin_trace_args(
-       access_local_cell(0),
-       access_local_cell(1),
-       access_local_cell(2),
-       access_local_cell(3),
+#if TRACE_ARGS_NUM == 8
+                              args[6], args[7],
+#endif
+                              am);
+}
+#else /* SIZEOF_VOID_P */
+    builtin_verbosecall_enter(
+        access_local_cell(0 * -SIZEOF_VOID_P),
+        access_local_cell(1 * -SIZEOF_VOID_P),
+        access_local_cell(2 * -SIZEOF_VOID_P),
+        access_local_cell(3 * -SIZEOF_VOID_P),
 #if TRACE_ARGS_NUM > 4
-       access_local_cell(4),
-       access_local_cell(5),
+        access_local_cell(4 * -SIZEOF_VOID_P),
+        access_local_cell(5 * -SIZEOF_VOID_P),
 #endif
 #if TRACE_ARGS_NUM == 8
-       access_local_cell(6),
-       access_local_cell(7),
+        access_local_cell(6 * -SIZEOF_VOID_P),
+        access_local_cell(7 * -SIZEOF_VOID_P),
 #endif
-       m);
+        am);
+#endif /* SIZEOF_VOID_P */
+#endif /* !defined(NDEBUG) */
 
-TRACERETURN ( v -- v )
-functionptr fp = codegen_findmethod((functionptr)(IP-1));
-methodinfo *m = ((methodinfo **) fp)[-1];
+TRACERETURN ( #am v -- v )
 float f;
 vm_Cell2f(v,f);
-builtin_displaymethodstop(m, (s8)v, f, f);
+#if !defined(NDEBUG)
+builtin_verbosecall_exit((s8) v, f, f, am);
+#endif
 
-TRACELRETURN ( l -- l )
-functionptr fp = codegen_findmethod((functionptr)(IP-1));
-methodinfo *m = ((methodinfo **) fp)[-1];
+TRACELRETURN ( #am l -- l )
 Double_Store ds;
 ds.l = l;
-builtin_displaymethodstop(m, l, ds.d, ds.d);
+#if !defined(NDEBUG)
+builtin_verbosecall_exit(l, ds.d, ds.d, am);
+#endif
 
-END ( -- )
-IF_spTOS(sp[0] = spTOS);
+END ( ... -- )
 global_sp = sp;
 SUPER_END;
 vm_uncount_block(IP); /* undo the count part of SUPER_END,
                         because there is no fallthrough */
 return NULL;
 
-ICONST_ISTORE = ICONST ISTORE
+_ALOAD_GETFIELD_CELL_ =  ALOAD GETFIELD_CELL 
+_DUP_ICONST_ =  DUP ICONST 
+_ALOAD_ALOAD_ =  ALOAD ALOAD 
+_ICONST_ICONST_ =  ICONST ICONST 
+_DUP_ICONST_ICONST_ =  DUP ICONST ICONST 
+_ICONST_CASTORE_ =  ICONST CASTORE 
+_ICONST_ICONST_CASTORE_ =  ICONST ICONST CASTORE 
+_DUP_ICONST_ICONST_CASTORE_ =  DUP ICONST ICONST CASTORE 
+_CASTORE_DUP_ =  CASTORE DUP 
+_CASTORE_DUP_ICONST_ =  CASTORE DUP ICONST 
+_DUP_ICONST_ICONST_CASTORE_DUP_ =  DUP ICONST ICONST CASTORE DUP 
+_ICONST_CASTORE_DUP_ =  ICONST CASTORE DUP 
+_ICONST_CASTORE_DUP_ICONST_ =  ICONST CASTORE DUP ICONST 
+_ICONST_ICONST_CASTORE_DUP_ =  ICONST ICONST CASTORE DUP 
+_ICONST_ICONST_CASTORE_DUP_ICONST_ =  ICONST ICONST CASTORE DUP ICONST 
+_CASTORE_DUP_ICONST_ICONST_ =  CASTORE DUP ICONST ICONST 
+_CASTORE_DUP_ICONST_ICONST_CASTORE_ =  CASTORE DUP ICONST ICONST CASTORE 
+_ICONST_CASTORE_DUP_ICONST_ICONST_ =  ICONST CASTORE DUP ICONST ICONST 
+_ASTORE_ALOAD_ =  ASTORE ALOAD 
+_ALOAD_GETFIELD_INT_ =  ALOAD GETFIELD_INT 
+_ALOAD_ILOAD_ =  ALOAD ILOAD 
+_ALOAD_ACONST_ =  ALOAD ACONST 
+_ICONST_ACONST_ =  ICONST ACONST 
+_AASTORE_DUP_ =  AASTORE DUP 
+_AASTORE_DUP_ICONST_ =  AASTORE DUP ICONST 
+_ALOAD_ICONST_ =  ALOAD ICONST 
+_ILOAD_ICONST_ =  ILOAD ICONST 
+_ILOAD_ILOAD_ =  ILOAD ILOAD 
+_DUP_ICONST_ACONST_ =  DUP ICONST ACONST 
+_GETFIELD_CELL_ALOAD_ =  GETFIELD_CELL ALOAD 
+_AASTORE_DUP_ICONST_ACONST_ =  AASTORE DUP ICONST ACONST 
+_ACONST_AASTORE_ =  ACONST AASTORE 
+_ICONST_ACONST_AASTORE_ =  ICONST ACONST AASTORE 
+_DUP_ICONST_ACONST_AASTORE_ =  DUP ICONST ACONST AASTORE 
+_ALOAD_GETFIELD_CELL_ALOAD_ =  ALOAD GETFIELD_CELL ALOAD 
+_ACONST_AASTORE_DUP_ =  ACONST AASTORE DUP 
+_ACONST_AASTORE_DUP_ICONST_ =  ACONST AASTORE DUP ICONST 
+_DUP_ICONST_ACONST_AASTORE_DUP_ =  DUP ICONST ACONST AASTORE DUP 
+_ICONST_ACONST_AASTORE_DUP_ =  ICONST ACONST AASTORE DUP 
+_ICONST_ACONST_AASTORE_DUP_ICONST_ =  ICONST ACONST AASTORE DUP ICONST 
+_AASTORE_DUP_ICONST_ACONST_AASTORE_ =  AASTORE DUP ICONST ACONST AASTORE 
+_DUP_ACONST_ =  DUP ACONST 
+_ACONST_AASTORE_DUP_ICONST_ACONST_ =  ACONST AASTORE DUP ICONST ACONST 
+_PUTFIELD_CELL_ALOAD_ =  PUTFIELD_CELL ALOAD 
+_ILOAD_ALOAD_ =  ILOAD ALOAD 
+_ICONST_ALOAD_ =  ICONST ALOAD 
+_DUP_ALOAD_ =  DUP ALOAD 
+_ICONST_ISTORE_ =  ICONST ISTORE 
+_ASTORE_ALOAD_ALOAD_ =  ASTORE ALOAD ALOAD 
+_ALOAD_PUTFIELD_CELL_ =  ALOAD PUTFIELD_CELL 
+_PUTFIELD_INT_ALOAD_ =  PUTFIELD_INT ALOAD 
+_ALOAD_ALOAD_PUTFIELD_CELL_ =  ALOAD ALOAD PUTFIELD_CELL 
+_ICONST_IADD_ =  ICONST IADD 
+_ISTORE_GOTO_ =  ISTORE GOTO 
+_ACONST_ACONST_ =  ACONST ACONST 
+_POP_ALOAD_ =  POP ALOAD 
+_ACONST_ICONST_ =  ACONST ICONST 
+_ALOAD_ALOAD_ALOAD_ =  ALOAD ALOAD ALOAD 
+_ALOAD_ALOAD_GETFIELD_CELL_ =  ALOAD ALOAD GETFIELD_CELL 
+_ISTORE_ALOAD_ =  ISTORE ALOAD 
+_GETFIELD_CELL_ILOAD_ =  GETFIELD_CELL ILOAD 
+_IINC_ILOAD_ =  IINC ILOAD 
+_ISTORE_ILOAD_ =  ISTORE ILOAD 
+_ALOAD_GETFIELD_CELL_ILOAD_ =  ALOAD GETFIELD_CELL ILOAD 
+_ILOAD_ICONST_IADD_ =  ILOAD ICONST IADD 
+_CHECKCAST_ASTORE_ =  CHECKCAST ASTORE 
+_ASTORE_ACONST_ =  ASTORE ACONST 
+_GETFIELD_INT_ALOAD_ =  GETFIELD_INT ALOAD 
+_ACONST_ALOAD_ =  ACONST ALOAD 
+_ICONST_ISTORE_GOTO_ =  ICONST ISTORE GOTO 
+_CHECKCAST_ASTORE_ALOAD_ =  CHECKCAST ASTORE ALOAD 
+_ASTORE_GOTO_ =  ASTORE GOTO 
+_ALOAD_PUTFIELD_CELL_ALOAD_ =  ALOAD PUTFIELD_CELL ALOAD 
+_ALOAD_ALOAD_PUTFIELD_CELL_ALOAD_ =  ALOAD ALOAD PUTFIELD_CELL ALOAD 
+_ICONST_PUTFIELD_INT_ =  ICONST PUTFIELD_INT 
+_ALOAD_IFNULL_ =  ALOAD IFNULL 
+_ALOAD_IFNONNULL_ =  ALOAD IFNONNULL 
+_ALOAD_ICONST_PUTFIELD_INT_ =  ALOAD ICONST PUTFIELD_INT 
+_ALOAD_GETFIELD_INT_ALOAD_ =  ALOAD GETFIELD_INT ALOAD 
+_ALOAD_ILOAD_ILOAD_ =  ALOAD ILOAD ILOAD 
+_DUP_ICONST_ALOAD_ =  DUP ICONST ALOAD 
+_IADD_ILOAD_ =  IADD ILOAD 
+_GETFIELD_CELL_ICONST_ =  GETFIELD_CELL ICONST 
+_ILOAD_PUTFIELD_INT_ =  ILOAD PUTFIELD_INT 
+_GETFIELD_INT_ALOAD_GETFIELD_INT_ =  GETFIELD_INT ALOAD GETFIELD_INT 
+_GETFIELD_CELL_GETFIELD_CELL_ =  GETFIELD_CELL GETFIELD_CELL 
+_ALOAD_ACONST_ACONST_ =  ALOAD ACONST ACONST 
+_ALOAD_ARRAYLENGTH_ =  ALOAD ARRAYLENGTH 
+_GETFIELD_CELL_IFNULL_ =  GETFIELD_CELL IFNULL 
+_ICONST_ISUB_ =  ICONST ISUB 
+_ALOAD_ILOAD_PUTFIELD_INT_ =  ALOAD ILOAD PUTFIELD_INT 
+_ALOAD_GETFIELD_CELL_GETFIELD_CELL_ =  ALOAD GETFIELD_CELL GETFIELD_CELL 
+_PUTFIELD_CELL_ALOAD_ALOAD_ =  PUTFIELD_CELL ALOAD ALOAD 
+_ILOAD_AALOAD_ =  ILOAD AALOAD 
+_ALOAD_MONITOREXIT_ =  ALOAD MONITOREXIT 
+_ALOAD_CHECKCAST_ =  ALOAD CHECKCAST 
+_ALOAD_GETFIELD_CELL_ICONST_ =  ALOAD GETFIELD_CELL ICONST 
+_ICONST_ILOAD_ =  ICONST ILOAD 
+_ACONST_ICONST_ICONST_ =  ACONST ICONST ICONST 
+_ALOAD_GETFIELD_CELL_IFNULL_ =  ALOAD GETFIELD_CELL IFNULL