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