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