Java Source Code: com.sun.tools.javac.jvm.Code


   1: /*
   2:  * @(#)Code.java    1.63 06/11/11
   3:  * 
   4:  * Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
   5:  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6:  *  
   7:  * This code is free software; you can redistribute it and/or modify it
   8:  * under the terms of the GNU General Public License version 2 only, as
   9:  * published by the Free Software Foundation.  Sun designates this
  10:  * particular file as subject to the "Classpath" exception as provided
  11:  * by Sun in the LICENSE file that accompanied this code.
  12:  *  
  13:  * This code is distributed in the hope that it will be useful, but WITHOUT
  14:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15:  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16:  * version 2 for more details (a copy is included in the LICENSE file that
  17:  * accompanied this code).
  18:  *  
  19:  * You should have received a copy of the GNU General Public License version
  20:  * 2 along with this work; if not, write to the Free Software Foundation,
  21:  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22:  *  
  23:  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  24:  * CA 95054 USA or visit www.sun.com if you need additional information or
  25:  * have any questions.
  26:  */
  27: 
  28: package com.sun.tools.javac.jvm;
  29: 
  30: import com.sun.tools.javac.code.*;
  31: import com.sun.tools.javac.code.Symbol.*;
  32: import com.sun.tools.javac.util.*;
  33: import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  34: 
  35: import static com.sun.tools.javac.code.TypeTags.*;
  36: import static com.sun.tools.javac.jvm.ByteCodes.*;
  37: import static com.sun.tools.javac.jvm.UninitializedType.*;
  38: import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
  39: 
  40: /** An internal structure that corresponds to the code attribute of
  41:  *  methods in a classfile. The class also provides some utility operations to
  42:  *  generate bytecode instructions.
  43:  *
  44:  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
  45:  *  you write code that depends on this, you do so at your own risk.
  46:  *  This code and its internal interfaces are subject to change or
  47:  *  deletion without notice.</b>
  48:  */
  49: @Version("@(#)Code.java    1.63 06/11/11")
  50:	  public class Code {
  51:
  52:    public final boolean debugCode;
  53:    public final boolean needStackMap;
  54:    
  55:	      public enum StackMapFormat {
  56:    NONE,
  57:	      CLDC {
  58:	          Name getAttributeName(Name.Table names) {
  59:        return names.StackMap;
  60:            }   
  61:    }, 
  62:	      JSR202 {
  63:	              Name getAttributeName(Name.Table names) {
  64:        return names.StackMapTable;
  65:            }   
  66:    };
  67:	      Name getAttributeName(Name.Table names) {
  68:            return names.empty;
  69:    }        
  70:    }
  71:    
  72:    final Types types;
  73:    final Symtab syms;
  74:
  75:/*---------- classfile fields: --------------- */
  76:
  77:    /** The maximum stack size.
  78:     */
  79:    public int max_stack = 0;
  80:
  81:    /** The maximum number of local variable slots.
  82:     */
  83:    public int max_locals = 0;
  84:
  85:    /** The code buffer.
  86:     */
  87:    public byte[] code = new byte[64];
  88:
  89:    /** the current code pointer.
  90:     */
  91:    public int cp = 0;
  92:
  93:    /** Check the code against VM spec limits; if
  94:     *  problems report them and return true.
  95:     */
  96:	      public boolean checkLimits(DiagnosticPosition pos, Log log) {
  97:	      if (cp > ClassFile.MAX_CODE) {
  98:        log.error(pos, "limit.code");
  99:        return true;
 100:    }
 101:	      if (max_locals > ClassFile.MAX_LOCALS) {
 102:        log.error(pos, "limit.locals");
 103:        return true;
 104:    }
 105:	      if (max_stack > ClassFile.MAX_STACK) {
 106:        log.error(pos, "limit.stack");
 107:        return true;
 108:    }
 109:    return false;
 110:    }
 111:
 112:    /** A buffer for expression catch data. Each enter is a vector
 113:     *  of four unsigned shorts.
 114:     */
 115:    ListBuffer<char[]> catchInfo = new ListBuffer<char[]>();
 116:
 117:    /** A buffer for line number information. Each entry is a vector
 118:     *  of two unsigned shorts.
 119:     */
 120:    List<char[]> lineInfo = List.nil(); // handled in stack fashion
 121:
 122:    /** The CharacterRangeTable
 123:     */
 124:    public CRTable crt;
 125:
 126:/*---------- internal fields: --------------- */
 127:
 128:    /** Are we generating code with jumps >= 32K?
 129:     */
 130:    public boolean fatcode;
 131:
 132:    /** Code generation enabled?
 133:     */
 134:    private boolean alive = true;
 135:
 136:    /** The current machine state (registers and stack).
 137:     */
 138:    State state;
 139:
 140:    /** Is it forbidden to compactify code, because something is
 141:     *  pointing to current location?
 142:     */
 143:    private boolean fixedPc = false;
 144:
 145:    /** The next available register.
 146:     */
 147:    public int nextreg = 0;
 148:
 149:    /** A chain for jumps to be resolved before the next opcode is emitted.
 150:     *  We do this lazily to avoid jumps to jumps.
 151:     */
 152:    Chain pendingJumps = null;
 153:
 154:    /** The position of the currently statement, if we are at the
 155:     *  start of this statement, NOPOS otherwise.
 156:     *  We need this to emit line numbers lazily, which we need to do
 157:     *  because of jump-to-jump optimization.
 158:     */
 159:    int pendingStatPos = Position.NOPOS;
 160:
 161:    /** Set true when a stackMap is needed at the current PC. */
 162:    boolean pendingStackMap = false;
 163:    
 164:    /** The stack map format to be generated. */
 165:    StackMapFormat stackMap;
 166:    
 167:    /** Switch: emit variable debug info.
 168:     */
 169:    boolean varDebugInfo;
 170:
 171:    /** Switch: emit line number info.
 172:     */
 173:    boolean lineDebugInfo;
 174:    
 175:    /** Emit line number info if map supplied
 176:     */
 177:    Position.LineMap lineMap;
 178:
 179:    /** The constant pool of the current class.
 180:     */
 181:    final Pool pool;
 182:
 183:    final MethodSymbol meth;
 184:
 185:    /** Construct a code object, given the settings of the fatcode,
 186:     *  debugging info switches and the CharacterRangeTable.
 187:     */
 188:    public Code(MethodSymbol meth,
 189:        boolean fatcode,
 190:        Position.LineMap lineMap,
 191:        boolean varDebugInfo,
 192:        StackMapFormat stackMap,
 193:        boolean debugCode,
 194:        CRTable crt,
 195:        Symtab syms,
 196:        Types types,
 197:	          Pool pool) {
 198:    this.meth = meth;
 199:    this.fatcode = fatcode;
 200:    this.lineMap = lineMap;
 201:    this.lineDebugInfo = lineMap != null;
 202:    this.varDebugInfo = varDebugInfo;
 203:    this.crt = crt;
 204:    this.syms = syms;
 205:    this.types = types;
 206:    this.debugCode = debugCode;
 207:    this.stackMap = stackMap;
 208:	      switch (stackMap) {
 209:    case CLDC:
 210:    case JSR202:
 211:        this.needStackMap = true;
 212:        break;
 213:    default:
 214:        this.needStackMap = false;
 215:    }
 216:    state = new State();
 217:    lvar = new LocalVar[20];
 218:    this.pool = pool;
 219:    }
 220:
 221:
 222:/* **************************************************************************
 223: * Typecodes & related stuff
 224: ****************************************************************************/
 225:
 226:    /** Given a type, return its type code (used implicitly in the
 227:     *  JVM architecture).
 228:     */
 229:	      public static int typecode(Type type) {
 230:	          switch (type.tag) {
 231:    case BYTE: return BYTEcode;
 232:    case SHORT: return SHORTcode;
 233:    case CHAR: return CHARcode;
 234:    case INT: return INTcode;
 235:    case LONG: return LONGcode;
 236:    case FLOAT: return FLOATcode;
 237:    case DOUBLE: return DOUBLEcode;
 238:    case BOOLEAN: return BYTEcode;
 239:    case VOID: return VOIDcode;
 240:        case CLASS:
 241:    case ARRAY:
 242:    case METHOD:
 243:    case BOT:
 244:    case TYPEVAR:
 245:    case UNINITIALIZED_THIS:
 246:    case UNINITIALIZED_OBJECT:
 247:        return OBJECTcode;
 248:        default: throw new AssertionError("typecode " + type.tag);
 249:        }
 250:    }
 251:
 252:    /** Collapse type code for subtypes of int to INTcode.
 253:     */
 254:	      public static int truncate(int tc) {
 255:	          switch (tc) {
 256:        case BYTEcode: case SHORTcode: case CHARcode: return INTcode;
 257:        default: return tc;
 258:        }
 259:    }
 260:
 261:    /** The width in bytes of objects of the type.
 262:     */
 263:	      public static int width(int typecode) {
 264:	          switch (typecode) {
 265:        case LONGcode: case DOUBLEcode: return 2;
 266:    case VOIDcode: return 0;
 267:        default: return 1;
 268:        }
 269:    }
 270:
 271:	      public static int width(Type type) {
 272:    return type == null ? 1 : width(typecode(type));
 273:    }
 274:
 275:    /** The total width taken up by a vector of objects.
 276:     */
 277:	      public static int width(List<Type> types) {
 278:        int w = 0;
 279:        for (List<Type> l = types; l.nonEmpty(); l = l.tail)
 280:        w = w + width(l.head);
 281:        return w;
 282:    }
 283:
 284:    /** Given a type, return its code for allocating arrays of that type.
 285:     */
 286:	      public static int arraycode(Type type) {
 287:	      switch (type.tag) {
 288:    case BYTE: return 8;
 289:    case BOOLEAN: return 4;
 290:    case SHORT: return 9;
 291:    case CHAR: return 5;
 292:    case INT: return 10;
 293:    case LONG: return 11;
 294:    case FLOAT: return 6;
 295:    case DOUBLE: return 7;
 296:        case CLASS: return 0;
 297:        case ARRAY: return 1;
 298:        default: throw new AssertionError("arraycode " + type);
 299:        }
 300:    }
 301:
 302:
 303:/* **************************************************************************
 304: * Emit code
 305: ****************************************************************************/
 306:
 307:    /** The current output code pointer.
 308:     */
 309:	      public int curPc() {
 310:    if (pendingJumps != null) resolvePending();
 311:    if (pendingStatPos != Position.NOPOS) markStatBegin();
 312:        fixedPc = true;
 313:        return cp;
 314:    }
 315:
 316:    /** Emit a byte of code.
 317:     */
 318:	      private  void emit1(int od) {
 319:        if (!alive) return;
 320:	      if (cp == code.length) {
 321:        byte[] newcode = new byte[cp * 2];
 322:        System.arraycopy(code, 0, newcode, 0, cp);
 323:        code = newcode;
 324:    }
 325:    code[cp++] = (byte)od;
 326:    }
 327:
 328:    /** Emit two bytes of code.
 329:     */
 330:	      private void emit2(int od) {
 331:        if (!alive) return;
 332:	      if (cp + 2 > code.length) {
 333:        emit1(od >> 8);
 334:        emit1(od);
 335:    } else {
 336:        code[cp++] = (byte)(od >> 8);
 337:        code[cp++] = (byte)od;
 338:    }
 339:    }
 340:
 341:    /** Emit four bytes of code.
 342:     */
 343:	      public void emit4(int od) {
 344:        if (!alive) return;
 345:	      if (cp + 4 > code.length) {
 346:        emit1(od >> 24);
 347:        emit1(od >> 16);
 348:        emit1(od >> 8);
 349:        emit1(od);
 350:    } else {
 351:        code[cp++] = (byte)(od >> 24);
 352:        code[cp++] = (byte)(od >> 16);
 353:        code[cp++] = (byte)(od >> 8);
 354:        code[cp++] = (byte)od;
 355:    }
 356:    }
 357:
 358:    /** Emit an opcode.
 359:     */
 360:	      private void emitop(int op) {
 361:    if (pendingJumps != null) resolvePending();
 362:	          if (alive) {
 363:        if (pendingStatPos != Position.NOPOS)
 364:        markStatBegin();
 365:	          if (pendingStackMap) {
 366:        pendingStackMap = false;
 367:        emitStackMap(); 
 368:        }
 369:        if (debugCode)
 370:        System.err.println("emit@" + cp + " stack=" +
 371:                   state.stacksize + ": " +
 372:                   mnem(op));
 373:            emit1(op);
 374:        }
 375:    }
 376:
 377:	      void postop() {
 378:    assert alive || state.stacksize == 0;
 379:    }
 380:
 381:    /** Emit a multinewarray instruction.
 382:     */
 383:	      public void emitMultianewarray(int ndims, int type, Type arrayType) {
 384:    emitop(multianewarray);
 385:        if (!alive) return;
 386:    emit2(type);
 387:    emit1(ndims);
 388:    state.pop(ndims);
 389:    state.push(arrayType);
 390:    }
 391:
 392:    /** Emit newarray.
 393:     */
 394:	      public void emitNewarray(int elemcode, Type arrayType) {
 395:    emitop(newarray);
 396:    if (!alive) return;
 397:    emit1(elemcode);
 398:    state.pop(1); // count
 399:    state.push(arrayType);
 400:    }
 401:
 402:    /** Emit anewarray.
 403:     */
 404:	      public void emitAnewarray(int od, Type arrayType) {
 405:        emitop(anewarray);
 406:    if (!alive) return;
 407:    emit2(od);
 408:    state.pop(1);
 409:    state.push(arrayType);
 410:    }
 411:
 412:    /** Emit an invokeinterface instruction.
 413:     */
 414:	      public void emitInvokeinterface(int meth, Type mtype) {
 415:    int argsize = width(mtype.getParameterTypes());
 416:    emitop(invokeinterface);
 417:        if (!alive) return;
 418:    emit2(meth);
 419:    emit1(argsize + 1);
 420:    emit1(0);
 421:    state.pop(argsize + 1);
 422:    state.push(mtype.getReturnType());
 423:    }
 424:
 425:    /** Emit an invokespecial instruction.
 426:     */
 427:	      public void emitInvokespecial(int meth, Type mtype) {
 428:    int argsize = width(mtype.getParameterTypes());
 429:    emitop(invokespecial);
 430:        if (!alive) return;
 431:    emit2(meth);
 432:    Symbol sym = (Symbol)pool.pool[meth];
 433:    state.pop(argsize);
 434:    if (sym.isConstructor())
 435:        state.markInitialized((UninitializedType)state.peek());
 436:    state.pop(1);
 437:    state.push(mtype.getReturnType());
 438:    }
 439:
 440:    /** Emit an invokestatic instruction.
 441:     */
 442:	      public void emitInvokestatic(int meth, Type mtype) {
 443:    int argsize = width(mtype.getParameterTypes());
 444:    emitop(invokestatic);
 445:        if (!alive) return;
 446:    emit2(meth);
 447:    state.pop(argsize);
 448:    state.push(mtype.getReturnType());
 449:    }
 450:
 451:    /** Emit an invokevirtual instruction.
 452:     */
 453:	      public void emitInvokevirtual(int meth, Type mtype) {
 454:    int argsize = width(mtype.getParameterTypes());
 455:    emitop(invokevirtual);
 456:        if (!alive) return;
 457:    emit2(meth);
 458:    state.pop(argsize + 1);
 459:    state.push(mtype.getReturnType());
 460:    }
 461:
 462:    /** Emit an opcode with no operand field.
 463:     */
 464:	      public void emitop0(int op) {
 465:    emitop(op);
 466:    if (!alive) return;
 467:	      switch (op) {
 468:	      case aaload: {
 469:        state.pop(1);// index
 470:        Type a = state.stack[state.stacksize-1];
 471:        state.pop(1);
 472:        state.push(types.erasure(types.elemtype(a))); }
 473:        break;
 474:    case goto_:
 475:        markDead();
 476:        break;
 477:    case nop:
 478:    case ineg:
 479:    case lneg:
 480:    case fneg:
 481:    case dneg:
 482:        break;
 483:    case aconst_null:
 484:        state.push(syms.botType);
 485:        break;
 486:    case iconst_m1:
 487:    case iconst_0:
 488:    case iconst_1:
 489:    case iconst_2:
 490:    case iconst_3:
 491:    case iconst_4:
 492:    case iconst_5:
 493:    case iload_0:
 494:    case iload_1:
 495:    case iload_2:
 496:    case iload_3:
 497:        state.push(syms.intType);
 498:        break;
 499:    case lconst_0:
 500:    case lconst_1:
 501:    case lload_0:
 502:    case lload_1:
 503:    case lload_2:
 504:    case lload_3:
 505:        state.push(syms.longType);
 506:        break;
 507:    case fconst_0:
 508:    case fconst_1:
 509:    case fconst_2:
 510:    case fload_0:
 511:    case fload_1:
 512:    case fload_2:
 513:    case fload_3:
 514:        state.push(syms.floatType);
 515:        break;
 516:    case dconst_0:
 517:    case dconst_1:
 518:    case dload_0:
 519:    case dload_1:
 520:    case dload_2:
 521:    case dload_3:
 522:        state.push(syms.doubleType);
 523:        break;
 524:    case aload_0:
 525:         state.push(lvar[0].sym.type);
 526:        break;
 527:    case aload_1:
 528:        state.push(lvar[1].sym.type);
 529:        break;
 530:    case aload_2:
 531:        state.push(lvar[2].sym.type);
 532:        break;
 533:    case aload_3:
 534:        state.push(lvar[3].sym.type);
 535:        break;
 536:    case iaload:
 537:    case baload:
 538:    case caload:
 539:    case saload:
 540:        state.pop(2);
 541:        state.push(syms.intType);
 542:        break;
 543:    case laload:
 544:        state.pop(2);
 545:        state.push(syms.longType);
 546:        break;
 547:    case faload:
 548:        state.pop(2);
 549:        state.push(syms.floatType);
 550:        break;
 551:    case daload:
 552:        state.pop(2);
 553:        state.push(syms.doubleType);
 554:        break;
 555:    case istore_0:
 556:    case istore_1:
 557:    case istore_2:
 558:    case istore_3:
 559:    case fstore_0:
 560:    case fstore_1:
 561:    case fstore_2:
 562:    case fstore_3:
 563:    case astore_0:
 564:    case astore_1:
 565:    case astore_2:
 566:    case astore_3:
 567:    case pop:
 568:    case lshr:
 569:    case lshl:
 570:    case lushr:
 571:        state.pop(1);
 572:        break;
 573:    case areturn:
 574:    case ireturn:
 575:    case freturn:
 576:        assert state.nlocks == 0;
 577:        state.pop(1);
 578:        markDead();
 579:        break;
 580:    case athrow:
 581:        state.pop(1);
 582:        markDead();
 583:        break;
 584:    case lstore_0:
 585:    case lstore_1:
 586:    case lstore_2:
 587:    case lstore_3:
 588:    case dstore_0:
 589:    case dstore_1:
 590:    case dstore_2:
 591:    case dstore_3:
 592:    case pop2:
 593:        state.pop(2);
 594:        break;
 595:    case lreturn:
 596:    case dreturn:
 597:        assert state.nlocks == 0;
 598:        state.pop(2);
 599:        markDead();
 600:        break;
 601:    case dup:
 602:        state.push(state.stack[state.stacksize-1]);
 603:        break;
 604:    case return_:
 605:        assert state.nlocks == 0;
 606:        markDead();
 607:        break;
 608:    case arraylength:
 609:        state.pop(1);
 610:        state.push(syms.intType);
 611:        break;
 612:    case isub:
 613:    case iadd:
 614:    case imul:
 615:    case idiv:
 616:    case imod:
 617:    case ishl:
 618:    case ishr:
 619:    case iushr:
 620:    case iand:
 621:    case ior:
 622:    case ixor:
 623:        state.pop(1);
 624:        // state.pop(1);
 625:        // state.push(syms.intType);
 626:        break;
 627:    case aastore:
 628:        state.pop(3);
 629:        break;
 630:    case land:
 631:    case lor:
 632:    case lxor:
 633:    case lmod:
 634:    case ldiv:
 635:    case lmul:
 636:    case lsub:
 637:    case ladd:
 638:        state.pop(2);
 639:        break;
 640:    case lcmp:
 641:        state.pop(4);
 642:        state.push(syms.intType);
 643:        break;
 644:    case l2i:
 645:        state.pop(2);
 646:        state.push(syms.intType);
 647:        break;
 648:    case i2l:
 649:        state.pop(1);
 650:        state.push(syms.longType);
 651:        break;
 652:    case i2f:
 653:        state.pop(1);
 654:        state.push(syms.floatType);
 655:        break;
 656:    case i2d:
 657:        state.pop(1);
 658:        state.push(syms.doubleType);
 659:        break;
 660:    case l2f:
 661:        state.pop(2);
 662:        state.push(syms.floatType);
 663:        break;
 664:    case l2d:
 665:        state.pop(2);
 666:        state.push(syms.doubleType);
 667:        break;
 668:    case f2i:
 669:        state.pop(1);
 670:        state.push(syms.intType);
 671:        break;
 672:    case f2l:
 673:        state.pop(1);
 674:        state.push(syms.longType);
 675:        break;
 676:    case f2d:
 677:        state.pop(1);
 678:        state.push(syms.doubleType);
 679:        break;
 680:    case d2i:
 681:        state.pop(2);
 682:        state.push(syms.intType);
 683:        break;
 684:    case d2l:
 685:        state.pop(2);
 686:        state.push(syms.longType);
 687:        break;
 688:    case d2f:
 689:        state.pop(2);
 690:        state.push(syms.floatType);
 691:        break;
 692:    case tableswitch:
 693:    case lookupswitch:
 694:        state.pop(1);
 695:        // the caller is responsible for patching up the state
 696:        break;
 697:	      case dup_x1: {
 698:        Type val1 = state.pop1();
 699:        Type val2 = state.pop1();
 700:        state.push(val1);
 701:        state.push(val2);
 702:        state.push(val1);
 703:        break;
 704:    }
 705:    case bastore:
 706:        state.pop(3);
 707:        break;
 708:    case int2byte:
 709:    case int2char:
 710:    case int2short:
 711:        break;
 712:    case fmul:
 713:    case fadd:
 714:    case fsub:
 715:    case fdiv:
 716:    case fmod:
 717:        state.pop(1);
 718:        break;
 719:    case castore:
 720:    case iastore:
 721:    case fastore:
 722:    case sastore:
 723:        state.pop(3);
 724:        break;
 725:    case lastore:
 726:    case dastore:
 727:        state.pop(4);
 728:        break;
 729:    case dup2:
 730:	          if (state.stack[state.stacksize-1] != null) {
 731:        Type value1 = state.pop1();
 732:        Type value2 = state.pop1();
 733:        state.push(value2);
 734:        state.push(value1);
 735:        state.push(value2);
 736:        state.push(value1);
 737:        } else {
 738:        Type value = state.pop2();
 739:        state.push(value);
 740:        state.push(value);
 741:        }
 742:        break;
 743:    case dup2_x1:
 744:	          if (state.stack[state.stacksize-1] != null) {
 745:        Type value1 = state.pop1();
 746:        Type value2 = state.pop1();
 747:        Type value3 = state.pop1();
 748:        state.push(value2);
 749:        state.push(value1);
 750:        state.push(value3);
 751:        state.push(value2);
 752:        state.push(value1);
 753:        } else {
 754:        Type value1 = state.pop2();
 755:        Type value2 = state.pop1();
 756:        state.push(value1);
 757:        state.push(value2);
 758:        state.push(value1);
 759:        }
 760:        break;
 761:    case dup2_x2:
 762:	          if (state.stack[state.stacksize-1] != null) {
 763:        Type value1 = state.pop1();
 764:        Type value2 = state.pop1();
 765:	          if (state.stack[state.stacksize-1] != null) {
 766:            // form 1
 767:            Type value3 = state.pop1();
 768:            Type value4 = state.pop1();
 769:            state.push(value2);
 770:            state.push(value1);
 771:            state.push(value4);
 772:            state.push(value3);
 773:            state.push(value2);
 774:            state.push(value1);
 775:        } else {
 776:            // form 3
 777:            Type value3 = state.pop2();
 778:            state.push(value2);
 779:            state.push(value1);
 780:            state.push(value3);
 781:            state.push(value2);
 782:            state.push(value1);
 783:        }
 784:        } else {
 785:        Type value1 = state.pop2();
 786:	          if (state.stack[state.stacksize-1] != null) {
 787:            // form 2
 788:            Type value2 = state.pop1();
 789:            Type value3 = state.pop1();
 790:            state.push(value1);
 791:            state.push(value3);
 792:            state.push(value2);
 793:            state.push(value1);
 794:        } else {
 795:            // form 4
 796:            Type value2 = state.pop2();
 797:            state.push(value1);
 798:            state.push(value2);
 799:            state.push(value1);
 800:        }
 801:        }
 802:        break;
 803:	      case dup_x2: {
 804:        Type value1 = state.pop1();
 805:	          if (state.stack[state.stacksize-1] != null) {
 806:        // form 1
 807:        Type value2 = state.pop1();
 808:        Type value3 = state.pop1();
 809:        state.push(value1);
 810:        state.push(value3);
 811:        state.push(value2);
 812:        state.push(value1);
 813:        } else {
 814:        // form 2
 815:        Type value2 = state.pop2();
 816:        state.push(value1);
 817:        state.push(value2);
 818:        state.push(value1);
 819:        }
 820:    }
 821:        break;
 822:    case fcmpl:
 823:    case fcmpg:
 824:        state.pop(2);
 825:        state.push(syms.intType);
 826:        break;
 827:    case dcmpl:
 828:    case dcmpg:
 829:        state.pop(4);
 830:        state.push(syms.intType);
 831:        break;
 832:	      case swap: {
 833:        Type value1 = state.pop1();
 834:        Type value2 = state.pop1();
 835:        state.push(value1);
 836:        state.push(value2);
 837:        break;
 838:    }
 839:    case dadd:
 840:    case dsub:
 841:    case dmul:
 842:    case ddiv:
 843:    case dmod:
 844:        state.pop(2);
 845:        break;
 846:    case ret:
 847:        markDead();
 848:        break;
 849:    case wide:
 850:        // must be handled by the caller.
 851:        return;
 852:    case monitorenter:
 853:    case monitorexit:
 854:        state.pop(1);
 855:        break;
 856:
 857:    default:
 858:        throw new AssertionError(mnem(op));
 859:     }
 860:    postop();
 861:    }
 862:
 863:    /** Emit an opcode with a one-byte operand field.
 864:     */
 865:	      public void emitop1(int op, int od) {
 866:    emitop(op);
 867:    if (!alive) return;
 868:    emit1(od);
 869:	      switch (op) {
 870:    case bipush:
 871:        state.push(syms.intType);
 872:        break;
 873:    case ldc1:
 874:        state.push(typeForPool(pool.pool[od]));
 875:        break;
 876:    default:
 877:        throw new AssertionError(mnem(op));
 878:    }
 879:    postop();
 880:    }
 881:
 882:    /** The type of a constant pool entry. */
 883:	      private Type typeForPool(Object o) {
 884:    if (o instanceof Integer) return syms.intType;
 885:    if (o instanceof Float) return syms.floatType;
 886:    if (o instanceof String) return syms.stringType;
 887:    if (o instanceof Long) return syms.longType;
 888:    if (o instanceof Double) return syms.doubleType;
 889:    if (o instanceof ClassSymbol) return syms.classType;
 890:    if (o instanceof Type.ArrayType) return syms.classType;
 891:    throw new AssertionError(o);
 892:    }
 893:
 894:    /** Emit an opcode with a one-byte operand field;
 895:     *  widen if field does not fit in a byte.
 896:     */
 897:	      public void emitop1w(int op, int od) {
 898:	      if (od > 0xFF) {
 899:        emitop(wide);
 900:        emitop(op);
 901:        emit2(od);
 902:    } else {
 903:        emitop(op);
 904:        emit1(od);
 905:    }
 906:    if (!alive) return;
 907:	      switch (op) {
 908:    case iload:
 909:        state.push(syms.intType);
 910:        break;
 911:    case lload:
 912:        state.push(syms.longType);
 913:        break;
 914:    case fload:
 915:        state.push(syms.floatType);
 916:        break;
 917:    case dload:
 918:        state.push(syms.doubleType);
 919:        break;
 920:    case aload:
 921:        state.push(lvar[od].sym.type);
 922:        break;
 923:    case lstore:
 924:    case dstore:
 925:        state.pop(2);
 926:        break;
 927:    case istore:
 928:    case fstore:
 929:    case astore:
 930:        state.pop(1);
 931:        break;
 932:    case ret:
 933:        markDead();
 934:        break;
 935:    default:
 936:        throw new AssertionError(mnem(op));
 937:    }
 938:    postop();
 939:    }
 940:
 941:    /** Emit an opcode with two one-byte operand fields;
 942:     *  widen if either field does not fit in a byte.
 943:     */
 944:	      public void emitop1w(int op, int od1, int od2) {
 945:	      if (od1 > 0xFF || od2 < -128 || od2 > 127) {
 946:        emitop(wide);
 947:        emitop(op);
 948:        emit2(od1);
 949:        emit2(od2);
 950:    } else {
 951:        emitop(op);
 952:        emit1(od1);
 953:        emit1(od2);
 954:    }
 955:    if (!alive) return;
 956:	      switch (op) {
 957:    case iinc:
 958:        break;
 959:    default:
 960:        throw new AssertionError(mnem(op));
 961:    }
 962:    }
 963:
 964:    /** Emit an opcode with a two-byte operand field.
 965:     */
 966:	      public void emitop2(int op, int od) {
 967:        emitop(op);
 968:    if (!alive) return;
 969:    emit2(od);
 970:	      switch (op) {
 971:    case getstatic:
 972:        state.push(((Symbol)(pool.pool[od])).erasure(types));
 973:        break;
 974:    case putstatic:
 975:        state.pop(((Symbol)(pool.pool[od])).erasure(types));
 976:        break;
 977:    case new_:
 978:        state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
 979:        break;
 980:    case sipush:
 981:        state.push(syms.intType);
 982:        break;
 983:    case if_acmp_null:
 984:    case if_acmp_nonnull:
 985:    case ifeq:
 986:    case ifne:
 987:    case iflt:
 988:    case ifge:
 989:    case ifgt:
 990:    case ifle:
 991:        state.pop(1);
 992:        break;
 993:    case if_icmpeq:
 994:    case if_icmpne:
 995:    case if_icmplt:
 996:    case if_icmpge:
 997:    case if_icmpgt:
 998:    case if_icmple:
 999:    case if_acmpeq:
1000:    case if_acmpne:
1001:        state.pop(2);
1002:        break;
1003:    case goto_:
1004:        markDead();
1005:        break;
1006:    case putfield:
1007:        state.pop(((Symbol)(pool.pool[od])).erasure(types));
1008:        state.pop(1); // object ref
1009:        break;
1010:    case getfield:
1011:        state.pop(1); // object ref
1012:        state.push(((Symbol)(pool.pool[od])).erasure(types));
1013:        break;
1014:	      case checkcast: {
1015:        state.pop(1); // object ref
1016:        Object o = pool.pool[od];
1017:        Type t = (o instanceof Symbol)
1018:        ? ((Symbol)o).erasure(types)
1019:        : types.erasure(((Type)o));
1020:        state.push(t);
1021:        break; }
1022:    case ldc2w:
1023:        state.push(typeForPool(pool.pool[od]));
1024:        break;
1025:    case instanceof_:
1026:        state.pop(1);
1027:        state.push(syms.intType);
1028:        break;
1029:    case ldc2:
1030:        state.push(typeForPool(pool.pool[od]));
1031:        break;
1032:    case jsr:
1033:        break;
1034:    default:
1035:        throw new AssertionError(mnem(op));
1036:    }
1037:    // postop();
1038:    }
1039:
1040:    /** Emit an opcode with a four-byte operand field.
1041:     */
1042:	      public void emitop4(int op, int od) {
1043:        emitop(op);
1044:    if (!alive) return;
1045:    emit4(od);
1046:	      switch (op) {
1047:    case goto_w:
1048:        markDead();
1049:        break;
1050:    case jsr_w:
1051:        break;
1052:    default:
1053:        throw new AssertionError(mnem(op));
1054:    }
1055:    // postop();
1056:    }
1057:
1058:    /** Align code pointer to next `incr' boundary.
1059:     */
1060:	      public void align(int incr) {
1061:        if (alive)
1062:            while (cp % incr != 0) emitop0(nop);
1063:    }
1064:
1065:    /** Place a byte into code at address pc. Pre: pc + 1 <= cp.
1066:     */
1067:	      private void put1(int pc, int op) {
1068:        code[pc] = (byte)op;
1069:    }
1070:
1071:    /** Place two bytes into code at address pc. Pre: pc + 2 <= cp.
1072:     */
1073:	      private void put2(int pc, int od) {
1074:        // pre: pc + 2 <= cp
1075:        put1(pc, od >> 8);
1076:        put1(pc+1, od);
1077:    }
1078:
1079:    /** Place four  bytes into code at address pc. Pre: pc + 4 <= cp.
1080:     */
1081:	      public void put4(int pc, int od) {
1082:        // pre: pc + 4 <= cp
1083:        put1(pc  , od >> 24);
1084:        put1(pc+1, od >> 16);
1085:        put1(pc+2, od >> 8);
1086:        put1(pc+3, od);
1087:    }
1088:
1089:    /** Return code byte at position pc as an unsigned int.
1090:     */
1091:	      private int get1(int pc) {
1092:        return code[pc] & 0xFF;
1093:    }
1094:
1095:    /** Return two code bytes at position pc as an unsigned int.
1096:     */
1097:	      private int get2(int pc) {
1098:        return (get1(pc) << 8) | get1(pc+1);
1099:    }
1100:
1101:    /** Return four code bytes at position pc as an int.
1102:     */
1103:	      public int get4(int pc) {
1104:        // pre: pc + 4 <= cp
1105:        return
1106:            (get1(pc) << 24) |
1107:            (get1(pc+1) << 16) |
1108:            (get1(pc+2) << 8) |
1109:            (get1(pc+3));
1110:    }
1111:
1112:    /** Is code generation currently enabled?
1113:     */
1114:	      public boolean isAlive() {
1115:    return alive || pendingJumps != null;
1116:    }
1117:
1118:    /** Switch code generation on/off.
1119:     */
1120:	      public void markDead() {
1121:    alive = false;
1122:    }
1123:
1124:    /** Declare an entry point; return current code pointer
1125:     */
1126:	      public int entryPoint() {
1127:    int pc = curPc();
1128:    alive = true;
1129:    pendingStackMap = needStackMap;
1130:    return pc;
1131:    }
1132:
1133:    /** Declare an entry point with initial state;
1134:     *  return current code pointer
1135:     */
1136:	      public int entryPoint(State state) {
1137:    int pc = curPc();
1138:    alive = true;
1139:    this.state = state.dup();
1140:    assert state.stacksize <= max_stack;
1141:    if (debugCode) System.err.println("entry point " + state);
1142:    pendingStackMap = needStackMap;
1143:    return pc;
1144:    }
1145:
1146:    /** Declare an entry point with initial state plus a pushed value;
1147:     *  return current code pointer
1148:     */
1149:	      public int entryPoint(State state, Type pushed) {
1150:    int pc = curPc();
1151:    alive = true;
1152:    this.state = state.dup();
1153:    assert state.stacksize <= max_stack;
1154:    this.state.push(pushed);
1155:    if (debugCode) System.err.println("entry point " + state);
1156:    pendingStackMap = needStackMap;
1157:    return pc;
1158:    }
1159:
1160:
1161:/**************************************************************************
1162: * Stack map generation
1163: *************************************************************************/
1164:
1165:    /** An entry in the stack map. */
1166:	      static class StackMapFrame {
1167:    int pc;
1168:    Type[] locals;
1169:    Type[] stack;
1170:    }
1171:
1172:    /** A buffer of cldc stack map entries. */
1173:    StackMapFrame[] stackMapBuffer = null;
1174:    
1175:    /** A buffer of compressed StackMapTable entries. */
1176:    StackMapTableFrame[] stackMapTableBuffer = null;
1177:    int stackMapBufferSize = 0;
1178:
1179:    /** The last PC at which we generated a stack map. */
1180:    int lastStackMapPC = -1;
1181:    
1182:    /** The last stack map frame in StackMapTable. */
1183:    StackMapFrame lastFrame = null;
1184:    
1185:    /** The stack map frame before the last one. */
1186:    StackMapFrame frameBeforeLast = null;
1187:
1188:    /** Emit a stack map entry.  */
1189:	      public void emitStackMap() {
1190:    int pc = curPc();
1191:    if (!needStackMap) return;
1192:        
1193:
1194: 
1195:	          switch (stackMap) {
1196:            case CLDC:
1197:                emitCLDCStackMap(pc, getLocalsSize());
1198:                break;
1199:            case JSR202:
1200:                emitStackMapFrame(pc, getLocalsSize());
1201:                break;
1202:            default:
1203:                throw new AssertionError("Should have chosen a stackmap format");
1204:    }
1205:    // DEBUG code follows
1206:    if (debugCode) state.dump(pc);
1207:    }
1208:    
1209:	      private int getLocalsSize() {
1210:        int nextLocal = 0;
1211:	      for (int i=max_locals-1; i>=0; i--) {
1212:	          if (state.defined.isMember(i) && lvar[i] != null) {
1213:        nextLocal = i + width(lvar[i].sym.erasure(types));
1214:        break;
1215:        }
1216:    }
1217:        return nextLocal;
1218:    }
1219:    
1220:    /** Emit a CLDC stack map frame. */
1221:	      void emitCLDCStackMap(int pc, int localsSize) {
1222:	      if (lastStackMapPC == pc) {
1223:        // drop existing stackmap at this offset
1224:        stackMapBuffer[--stackMapBufferSize] = null;
1225:    }
1226:    lastStackMapPC = pc;
1227:
1228:	      if (stackMapBuffer == null) {
1229:        stackMapBuffer = new StackMapFrame[20];
1230:    } else if (stackMapBuffer.length == stackMapBufferSize) {
1231:        StackMapFrame[] newStackMapBuffer =
1232:        new StackMapFrame[stackMapBufferSize << 1];
1233:        System.arraycopy(stackMapBuffer, 0, newStackMapBuffer,
1234:                 0, stackMapBufferSize);
1235:        stackMapBuffer = newStackMapBuffer;
1236:    }
1237:    StackMapFrame frame =
1238:        stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
1239:    frame.pc = pc;
1240:        
1241:    frame.locals = new Type[localsSize];
1242:	      for (int i=0; i<localsSize; i++) {
1243:	              if (state.defined.isMember(i) && lvar[i] != null) {
1244:                Type vtype = lvar[i].sym.type;
1245:        if (!(vtype instanceof UninitializedType))
1246:                    vtype = types.erasure(vtype);
1247:        frame.locals[i] = vtype;
1248:        }
1249:    }
1250:    frame.stack = new Type[state.stacksize];
1251:    for (int i=0; i<state.stacksize; i++)
1252:        frame.stack[i] = state.stack[i];
1253:    }
1254:    
1255:	      void emitStackMapFrame(int pc, int localsSize) {
1256:	          if (lastFrame == null) {
1257:            // first frame
1258:            lastFrame = getInitialFrame();
1259:        } else if (lastFrame.pc == pc) {
1260:        // drop existing stackmap at this offset
1261:        stackMapTableBuffer[--stackMapBufferSize] = null;
1262:            lastFrame = frameBeforeLast;
1263:            frameBeforeLast = null;
1264:    }
1265:        
1266:        StackMapFrame frame = new StackMapFrame();
1267:        frame.pc = pc;
1268:  
1269:    int localCount = 0;
1270:    Type[] locals = new Type[localsSize];
1271:	          for (int i=0; i<localsSize; i++, localCount++) {
1272:	              if (state.defined.isMember(i) && lvar[i] != null) {
1273:                Type vtype = lvar[i].sym.type;
1274:        if (!(vtype instanceof UninitializedType))
1275:                    vtype = types.erasure(vtype);
1276:        locals[i] = vtype;
1277:        if (width(vtype) > 1) i++;
1278:            }
1279:    }
1280:    frame.locals = new Type[localCount];
1281:	      for (int i=0, j=0; i<localsSize; i++, j++) {
1282:            assert(j < localCount);
1283:        frame.locals[j] = locals[i];
1284:            if (width(locals[i]) > 1) i++;
1285:    }
1286:
1287:    int stackCount = 0;
1288:	      for (int i=0; i<state.stacksize; i++) {
1289:	              if (state.stack[i] != null) {
1290:                stackCount++;
1291:        }
1292:    }
1293:    frame.stack = new Type[stackCount];
1294:    stackCount = 0;
1295:	      for (int i=0; i<state.stacksize; i++) {
1296:	              if (state.stack[i] != null) {
1297:                frame.stack[stackCount++] = state.stack[i];
1298:        }
1299:    }    
1300:            
1301:	          if (stackMapTableBuffer == null) {
1302:        stackMapTableBuffer = new StackMapTableFrame[20];
1303:    } else if (stackMapTableBuffer.length == stackMapBufferSize) {
1304:        StackMapTableFrame[] newStackMapTableBuffer =
1305:        new StackMapTableFrame[stackMapBufferSize << 1];
1306:        System.arraycopy(stackMapTableBuffer, 0, newStackMapTableBuffer,
1307:                 0, stackMapBufferSize);
1308:        stackMapTableBuffer = newStackMapTableBuffer;
1309:    }
1310:    stackMapTableBuffer[stackMapBufferSize++] = 
1311:                StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
1312:               
1313:        frameBeforeLast = lastFrame;
1314:        lastFrame = frame;
1315:    }
1316:    
1317:	      StackMapFrame getInitialFrame() {
1318:        StackMapFrame frame = new StackMapFrame();
1319:        List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
1320:        int len = arg_types.length();
1321:        int count = 0;
1322:	          if (!meth.isStatic()) {
1323:            Type thisType = meth.owner.type;
1324:            frame.locals = new Type[len+1];
1325:	              if (meth.isConstructor() && thisType != syms.objectType) {
1326:                frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
1327:            } else {
1328:                frame.locals[count++] = types.erasure(thisType);
1329:            }
1330:        } else {
1331:            frame.locals = new Type[len];
1332:        }
1333:	          for (Type arg_type : arg_types) {
1334:            frame.locals[count++] = types.erasure(arg_type);
1335:        }
1336:        frame.pc = -1;
1337:        frame.stack = null;
1338:        return frame;
1339:    }
1340:    
1341:    
1342:/**************************************************************************
1343: * Operations having to do with jumps
1344: *************************************************************************/
1345:
1346:    /** A chain represents a list of unresolved jumps. Jump locations
1347:     *  are sorted in decreasing order.
1348:     */
1349:	      public static class Chain {
1350:
1351:    /** The position of the jump instruction.
1352:     */
1353:    public final int pc;
1354:
1355:        /** The machine state after the jump instruction.
1356:     *  Invariant: all elements of a chain list have the same stacksize
1357:     *  and compatible stack and register contents.
1358:     */
1359:    Code.State state;
1360:
1361:    /** The next jump in the list.
1362:     */
1363:    public final Chain next;
1364:
1365:    /** Construct a chain from its jump position, stacksize, previous
1366:     *  chain, and machine state.
1367:     */
1368:	      public Chain(int pc, Chain next, Code.State state) {
1369:        this.pc = pc;
1370:        this.next = next;
1371:        this.state = state;
1372:    }
1373:    }
1374:
1375:    /** Negate a branch opcode.
1376:     */
1377:	      public static int negate(int opcode) {
1378:    if (opcode == if_acmp_null) return if_acmp_nonnull;
1379:    else if (opcode == if_acmp_nonnull) return if_acmp_null;
1380:    else return ((opcode + 1) ^ 1) - 1;
1381:    }
1382:
1383:    /** Emit a jump instruction.
1384:     *  Return code pointer of instruction to be patched.
1385:     */
1386:	      public int emitJump(int opcode) {
1387:	      if (fatcode) {
1388:	          if (opcode == goto_ || opcode == jsr) {
1389:        emitop4(opcode + goto_w - goto_, 0);
1390:        } else {
1391:        emitop2(negate(opcode), 8);
1392:        emitop4(goto_w, 0);
1393:        alive = true;
1394:        pendingStackMap = needStackMap;
1395:        }
1396:        return cp - 5;
1397:    } else {
1398:        emitop2(opcode, 0);
1399:        return cp - 3;
1400:    }
1401:    }
1402:
1403:    /** Emit a branch with given opcode; return its chain.
1404:     *  branch differs from jump in that jsr is treated as no-op.
1405:     */
1406:	      public Chain branch(int opcode) {
1407:    Chain result = null;
1408:	      if (opcode == goto_) {
1409:        result = pendingJumps;
1410:        pendingJumps = null;
1411:    }
1412:	          if (opcode != dontgoto && isAlive()) {
1413:        result = new Chain(emitJump(opcode),
1414:                   result,
1415:                   state.dup());
1416:        fixedPc = fatcode;
1417:        if (opcode == goto_) alive = false;
1418:    }
1419:    return result;
1420:    }
1421:
1422:    /** Resolve chain to point to given target.
1423:     */
1424:	      public void resolve(Chain chain, int target) {
1425:    boolean changed = false;
1426:    State newState = state;
1427:	      for (; chain != null; chain = chain.next) {
1428:        assert state != chain.state;
1429:            assert target > chain.pc || state.stacksize == 0;
1430:	              if (target >= cp) {
1431:        target = cp;
1432:        } else if (get1(target) == goto_) {
1433:        if (fatcode) target = target + get4(target + 1);
1434:        else target = target + get2(target + 1);
1435:        }
1436:        if (get1(chain.pc) == goto_ &&
1437:	                  chain.pc + 3 == target && target == cp && !fixedPc) {
1438:                // If goto the next instruction, the jump is not needed: 
1439:                // compact the code.
1440:                cp = cp - 3;
1441:                target = target - 3;
1442:	                  if (chain.next == null) {
1443:                    // This is the only jump to the target. Exit the loop 
1444:                    // without setting new state. The code is reachable 
1445:                    // from the instruction before goto_.
1446:                    alive = true;
1447:                    break;
1448:                }
1449:            } else {
1450:        if (fatcode)
1451:            put4(chain.pc + 1, target - chain.pc);
1452:        else if (target - chain.pc < Short.MIN_VALUE ||
1453:             target - chain.pc > Short.MAX_VALUE)
1454:            fatcode = true;
1455:                else
1456:                    put2(chain.pc + 1, target - chain.pc);
1457:        assert !alive ||
1458:            chain.state.stacksize == newState.stacksize &&
1459:            chain.state.nlocks == newState.nlocks;
1460:            }
1461:            fixedPc = true;
1462:	              if (cp == target) {
1463:        changed = true;
1464:        if (debugCode)
1465:            System.err.println("resolving chain state=" + chain.state);
1466:	          if (alive) {
1467:            newState = chain.state.join(newState);
1468:        } else {
1469:            newState = chain.state;
1470:            alive = true;
1471:        }
1472:            }
1473:    }
1474:    assert !changed || state != newState;
1475:	      if (state != newState) {
1476:        setDefined(newState.defined);
1477:        state = newState;
1478:        pendingStackMap = needStackMap;
1479:    }
1480:    }
1481:
1482:    /** Resolve chain to point to current code pointer.
1483:     */
1484:	      public void resolve(Chain chain) {
1485:    assert
1486:        !alive ||
1487:        chain==null ||
1488:        state.stacksize == chain.state.stacksize &&
1489:        state.nlocks == chain.state.nlocks;
1490:    pendingJumps = mergeChains(chain, pendingJumps);
1491:    }
1492:
1493:    /** Resolve any pending jumps.
1494:     */
1495:	      public void resolvePending() {
1496:    Chain x = pendingJumps;
1497:    pendingJumps = null;
1498:    resolve(x, cp);
1499:    }
1500:
1501:    /** Merge the jumps in of two chains into one.
1502:     */
1503:	      public static Chain mergeChains(Chain chain1, Chain chain2) {
1504:    // recursive merge sort
1505:        if (chain2 == null) return chain1;
1506:        if (chain1 == null) return chain2;
1507:    assert
1508:        chain1.state.stacksize == chain2.state.stacksize &&
1509:        chain1.state.nlocks == chain2.state.nlocks;
1510:        if (chain1.pc < chain2.pc)
1511:        return new Chain(
1512:        chain2.pc,
1513:        mergeChains(chain1, chain2.next),
1514:        chain2.state);
1515:    return new Chain(
1516:        chain1.pc,
1517:        mergeChains(chain1.next, chain2),
1518:        chain1.state);
1519:    }
1520:
1521:
1522:/* **************************************************************************
1523: * Catch clauses
1524: ****************************************************************************/
1525:
1526:    /** Add a catch clause to code.
1527:     */
1528:    public void addCatch(
1529:	      char startPc, char endPc, char handlerPc, char catchType) {
1530:    catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
1531:    }
1532:
1533:
1534:/* **************************************************************************
1535: * Line numbers
1536: ****************************************************************************/
1537:
1538:    /** Add a line number entry.
1539:     */
1540:	      public void addLineNumber(char startPc, char lineNumber) {
1541:	      if (lineDebugInfo) {
1542:        if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
1543:        lineInfo = lineInfo.tail;
1544:        if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
1545:        lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
1546:    }
1547:    }
1548:
1549:    /** Mark beginning of statement.
1550:     */
1551:	      public void statBegin(int pos) {
1552:	      if (pos != Position.NOPOS) {
1553:        pendingStatPos = pos;
1554:    }
1555:    }
1556:
1557:    /** Force stat begin eagerly
1558:     */
1559:	      public void markStatBegin() {
1560:	      if (alive && lineDebugInfo) {
1561:        int line = lineMap.getLineNumber(pendingStatPos);
1562:        char cp1 = (char)cp;
1563:        char line1 = (char)line;
1564:        if (cp1 == cp && line1 == line)
1565:        addLineNumber(cp1, line1);
1566:    }
1567:    pendingStatPos = Position.NOPOS;
1568:    }
1569:
1570:
1571:/* **************************************************************************
1572: * Simulated VM machine state
1573: ****************************************************************************/
1574:
1575:	      class State implements Cloneable {
1576:    /** The set of registers containing values. */
1577:    Bits defined;
1578:
1579:    /** The (types of the) contents of the machine stack. */
1580:    Type[] stack;
1581:
1582:    /** The first stack position currently unused. */
1583:    int stacksize;
1584:
1585:    /** The numbers of registers containing locked monitors. */
1586:    int[] locks;
1587:    int nlocks;
1588:
1589:	      State() {
1590:        defined = new Bits();
1591:        stack = new Type[16];
1592:    }
1593:
1594:	      State dup() {
1595:	          try {
1596:        State state = (State)super.clone();
1597:        state.defined = defined.dup();
1598:        state.stack = stack.clone();
1599:        if (locks != null) state.locks = locks.clone();
1600:	          if (debugCode) {
1601:            System.err.println("duping state " + this);
1602:            dump();
1603:        }
1604:        return state;
1605:        } catch (CloneNotSupportedException ex) {
1606:        throw new AssertionError(ex);
1607:        }
1608:    }
1609:
1610:	      void lock(int register) {
1611:	          if (locks == null) {
1612:        locks = new int[20];
1613:        } else if (locks.length == nlocks) {
1614:        int[] newLocks = new int[locks.length << 1];
1615:        System.arraycopy(locks, 0, newLocks, 0, locks.length);
1616:        locks = newLocks;
1617:        }
1618:        locks[nlocks] = register;
1619:        nlocks++;
1620:    }
1621:
1622:	      void unlock(int register) {
1623:        nlocks--;
1624:        assert locks[nlocks] == register;
1625:        locks[nlocks] = -1;
1626:    }
1627:
1628:	      void push(Type t) {
1629:        if (debugCode) System.err.println("   pushing " + t);
1630:	          switch (t.tag) {
1631:        case TypeTags.VOID:
1632:        return;
1633:        case TypeTags.BYTE:
1634:        case TypeTags.CHAR:
1635:        case TypeTags.SHORT:
1636:        case TypeTags.BOOLEAN:
1637:        t = syms.intType;
1638:        break;
1639:        default:
1640:        break;
1641:        }
1642:	          if (stacksize+2 >= stack.length) {
1643:        Type[] newstack = new Type[2*stack.length];
1644:        System.arraycopy(stack, 0, newstack, 0, stack.length);
1645:        stack = newstack;
1646:        }
1647:        stack[stacksize++] = t;
1648:	          switch (width(t)) {
1649:        case 1:
1650:        break;
1651:        case 2:
1652:        stack[stacksize++] = null;
1653:        break;
1654:        default:
1655:        throw new AssertionError(t);
1656:        }
1657:        if (stacksize > max_stack)
1658:        max_stack = stacksize;
1659:    }
1660:
1661:	      Type pop1() {
1662:        if (debugCode) System.err.println("   popping " + 1);
1663:        stacksize--;
1664:        Type result = stack[stacksize];
1665:        stack[stacksize] = null;
1666:        assert result != null && width(result) == 1;
1667:        return result;
1668:    }
1669:
1670:	      Type peek() {
1671:        return stack[stacksize-1];
1672:    }
1673:
1674:	      Type pop2() {
1675:        if (debugCode) System.err.println("   popping " + 2);
1676:        stacksize -= 2;
1677:        Type result = stack[stacksize];
1678:        stack[stacksize] = null;
1679:        assert stack[stacksize+1] == null;
1680:        assert result != null && width(result) == 2;
1681:        return result;
1682:    }
1683:
1684:	      void pop(int n) {
1685:        if (debugCode) System.err.println("   popping " + n);
1686:	          while (n > 0) {
1687:        stack[--stacksize] = null;
1688:        n--;
1689:        }
1690:    }
1691:
1692:	      void pop(Type t) {
1693:        pop(width(t));
1694:    }
1695:
1696:    /** Force the top of the stack to be treated as this supertype
1697:     *  of its current type. */
1698:	      void forceStackTop(Type t) {
1699:            if (!alive) return;
1700:	          switch (t.tag) {
1701:        case CLASS:
1702:        case ARRAY:
1703:        int width = width(t);
1704:        Type old = stack[stacksize-width];
1705:        assert types.isSubtype(types.erasure(old),
1706:                       types.erasure(t));
1707:        stack[stacksize-width] = t;
1708:        break;
1709:        default:
1710:        }
1711:    }
1712:
1713:	      void markInitialized(UninitializedType old) {
1714:        Type newtype = old.initializedType();
1715:        for (int i=0; i<stacksize; i++)
1716:        if (stack[i] == old) stack[i] = newtype;
1717:	          for (int i=0; i<lvar.length; i++) {
1718:        LocalVar lv = lvar[i];
1719:	          if (lv != null && lv.sym.type == old) {
1720:            VarSymbol sym = lv.sym;
1721:            sym = sym.clone(sym.owner);
1722:            sym.type = newtype;
1723:            LocalVar newlv = lvar[i] = new LocalVar(sym);
1724:            // should the following be initialized to cp?
1725:            newlv.start_pc = lv.start_pc;
1726:        }
1727:        }
1728:    }
1729:
1730:	      State join(State other) {
1731:        defined = defined.andSet(other.defined);
1732:        assert stacksize == other.stacksize;
1733:        assert nlocks == other.nlocks;
1734:	          for (int i=0; i<stacksize; ) {
1735:        Type t = stack[i];
1736:        Type tother = other.stack[i];
1737:        Type result =
1738:            t==tother ? t :
1739:            types.isSubtype(t, tother) ? tother :
1740:            types.isSubtype(tother, t) ? t :
1741:            error();
1742:        int w = width(result);
1743:        stack[i] = result;
1744:        if (w == 2) assert stack[i+1] == null;
1745:        i += w;
1746:        }
1747:        return this;
1748:    }
1749:
1750:	      Type error() {
1751:        throw new AssertionError("inconsistent stack types at join point");
1752:    }
1753:
1754:	      void dump() {
1755:        dump(-1);
1756:    }
1757:
1758:	      void dump(int pc) {
1759:        System.err.print("stackMap for " + meth.owner + "." + meth);
1760:        if (pc == -1)
1761:        System.out.println();
1762:        else
1763:        System.out.println(" at " + pc);
1764:        System.err.println(" stack (from bottom):");
1765:        for (int i=0; i<stacksize; i++)
1766:        System.err.println("  " + i + ": " + stack[i]);
1767:
1768:        int lastLocal = 0;
1769:	          for (int i=max_locals-1; i>=0; i--) {
1770:	          if (defined.isMember(i)) {
1771:            lastLocal = i;
1772:            break;
1773:        }
1774:        }
1775:        if (lastLocal >= 0)
1776:        System.err.println(" locals:");
1777:	          for (int i=0; i<=lastLocal; i++) {
1778:        System.err.print("  " + i + ": ");
1779:	          if (defined.isMember(i)) {
1780:            LocalVar var = lvar[i];
1781:	              if (var == null) {
1782:            System.err.println("(none)");
1783:            } else if (var.sym == null)
1784:            System.err.println("UNKNOWN!");
1785:            else
1786:            System.err.println("" + var.sym + " of type " +
1787:                       var.sym.erasure(types));
1788:        } else {
1789:            System.err.println("undefined");
1790:        }
1791:        }
1792:	          if (nlocks != 0) {
1793:        System.err.print(" locks:");
1794:	          for (int i=0; i<nlocks; i++) {
1795:            System.err.print(" " + locks[i]);
1796:        }
1797:        System.err.println();
1798:        }
1799:    }
1800:    }
1801:
1802:    static Type jsrReturnValue = new Type(TypeTags.INT, null);
1803:
1804:
1805:/* **************************************************************************
1806: * Local variables
1807: ****************************************************************************/
1808:
1809:    /** A live range of a local variable. */
1810:	      static class LocalVar {
1811:    final VarSymbol sym;
1812:    final char reg;
1813:    char start_pc = Character.MAX_VALUE;
1814:    char length = Character.MAX_VALUE;
1815:	      LocalVar(VarSymbol v) {
1816:        this.sym = v;
1817:        this.reg = (char)v.adr;
1818:    }
1819:	      public LocalVar dup() {
1820:        return new LocalVar(sym);
1821:    }
1822:	      public String toString() {
1823:        return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length);
1824:    }
1825:    };
1826:
1827:    /** Local variables, indexed by register. */
1828:    LocalVar[] lvar;
1829:
1830:    /** Add a new local variable. */
1831:	      private void addLocalVar(VarSymbol v) {
1832:    int adr = v.adr;
1833:	      if (adr+1 >= lvar.length) {
1834:        int newlength = lvar.length << 1;
1835:        if (newlength <= adr) newlength = adr + 10;
1836:        LocalVar[] new_lvar = new LocalVar[newlength];
1837:        System.arraycopy(lvar, 0, new_lvar, 0, lvar.length);
1838:        lvar = new_lvar;
1839:    }
1840:    assert lvar[adr] == null;
1841:    if (pendingJumps != null) resolvePending();
1842:    lvar[adr] = new LocalVar(v);
1843:    state.defined.excl(adr);
1844:    }
1845:
1846:    /** Set the current variable defined state. */
1847:	      public void setDefined(Bits newDefined) {
1848:	      if (alive && newDefined != state.defined) {
1849:        Bits diff = state.defined.dup().xorSet(newDefined);
1850:        for (int adr = diff.nextBit(0);
1851:         adr >= 0;
1852:	           adr = diff.nextBit(adr+1)) {
1853:        if (adr >= nextreg)
1854:            state.defined.excl(adr);
1855:        else if (state.defined.isMember(adr))
1856:            setUndefined(adr);
1857:        else
1858:            setDefined(adr);
1859:        }
1860:    }
1861:    }
1862:
1863:    /** Mark a register as being (possibly) defined. */
1864:	      public void setDefined(int adr) {
1865:    LocalVar v = lvar[adr];
1866:	      if (v == null) {
1867:        state.defined.excl(adr);
1868:    } else {
1869:        state.defined.incl(adr);
1870:	          if (cp < Character.MAX_VALUE) {
1871:        if (v.start_pc == Character.MAX_VALUE)
1872:            v.start_pc = (char)cp;
1873:        }
1874:    }
1875:    }
1876:
1877:    /** Mark a register as being undefined. */
1878:	      public void setUndefined(int adr) {
1879:    state.defined.excl(adr);
1880:    if (adr < lvar.length &&
1881:        lvar[adr] != null &&
1882:	          lvar[adr].start_pc != Character.MAX_VALUE) {
1883:        LocalVar v = lvar[adr];
1884:        char length = (char)(curPc() - v.start_pc);
1885:	          if (length > 0 && length < Character.MAX_VALUE) {
1886:        lvar[adr] = v.dup();
1887:        v.length = length;
1888:        putVar(v);
1889:        } else {
1890:        v.start_pc = Character.MAX_VALUE;
1891:        }
1892:    }
1893:    }
1894:
1895:    /** End the scope of a variable. */
1896:	      private void endScope(int adr) {
1897:    LocalVar v = lvar[adr];
1898:	      if (v != null) {
1899:        lvar[adr] = null;
1900:	          if (v.start_pc != Character.MAX_VALUE) {
1901:        char length = (char)(curPc() - v.start_pc);
1902:	          if (length < Character.MAX_VALUE) {
1903:            v.length = length;
1904:            putVar(v);
1905:        }
1906:        }
1907:    }
1908:    state.defined.excl(adr);
1909:    }
1910:
1911:    /** Put a live variable range into the buffer to be output to the
1912:     *  class file.
1913:     */
1914:	      void putVar(LocalVar var) {
1915:    if (!varDebugInfo) return;
1916:    if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
1917:    if (varBuffer == null)
1918:        varBuffer = new LocalVar[20];
1919:	      else if (varBufferSize >= varBuffer.length) {
1920:        LocalVar[] newVarBuffer = new LocalVar[varBufferSize*2];
1921:        System.arraycopy(varBuffer, 0, newVarBuffer, 0, varBuffer.length);
1922:        varBuffer = newVarBuffer;
1923:    }
1924:    varBuffer[varBufferSize++] = var;
1925:    }
1926:
1927:    /** Previously live local variables, to be put into the variable table. */
1928:    LocalVar[] varBuffer;
1929:    int varBufferSize;
1930:
1931:    /** Create a new local variable address and return it.
1932:     */
1933:	      private int newLocal(int typecode) {
1934:    int reg = nextreg;
1935:    int w = width(typecode);
1936:    nextreg = reg + w;
1937:    if (nextreg > max_locals) max_locals = nextreg;
1938:    return reg;
1939:    }
1940:
1941:	      private int newLocal(Type type) {
1942:    return newLocal(typecode(type));
1943:    }
1944:
1945:	      public int newLocal(VarSymbol v) {
1946:    int reg = v.adr = newLocal(v.erasure(types));
1947:    addLocalVar(v);
1948:    return reg;
1949:    }
1950:
1951:    /** Start a set of fresh registers.
1952:     */
1953:	      public void newRegSegment() {
1954:    nextreg = max_locals;
1955:    }
1956:
1957:    /** End scopes of all variables with registers >= first.
1958:     */
1959:	      public void endScopes(int first) {
1960:    int prevNextReg = nextreg;
1961:    nextreg = first;
1962:    for (int i = nextreg; i < prevNextReg; i++) endScope(i);
1963:    }
1964:
1965:/**************************************************************************
1966: * static tables
1967: *************************************************************************/
1968:
1969:	      public static String mnem(int opcode) {
1970:    return Mneumonics.mnem[opcode];
1971:    }
1972:
1973:	      private static class Mneumonics {
1974:    private final static String[] mnem = new String[ByteCodeCount];
1975:	      static {
1976:        mnem[nop] = "nop";
1977:        mnem[aconst_null] = "aconst_null";
1978:        mnem[iconst_m1] = "iconst_m1";
1979:        mnem[iconst_0] = "iconst_0";
1980:        mnem[iconst_1] = "iconst_1";
1981:        mnem[iconst_2] = "iconst_2";
1982:        mnem[iconst_3] = "iconst_3";
1983:        mnem[iconst_4] = "iconst_4";
1984:        mnem[iconst_5] = "iconst_5";
1985:        mnem[lconst_0] = "lconst_0";
1986:        mnem[lconst_1] = "lconst_1";
1987:        mnem[fconst_0] = "fconst_0";
1988:        mnem[fconst_1] = "fconst_1";
1989:        mnem[fconst_2] = "fconst_2";
1990:        mnem[dconst_0] = "dconst_0";
1991:        mnem[dconst_1] = "dconst_1";
1992:        mnem[bipush] = "bipush";
1993:        mnem[sipush] = "sipush";
1994:        mnem[ldc1] = "ldc1";
1995:        mnem[ldc2] = "ldc2";
1996:        mnem[ldc2w] = "ldc2w";
1997:        mnem[iload] = "iload";
1998:        mnem[lload] = "lload";
1999:        mnem[fload] = "fload";
2000:        mnem[dload] = "dload";
2001:        mnem[aload] = "aload";
2002:        mnem[iload_0] = "iload_0";
2003:        mnem[lload_0] = "lload_0";
2004:        mnem[fload_0] = "fload_0";
2005:        mnem[dload_0] = "dload_0";
2006:        mnem[aload_0] = "aload_0";
2007:        mnem[iload_1] = "iload_1";
2008:        mnem[lload_1] = "lload_1";
2009:        mnem[fload_1] = "fload_1";
2010:        mnem[dload_1] = "dload_1";
2011:        mnem[aload_1] = "aload_1";
2012:        mnem[iload_2] = "iload_2";
2013:        mnem[lload_2] = "lload_2";
2014:        mnem[fload_2] = "fload_2";
2015:        mnem[dload_2] = "dload_2";
2016:        mnem[aload_2] = "aload_2";
2017:        mnem[iload_3] = "iload_3";
2018:        mnem[lload_3] = "lload_3";
2019:        mnem[fload_3] = "fload_3";
2020:        mnem[dload_3] = "dload_3";
2021:        mnem[aload_3] = "aload_3";
2022:        mnem[iaload] = "iaload";
2023:        mnem[laload] = "laload";
2024:        mnem[faload] = "faload";
2025:        mnem[daload] = "daload";
2026:        mnem[aaload] = "aaload";
2027:        mnem[baload] = "baload";
2028:        mnem[caload] = "caload";
2029:        mnem[saload] = "saload";
2030:        mnem[istore] = "istore";
2031:        mnem[lstore] = "lstore";
2032:        mnem[fstore] = "fstore";
2033:        mnem[dstore] = "dstore";
2034:        mnem[astore] = "astore";
2035:        mnem[istore_0] = "istore_0";
2036:        mnem[lstore_0] = "lstore_0";
2037:        mnem[fstore_0] = "fstore_0";
2038:        mnem[dstore_0] = "dstore_0";
2039:        mnem[astore_0] = "astore_0";
2040:        mnem[istore_1] = "istore_1";
2041:        mnem[lstore_1] = "lstore_1";
2042:        mnem[fstore_1] = "fstore_1";
2043:        mnem[dstore_1] = "dstore_1";
2044:        mnem[astore_1] = "astore_1";
2045:        mnem[istore_2] = "istore_2";
2046:        mnem[lstore_2] = "lstore_2";
2047:        mnem[fstore_2] = "fstore_2";
2048:        mnem[dstore_2] = "dstore_2";
2049:        mnem[astore_2] = "astore_2";
2050:        mnem[istore_3] = "istore_3";
2051:        mnem[lstore_3] = "lstore_3";
2052:        mnem[fstore_3] = "fstore_3";
2053:        mnem[dstore_3] = "dstore_3";
2054:        mnem[astore_3] = "astore_3";
2055:        mnem[iastore] = "iastore";
2056:        mnem[lastore] = "lastore";
2057:        mnem[fastore] = "fastore";
2058:        mnem[dastore] = "dastore";
2059:        mnem[aastore] = "aastore";
2060:        mnem[bastore] = "bastore";
2061:        mnem[castore] = "castore";
2062:        mnem[sastore] = "sastore";
2063:        mnem[pop] = "pop";
2064:        mnem[pop2] = "pop2";
2065:        mnem[dup] = "dup";
2066:        mnem[dup_x1] = "dup_x1";
2067:        mnem[dup_x2] = "dup_x2";
2068:        mnem[dup2] = "dup2";
2069:        mnem[dup2_x1] = "dup2_x1";
2070:        mnem[dup2_x2] = "dup2_x2";
2071:        mnem[swap] = "swap";
2072:        mnem[iadd] = "iadd";
2073:        mnem[ladd] = "ladd";
2074:        mnem[fadd] = "fadd";
2075:        mnem[dadd] = "dadd";
2076:        mnem[isub] = "isub";
2077:        mnem[lsub] = "lsub";
2078:        mnem[fsub] = "fsub";
2079:        mnem[dsub] = "dsub";
2080:        mnem[imul] = "imul";
2081:        mnem[lmul] = "lmul";
2082:        mnem[fmul] = "fmul";
2083:        mnem[dmul] = "dmul";
2084:        mnem[idiv] = "idiv";
2085:        mnem[ldiv] = "ldiv";
2086:        mnem[fdiv] = "fdiv";
2087:        mnem[ddiv] = "ddiv";
2088:        mnem[imod] = "imod";
2089:        mnem[lmod] = "lmod";
2090:        mnem[fmod] = "fmod";
2091:        mnem[dmod] = "dmod";
2092:        mnem[ineg] = "ineg";
2093:        mnem[lneg] = "lneg";
2094:        mnem[fneg] = "fneg";
2095:        mnem[dneg] = "dneg";
2096:        mnem[ishl] = "ishl";
2097:        mnem[lshl] = "lshl";
2098:        mnem[ishr] = "ishr";
2099:        mnem[lshr] = "lshr";
2100:        mnem[iushr] = "iushr";
2101:        mnem[lushr] = "lushr";
2102:        mnem[iand] = "iand";
2103:        mnem[land] = "land";
2104:        mnem[ior] = "ior";
2105:        mnem[lor] = "lor";
2106:        mnem[ixor] = "ixor";
2107:        mnem[lxor] = "lxor";
2108:        mnem[iinc] = "iinc";
2109:        mnem[i2l] = "i2l";
2110:        mnem[i2f] = "i2f";
2111:        mnem[i2d] = "i2d";
2112:        mnem[l2i] = "l2i";
2113:        mnem[l2f] = "l2f";
2114:        mnem[l2d] = "l2d";
2115:        mnem[f2i] = "f2i";
2116:        mnem[f2l] = "f2l";
2117:        mnem[f2d] = "f2d";
2118:        mnem[d2i] = "d2i";
2119:        mnem[d2l] = "d2l";
2120:        mnem[d2f] = "d2f";
2121:        mnem[int2byte] = "int2byte";
2122:        mnem[int2char] = "int2char";
2123:        mnem[int2short] = "int2short";
2124:        mnem[lcmp] = "lcmp";
2125:        mnem[fcmpl] = "fcmpl";
2126:        mnem[fcmpg] = "fcmpg";
2127:        mnem[dcmpl] = "dcmpl";
2128:        mnem[dcmpg] = "dcmpg";
2129:        mnem[ifeq] = "ifeq";
2130:        mnem[ifne] = "ifne";
2131:        mnem[iflt] = "iflt";
2132:        mnem[ifge] = "ifge";
2133:        mnem[ifgt] = "ifgt";
2134:        mnem[ifle] = "ifle";
2135:        mnem[if_icmpeq] = "if_icmpeq";
2136:        mnem[if_icmpne] = "if_icmpne";
2137:        mnem[if_icmplt] = "if_icmplt";
2138:        mnem[if_icmpge] = "if_icmpge";
2139:        mnem[if_icmpgt] = "if_icmpgt";
2140:        mnem[if_icmple] = "if_icmple";
2141:        mnem[if_acmpeq] = "if_acmpeq";
2142:        mnem[if_acmpne] = "if_acmpne";
2143:        mnem[goto_] = "goto_";
2144:        mnem[jsr] = "jsr";
2145:        mnem[ret] = "ret";
2146:        mnem[tableswitch] = "tableswitch";
2147:        mnem[lookupswitch] = "lookupswitch";
2148:        mnem[ireturn] = "ireturn";
2149:        mnem[lreturn] = "lreturn";
2150:        mnem[freturn] = "freturn";
2151:        mnem[dreturn] = "dreturn";
2152:        mnem[areturn] = "areturn";
2153:        mnem[return_] = "return_";
2154:        mnem[getstatic] = "getstatic";
2155:        mnem[putstatic] = "putstatic";
2156:        mnem[getfield] = "getfield";
2157:        mnem[putfield] = "putfield";
2158:        mnem[invokevirtual] = "invokevirtual";
2159:        mnem[invokespecial] = "invokespecial";
2160:        mnem[invokestatic] = "invokestatic";
2161:        mnem[invokeinterface] = "invokeinterface";
2162:        // mnem[___unused___] = "___unused___";
2163:        mnem[new_] = "new_";
2164:        mnem[newarray] = "newarray";
2165:        mnem[anewarray] = "anewarray";
2166:        mnem[arraylength] = "arraylength";
2167:        mnem[athrow] = "athrow";
2168:        mnem[checkcast] = "checkcast";
2169:        mnem[instanceof_] = "instanceof_";
2170:        mnem[monitorenter] = "monitorenter";
2171:        mnem[monitorexit] = "monitorexit";
2172:        mnem[wide] = "wide";
2173:        mnem[multianewarray] = "multianewarray";
2174:        mnem[if_acmp_null] = "if_acmp_null";
2175:        mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2176:        mnem[goto_w] = "goto_w";
2177:        mnem[jsr_w] = "jsr_w";
2178:        mnem[breakpoint] = "breakpoint";
2179:    }
2180:    }
2181:}