Code.java revision 2676:873e58766948
1135549Sdes/* 2135549Sdes * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. 3135549Sdes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4193149Sdougb * 5135549Sdes * This code is free software; you can redistribute it and/or modify it 6135549Sdes * under the terms of the GNU General Public License version 2 only, as 7174189Sdougb * published by the Free Software Foundation. Oracle designates this 8135549Sdes * particular file as subject to the "Classpath" exception as provided 9135549Sdes * by Oracle in the LICENSE file that accompanied this code. 10135549Sdes * 11135549Sdes * This code is distributed in the hope that it will be useful, but WITHOUT 12135549Sdes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13135549Sdes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14135549Sdes * version 2 for more details (a copy is included in the LICENSE file that 15135549Sdes * accompanied this code). 16135549Sdes * 17135549Sdes * You should have received a copy of the GNU General Public License version 18135549Sdes * 2 along with this work; if not, write to the Free Software Foundation, 19135549Sdes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20193149Sdougb * 21135549Sdes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22135549Sdes * or visit www.oracle.com if you need additional information or have any 23135549Sdes * questions. 24135549Sdes */ 25170224Sdougb 26170224Sdougbpackage com.sun.tools.javac.jvm; 27135549Sdes 28135549Sdesimport com.sun.tools.javac.code.*; 29135549Sdesimport com.sun.tools.javac.code.Symbol.*; 30135549Sdesimport com.sun.tools.javac.code.Types.UniqueType; 31135549Sdesimport com.sun.tools.javac.tree.JCTree; 32135549Sdesimport com.sun.tools.javac.util.*; 33135549Sdesimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 34135549Sdes 35170224Sdougbimport static com.sun.tools.javac.code.TypeTag.BOT; 36135549Sdesimport static com.sun.tools.javac.code.TypeTag.INT; 37135549Sdesimport static com.sun.tools.javac.jvm.ByteCodes.*; 38135549Sdesimport static com.sun.tools.javac.jvm.UninitializedType.*; 39135549Sdesimport static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame; 40135549Sdes 41170224Sdougb/** An internal structure that corresponds to the code attribute of 42135549Sdes * methods in a classfile. The class also provides some utility operations to 43135549Sdes * generate bytecode instructions. 44135549Sdes * 45135549Sdes * <p><b>This is NOT part of any supported API. 46135549Sdes * If you write code that depends on this, you do so at your own risk. 47170224Sdougb * This code and its internal interfaces are subject to change or 48135549Sdes * deletion without notice.</b> 49135549Sdes */ 50135549Sdespublic class Code { 51135549Sdes 52135549Sdes public final boolean debugCode; 53170224Sdougb public final boolean needStackMap; 54135549Sdes 55135549Sdes public enum StackMapFormat { 56135549Sdes NONE, 57135549Sdes CLDC { 58135549Sdes Name getAttributeName(Names names) { 59170224Sdougb return names.StackMap; 60135549Sdes } 61135549Sdes }, 62135549Sdes JSR202 { 63135549Sdes Name getAttributeName(Names names) { 64135549Sdes return names.StackMapTable; 65170224Sdougb } 66135549Sdes }; 67135549Sdes Name getAttributeName(Names names) { 68135549Sdes return names.empty; 69135549Sdes } 70135549Sdes } 71170224Sdougb 72135549Sdes final Types types; 73135549Sdes final Symtab syms; 74135549Sdes 75135549Sdes/*---------- classfile fields: --------------- */ 76135549Sdes 77170224Sdougb /** The maximum stack size. 78135549Sdes */ 79135549Sdes public int max_stack = 0; 80135549Sdes 81135549Sdes /** The maximum number of local variable slots. 82135549Sdes */ 83170224Sdougb public int max_locals = 0; 84135549Sdes 85135549Sdes /** The code buffer. 86135549Sdes */ 87135549Sdes public byte[] code = new byte[64]; 88170224Sdougb 89135549Sdes /** the current code pointer. 90135549Sdes */ 91135549Sdes public int cp = 0; 92135549Sdes 93170224Sdougb /** Check the code against VM spec limits; if 94135549Sdes * problems report them and return true. 95135549Sdes */ 96153821Sdougb public boolean checkLimits(DiagnosticPosition pos, Log log) { 97135549Sdes if (cp > ClassFile.MAX_CODE) { 98170224Sdougb log.error(pos, "limit.code"); 99135549Sdes return true; 100135549Sdes } 101135549Sdes if (max_locals > ClassFile.MAX_LOCALS) { 102135549Sdes log.error(pos, "limit.locals"); 103170224Sdougb return true; 104193149Sdougb } 105193149Sdougb if (max_stack > ClassFile.MAX_STACK) { 106135549Sdes log.error(pos, "limit.stack"); 107193149Sdougb return true; 108135549Sdes } 109170224Sdougb return false; 110193149Sdougb } 111193149Sdougb 112135549Sdes /** A buffer for expression catch data. Each enter is a vector 113193149Sdougb * of four unsigned shorts. 114135549Sdes */ 115170224Sdougb ListBuffer<char[]> catchInfo = new ListBuffer<>(); 116193149Sdougb 117135549Sdes /** A buffer for line number information. Each entry is a vector 118193149Sdougb * of two unsigned shorts. 119135549Sdes */ 120170224Sdougb List<char[]> lineInfo = List.nil(); // handled in stack fashion 121135549Sdes 122135549Sdes /** The CharacterRangeTable 123135549Sdes */ 124135549Sdes public CRTable crt; 125170224Sdougb 126193149Sdougb/*---------- internal fields: --------------- */ 127135549Sdes 128193149Sdougb /** Are we generating code with jumps ≥ 32K? 129135549Sdes */ 130170224Sdougb public boolean fatcode; 131135549Sdes 132135549Sdes /** Code generation enabled? 133135549Sdes */ 134135549Sdes private boolean alive = true; 135135549Sdes 136186463Sdougb /** The current machine state (registers and stack). 137186463Sdougb */ 138186463Sdougb State state; 139186463Sdougb 140186463Sdougb /** Is it forbidden to compactify code, because something is 141186463Sdougb * pointing to current location? 142186463Sdougb */ 143186463Sdougb private boolean fixedPc = false; 144186463Sdougb 145186463Sdougb /** The next available register. 146186463Sdougb */ 147186463Sdougb public int nextreg = 0; 148186463Sdougb 149186463Sdougb /** A chain for jumps to be resolved before the next opcode is emitted. 150186463Sdougb * We do this lazily to avoid jumps to jumps. 151170224Sdougb */ 152135549Sdes Chain pendingJumps = null; 153135549Sdes 154135549Sdes /** The position of the currently statement, if we are at the 155170224Sdougb * start of this statement, NOPOS otherwise. 156135549Sdes * We need this to emit line numbers lazily, which we need to do 157135549Sdes * because of jump-to-jump optimization. 158135549Sdes */ 159135549Sdes int pendingStatPos = Position.NOPOS; 160135549Sdes 161170224Sdougb /** Set true when a stackMap is needed at the current PC. */ 162135549Sdes boolean pendingStackMap = false; 163135549Sdes 164135549Sdes /** The stack map format to be generated. */ 165135549Sdes StackMapFormat stackMap; 166170224Sdougb 167135549Sdes /** Switch: emit variable debug info. 168135549Sdes */ 169135549Sdes boolean varDebugInfo; 170135549Sdes 171193149Sdougb /** Switch: emit line number info. 172193149Sdougb */ 173193149Sdougb boolean lineDebugInfo; 174193149Sdougb 175193149Sdougb /** Emit line number info if map supplied 176135549Sdes */ 177193149Sdougb Position.LineMap lineMap; 178135549Sdes 179193149Sdougb /** The constant pool of the current class. 180193149Sdougb */ 181135549Sdes final Pool pool; 182193149Sdougb 183135549Sdes final MethodSymbol meth; 184193149Sdougb 185193149Sdougb final LVTRanges lvtRanges; 186135549Sdes 187193149Sdougb /** Construct a code object, given the settings of the fatcode, 188135549Sdes * debugging info switches and the CharacterRangeTable. 189193149Sdougb */ 190193149Sdougb public Code(MethodSymbol meth, 191135549Sdes boolean fatcode, 192193149Sdougb Position.LineMap lineMap, 193135549Sdes boolean varDebugInfo, 194193149Sdougb StackMapFormat stackMap, 195193149Sdougb boolean debugCode, 196135549Sdes CRTable crt, 197193149Sdougb Symtab syms, 198135549Sdes Types types, 199193149Sdougb Pool pool, 200193149Sdougb LVTRanges lvtRanges) { 201193149Sdougb this.meth = meth; 202193149Sdougb this.fatcode = fatcode; 203193149Sdougb this.lineMap = lineMap; 204193149Sdougb this.lineDebugInfo = lineMap != null; 205135549Sdes this.varDebugInfo = varDebugInfo; 206193149Sdougb this.crt = crt; 207135549Sdes this.syms = syms; 208193149Sdougb this.types = types; 209193149Sdougb this.debugCode = debugCode; 210135549Sdes this.stackMap = stackMap; 211193149Sdougb switch (stackMap) { 212135549Sdes case CLDC: 213193149Sdougb case JSR202: 214193149Sdougb this.needStackMap = true; 215193149Sdougb break; 216135549Sdes default: 217135549Sdes this.needStackMap = false; 218193149Sdougb } 219193149Sdougb state = new State(); 220193149Sdougb lvar = new LocalVar[20]; 221135549Sdes this.pool = pool; 222193149Sdougb this.lvtRanges = lvtRanges; 223135549Sdes } 224193149Sdougb 225193149Sdougb 226135549Sdes/* ************************************************************************** 227193149Sdougb * Typecodes & related stuff 228135549Sdes ****************************************************************************/ 229193149Sdougb 230193149Sdougb /** Given a type, return its type code (used implicitly in the 231193149Sdougb * JVM architecture). 232135549Sdes */ 233193149Sdougb public static int typecode(Type type) { 234135549Sdes switch (type.getTag()) { 235170224Sdougb case BYTE: return BYTEcode; 236193149Sdougb case SHORT: return SHORTcode; 237193149Sdougb case CHAR: return CHARcode; 238193149Sdougb case INT: return INTcode; 239193149Sdougb case LONG: return LONGcode; 240193149Sdougb case FLOAT: return FLOATcode; 241170224Sdougb case DOUBLE: return DOUBLEcode; 242170224Sdougb case BOOLEAN: return BYTEcode; 243170224Sdougb case VOID: return VOIDcode; 244170224Sdougb case CLASS: 245170224Sdougb case ARRAY: 246170224Sdougb case METHOD: 247186463Sdougb case BOT: 248170224Sdougb case TYPEVAR: 249170224Sdougb case UNINITIALIZED_THIS: 250170224Sdougb case UNINITIALIZED_OBJECT: 251170224Sdougb return OBJECTcode; 252193149Sdougb default: throw new AssertionError("typecode " + type.getTag()); 253193149Sdougb } 254193149Sdougb } 255214585Sdougb 256214585Sdougb /** Collapse type code for subtypes of int to INTcode. 257214585Sdougb */ 258214585Sdougb public static int truncate(int tc) { 259214585Sdougb switch (tc) { 260214585Sdougb case BYTEcode: case SHORTcode: case CHARcode: return INTcode; 261193149Sdougb default: return tc; 262214585Sdougb } 263193149Sdougb } 264193149Sdougb 265170224Sdougb /** The width in bytes of objects of the type. 266186463Sdougb */ 267170224Sdougb public static int width(int typecode) { 268170224Sdougb switch (typecode) { 269170224Sdougb case LONGcode: case DOUBLEcode: return 2; 270170224Sdougb case VOIDcode: return 0; 271170224Sdougb default: return 1; 272186463Sdougb } 273170224Sdougb } 274170224Sdougb 275170224Sdougb public static int width(Type type) { 276170224Sdougb return type == null ? 1 : width(typecode(type)); 277170224Sdougb } 278170224Sdougb 279170224Sdougb /** The total width taken up by a vector of objects. 280170224Sdougb */ 281170224Sdougb public static int width(List<Type> types) { 282170224Sdougb int w = 0; 283170224Sdougb for (List<Type> l = types; l.nonEmpty(); l = l.tail) 284170224Sdougb w = w + width(l.head); 285170224Sdougb return w; 286170224Sdougb } 287170224Sdougb 288170224Sdougb /** Given a type, return its code for allocating arrays of that type. 289170224Sdougb */ 290170224Sdougb public static int arraycode(Type type) { 291170224Sdougb switch (type.getTag()) { 292193149Sdougb case BYTE: return 8; 293193149Sdougb case BOOLEAN: return 4; 294193149Sdougb case SHORT: return 9; 295193149Sdougb case CHAR: return 5; 296193149Sdougb case INT: return 10; 297193149Sdougb case LONG: return 11; 298193149Sdougb case FLOAT: return 6; 299193149Sdougb case DOUBLE: return 7; 300193149Sdougb case CLASS: return 0; 301170224Sdougb case ARRAY: return 1; 302170224Sdougb default: throw new AssertionError("arraycode " + type); 303170224Sdougb } 304170224Sdougb } 305170224Sdougb 306135549Sdes 307135549Sdes/* ************************************************************************** 308135549Sdes * Emit code 309135549Sdes ****************************************************************************/ 310135549Sdes 311135549Sdes /** The current output code pointer. 312170224Sdougb */ 313135549Sdes public int curCP() { 314135549Sdes /* 315135549Sdes * This method has side-effects because calling it can indirectly provoke 316135549Sdes * extra code generation, like goto instructions, depending on the context 317135549Sdes * where it's called. 318135549Sdes * Use with care or even better avoid using it. 319135549Sdes */ 320135549Sdes if (pendingJumps != null) { 321135549Sdes resolvePending(); 322135549Sdes } 323135549Sdes if (pendingStatPos != Position.NOPOS) { 324135549Sdes markStatBegin(); 325135549Sdes } 326135549Sdes fixedPc = true; 327135549Sdes return cp; 328135549Sdes } 329135549Sdes 330135549Sdes /** Emit a byte of code. 331135549Sdes */ 332135549Sdes private void emit1(int od) { 333135549Sdes if (!alive) return; 334135549Sdes code = ArrayUtils.ensureCapacity(code, cp); 335135549Sdes code[cp++] = (byte)od; 336135549Sdes } 337135549Sdes 338170224Sdougb /** Emit two bytes of code. 339135549Sdes */ 340135549Sdes private void emit2(int od) { 341135549Sdes if (!alive) return; 342135549Sdes if (cp + 2 > code.length) { 343135549Sdes emit1(od >> 8); 344135549Sdes emit1(od); 345135549Sdes } else { 346135549Sdes code[cp++] = (byte)(od >> 8); 347135549Sdes code[cp++] = (byte)od; 348135549Sdes } 349 } 350 351 /** Emit four bytes of code. 352 */ 353 public void emit4(int od) { 354 if (!alive) return; 355 if (cp + 4 > code.length) { 356 emit1(od >> 24); 357 emit1(od >> 16); 358 emit1(od >> 8); 359 emit1(od); 360 } else { 361 code[cp++] = (byte)(od >> 24); 362 code[cp++] = (byte)(od >> 16); 363 code[cp++] = (byte)(od >> 8); 364 code[cp++] = (byte)od; 365 } 366 } 367 368 /** Emit an opcode. 369 */ 370 private void emitop(int op) { 371 if (pendingJumps != null) resolvePending(); 372 if (alive) { 373 if (pendingStatPos != Position.NOPOS) 374 markStatBegin(); 375 if (pendingStackMap) { 376 pendingStackMap = false; 377 emitStackMap(); 378 } 379 if (debugCode) 380 System.err.println("emit@" + cp + " stack=" + 381 state.stacksize + ": " + 382 mnem(op)); 383 emit1(op); 384 } 385 } 386 387 void postop() { 388 Assert.check(alive || state.stacksize == 0); 389 } 390 391 /** Emit a ldc (or ldc_w) instruction, taking into account operand size 392 */ 393 public void emitLdc(int od) { 394 if (od <= 255) { 395 emitop1(ldc1, od); 396 } 397 else { 398 emitop2(ldc2, od); 399 } 400 } 401 402 /** Emit a multinewarray instruction. 403 */ 404 public void emitMultianewarray(int ndims, int type, Type arrayType) { 405 emitop(multianewarray); 406 if (!alive) return; 407 emit2(type); 408 emit1(ndims); 409 state.pop(ndims); 410 state.push(arrayType); 411 } 412 413 /** Emit newarray. 414 */ 415 public void emitNewarray(int elemcode, Type arrayType) { 416 emitop(newarray); 417 if (!alive) return; 418 emit1(elemcode); 419 state.pop(1); // count 420 state.push(arrayType); 421 } 422 423 /** Emit anewarray. 424 */ 425 public void emitAnewarray(int od, Type arrayType) { 426 emitop(anewarray); 427 if (!alive) return; 428 emit2(od); 429 state.pop(1); 430 state.push(arrayType); 431 } 432 433 /** Emit an invokeinterface instruction. 434 */ 435 public void emitInvokeinterface(int meth, Type mtype) { 436 int argsize = width(mtype.getParameterTypes()); 437 emitop(invokeinterface); 438 if (!alive) return; 439 emit2(meth); 440 emit1(argsize + 1); 441 emit1(0); 442 state.pop(argsize + 1); 443 state.push(mtype.getReturnType()); 444 } 445 446 /** Emit an invokespecial instruction. 447 */ 448 public void emitInvokespecial(int meth, Type mtype) { 449 int argsize = width(mtype.getParameterTypes()); 450 emitop(invokespecial); 451 if (!alive) return; 452 emit2(meth); 453 Symbol sym = (Symbol)pool.pool[meth]; 454 state.pop(argsize); 455 if (sym.isConstructor()) 456 state.markInitialized((UninitializedType)state.peek()); 457 state.pop(1); 458 state.push(mtype.getReturnType()); 459 } 460 461 /** Emit an invokestatic instruction. 462 */ 463 public void emitInvokestatic(int meth, Type mtype) { 464 int argsize = width(mtype.getParameterTypes()); 465 emitop(invokestatic); 466 if (!alive) return; 467 emit2(meth); 468 state.pop(argsize); 469 state.push(mtype.getReturnType()); 470 } 471 472 /** Emit an invokevirtual instruction. 473 */ 474 public void emitInvokevirtual(int meth, Type mtype) { 475 int argsize = width(mtype.getParameterTypes()); 476 emitop(invokevirtual); 477 if (!alive) return; 478 emit2(meth); 479 state.pop(argsize + 1); 480 state.push(mtype.getReturnType()); 481 } 482 483 /** Emit an invokedynamic instruction. 484 */ 485 public void emitInvokedynamic(int desc, Type mtype) { 486 int argsize = width(mtype.getParameterTypes()); 487 emitop(invokedynamic); 488 if (!alive) return; 489 emit2(desc); 490 emit2(0); 491 state.pop(argsize); 492 state.push(mtype.getReturnType()); 493 } 494 495 /** Emit an opcode with no operand field. 496 */ 497 public void emitop0(int op) { 498 emitop(op); 499 if (!alive) return; 500 switch (op) { 501 case aaload: { 502 state.pop(1);// index 503 Type a = state.stack[state.stacksize-1]; 504 state.pop(1); 505 //sometimes 'null type' is treated as a one-dimensional array type 506 //see Gen.visitLiteral - we should handle this case accordingly 507 Type stackType = a.hasTag(BOT) ? 508 syms.objectType : 509 types.erasure(types.elemtype(a)); 510 state.push(stackType); } 511 break; 512 case goto_: 513 markDead(); 514 break; 515 case nop: 516 case ineg: 517 case lneg: 518 case fneg: 519 case dneg: 520 break; 521 case aconst_null: 522 state.push(syms.botType); 523 break; 524 case iconst_m1: 525 case iconst_0: 526 case iconst_1: 527 case iconst_2: 528 case iconst_3: 529 case iconst_4: 530 case iconst_5: 531 case iload_0: 532 case iload_1: 533 case iload_2: 534 case iload_3: 535 state.push(syms.intType); 536 break; 537 case lconst_0: 538 case lconst_1: 539 case lload_0: 540 case lload_1: 541 case lload_2: 542 case lload_3: 543 state.push(syms.longType); 544 break; 545 case fconst_0: 546 case fconst_1: 547 case fconst_2: 548 case fload_0: 549 case fload_1: 550 case fload_2: 551 case fload_3: 552 state.push(syms.floatType); 553 break; 554 case dconst_0: 555 case dconst_1: 556 case dload_0: 557 case dload_1: 558 case dload_2: 559 case dload_3: 560 state.push(syms.doubleType); 561 break; 562 case aload_0: 563 state.push(lvar[0].sym.type); 564 break; 565 case aload_1: 566 state.push(lvar[1].sym.type); 567 break; 568 case aload_2: 569 state.push(lvar[2].sym.type); 570 break; 571 case aload_3: 572 state.push(lvar[3].sym.type); 573 break; 574 case iaload: 575 case baload: 576 case caload: 577 case saload: 578 state.pop(2); 579 state.push(syms.intType); 580 break; 581 case laload: 582 state.pop(2); 583 state.push(syms.longType); 584 break; 585 case faload: 586 state.pop(2); 587 state.push(syms.floatType); 588 break; 589 case daload: 590 state.pop(2); 591 state.push(syms.doubleType); 592 break; 593 case istore_0: 594 case istore_1: 595 case istore_2: 596 case istore_3: 597 case fstore_0: 598 case fstore_1: 599 case fstore_2: 600 case fstore_3: 601 case astore_0: 602 case astore_1: 603 case astore_2: 604 case astore_3: 605 case pop: 606 case lshr: 607 case lshl: 608 case lushr: 609 state.pop(1); 610 break; 611 case areturn: 612 case ireturn: 613 case freturn: 614 Assert.check(state.nlocks == 0); 615 state.pop(1); 616 markDead(); 617 break; 618 case athrow: 619 state.pop(1); 620 markDead(); 621 break; 622 case lstore_0: 623 case lstore_1: 624 case lstore_2: 625 case lstore_3: 626 case dstore_0: 627 case dstore_1: 628 case dstore_2: 629 case dstore_3: 630 case pop2: 631 state.pop(2); 632 break; 633 case lreturn: 634 case dreturn: 635 Assert.check(state.nlocks == 0); 636 state.pop(2); 637 markDead(); 638 break; 639 case dup: 640 state.push(state.stack[state.stacksize-1]); 641 break; 642 case return_: 643 Assert.check(state.nlocks == 0); 644 markDead(); 645 break; 646 case arraylength: 647 state.pop(1); 648 state.push(syms.intType); 649 break; 650 case isub: 651 case iadd: 652 case imul: 653 case idiv: 654 case imod: 655 case ishl: 656 case ishr: 657 case iushr: 658 case iand: 659 case ior: 660 case ixor: 661 state.pop(1); 662 // state.pop(1); 663 // state.push(syms.intType); 664 break; 665 case aastore: 666 state.pop(3); 667 break; 668 case land: 669 case lor: 670 case lxor: 671 case lmod: 672 case ldiv: 673 case lmul: 674 case lsub: 675 case ladd: 676 state.pop(2); 677 break; 678 case lcmp: 679 state.pop(4); 680 state.push(syms.intType); 681 break; 682 case l2i: 683 state.pop(2); 684 state.push(syms.intType); 685 break; 686 case i2l: 687 state.pop(1); 688 state.push(syms.longType); 689 break; 690 case i2f: 691 state.pop(1); 692 state.push(syms.floatType); 693 break; 694 case i2d: 695 state.pop(1); 696 state.push(syms.doubleType); 697 break; 698 case l2f: 699 state.pop(2); 700 state.push(syms.floatType); 701 break; 702 case l2d: 703 state.pop(2); 704 state.push(syms.doubleType); 705 break; 706 case f2i: 707 state.pop(1); 708 state.push(syms.intType); 709 break; 710 case f2l: 711 state.pop(1); 712 state.push(syms.longType); 713 break; 714 case f2d: 715 state.pop(1); 716 state.push(syms.doubleType); 717 break; 718 case d2i: 719 state.pop(2); 720 state.push(syms.intType); 721 break; 722 case d2l: 723 state.pop(2); 724 state.push(syms.longType); 725 break; 726 case d2f: 727 state.pop(2); 728 state.push(syms.floatType); 729 break; 730 case tableswitch: 731 case lookupswitch: 732 state.pop(1); 733 // the caller is responsible for patching up the state 734 break; 735 case dup_x1: { 736 Type val1 = state.pop1(); 737 Type val2 = state.pop1(); 738 state.push(val1); 739 state.push(val2); 740 state.push(val1); 741 break; 742 } 743 case bastore: 744 state.pop(3); 745 break; 746 case int2byte: 747 case int2char: 748 case int2short: 749 break; 750 case fmul: 751 case fadd: 752 case fsub: 753 case fdiv: 754 case fmod: 755 state.pop(1); 756 break; 757 case castore: 758 case iastore: 759 case fastore: 760 case sastore: 761 state.pop(3); 762 break; 763 case lastore: 764 case dastore: 765 state.pop(4); 766 break; 767 case dup2: 768 if (state.stack[state.stacksize-1] != null) { 769 Type value1 = state.pop1(); 770 Type value2 = state.pop1(); 771 state.push(value2); 772 state.push(value1); 773 state.push(value2); 774 state.push(value1); 775 } else { 776 Type value = state.pop2(); 777 state.push(value); 778 state.push(value); 779 } 780 break; 781 case dup2_x1: 782 if (state.stack[state.stacksize-1] != null) { 783 Type value1 = state.pop1(); 784 Type value2 = state.pop1(); 785 Type value3 = state.pop1(); 786 state.push(value2); 787 state.push(value1); 788 state.push(value3); 789 state.push(value2); 790 state.push(value1); 791 } else { 792 Type value1 = state.pop2(); 793 Type value2 = state.pop1(); 794 state.push(value1); 795 state.push(value2); 796 state.push(value1); 797 } 798 break; 799 case dup2_x2: 800 if (state.stack[state.stacksize-1] != null) { 801 Type value1 = state.pop1(); 802 Type value2 = state.pop1(); 803 if (state.stack[state.stacksize-1] != null) { 804 // form 1 805 Type value3 = state.pop1(); 806 Type value4 = state.pop1(); 807 state.push(value2); 808 state.push(value1); 809 state.push(value4); 810 state.push(value3); 811 state.push(value2); 812 state.push(value1); 813 } else { 814 // form 3 815 Type value3 = state.pop2(); 816 state.push(value2); 817 state.push(value1); 818 state.push(value3); 819 state.push(value2); 820 state.push(value1); 821 } 822 } else { 823 Type value1 = state.pop2(); 824 if (state.stack[state.stacksize-1] != null) { 825 // form 2 826 Type value2 = state.pop1(); 827 Type value3 = state.pop1(); 828 state.push(value1); 829 state.push(value3); 830 state.push(value2); 831 state.push(value1); 832 } else { 833 // form 4 834 Type value2 = state.pop2(); 835 state.push(value1); 836 state.push(value2); 837 state.push(value1); 838 } 839 } 840 break; 841 case dup_x2: { 842 Type value1 = state.pop1(); 843 if (state.stack[state.stacksize-1] != null) { 844 // form 1 845 Type value2 = state.pop1(); 846 Type value3 = state.pop1(); 847 state.push(value1); 848 state.push(value3); 849 state.push(value2); 850 state.push(value1); 851 } else { 852 // form 2 853 Type value2 = state.pop2(); 854 state.push(value1); 855 state.push(value2); 856 state.push(value1); 857 } 858 } 859 break; 860 case fcmpl: 861 case fcmpg: 862 state.pop(2); 863 state.push(syms.intType); 864 break; 865 case dcmpl: 866 case dcmpg: 867 state.pop(4); 868 state.push(syms.intType); 869 break; 870 case swap: { 871 Type value1 = state.pop1(); 872 Type value2 = state.pop1(); 873 state.push(value1); 874 state.push(value2); 875 break; 876 } 877 case dadd: 878 case dsub: 879 case dmul: 880 case ddiv: 881 case dmod: 882 state.pop(2); 883 break; 884 case ret: 885 markDead(); 886 break; 887 case wide: 888 // must be handled by the caller. 889 return; 890 case monitorenter: 891 case monitorexit: 892 state.pop(1); 893 break; 894 895 default: 896 throw new AssertionError(mnem(op)); 897 } 898 postop(); 899 } 900 901 /** Emit an opcode with a one-byte operand field. 902 */ 903 public void emitop1(int op, int od) { 904 emitop(op); 905 if (!alive) return; 906 emit1(od); 907 switch (op) { 908 case bipush: 909 state.push(syms.intType); 910 break; 911 case ldc1: 912 state.push(typeForPool(pool.pool[od])); 913 break; 914 default: 915 throw new AssertionError(mnem(op)); 916 } 917 postop(); 918 } 919 920 /** The type of a constant pool entry. */ 921 private Type typeForPool(Object o) { 922 if (o instanceof Integer) return syms.intType; 923 if (o instanceof Float) return syms.floatType; 924 if (o instanceof String) return syms.stringType; 925 if (o instanceof Long) return syms.longType; 926 if (o instanceof Double) return syms.doubleType; 927 if (o instanceof ClassSymbol) return syms.classType; 928 if (o instanceof Pool.MethodHandle) return syms.methodHandleType; 929 if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type); 930 if (o instanceof Type) { 931 Type ty = (Type) o; 932 933 if (ty instanceof Type.ArrayType) return syms.classType; 934 if (ty instanceof Type.MethodType) return syms.methodTypeType; 935 } 936 throw new AssertionError("Invalid type of constant pool entry: " + o.getClass()); 937 } 938 939 /** Emit an opcode with a one-byte operand field; 940 * widen if field does not fit in a byte. 941 */ 942 public void emitop1w(int op, int od) { 943 if (od > 0xFF) { 944 emitop(wide); 945 emitop(op); 946 emit2(od); 947 } else { 948 emitop(op); 949 emit1(od); 950 } 951 if (!alive) return; 952 switch (op) { 953 case iload: 954 state.push(syms.intType); 955 break; 956 case lload: 957 state.push(syms.longType); 958 break; 959 case fload: 960 state.push(syms.floatType); 961 break; 962 case dload: 963 state.push(syms.doubleType); 964 break; 965 case aload: 966 state.push(lvar[od].sym.type); 967 break; 968 case lstore: 969 case dstore: 970 state.pop(2); 971 break; 972 case istore: 973 case fstore: 974 case astore: 975 state.pop(1); 976 break; 977 case ret: 978 markDead(); 979 break; 980 default: 981 throw new AssertionError(mnem(op)); 982 } 983 postop(); 984 } 985 986 /** Emit an opcode with two one-byte operand fields; 987 * widen if either field does not fit in a byte. 988 */ 989 public void emitop1w(int op, int od1, int od2) { 990 if (od1 > 0xFF || od2 < -128 || od2 > 127) { 991 emitop(wide); 992 emitop(op); 993 emit2(od1); 994 emit2(od2); 995 } else { 996 emitop(op); 997 emit1(od1); 998 emit1(od2); 999 } 1000 if (!alive) return; 1001 switch (op) { 1002 case iinc: 1003 break; 1004 default: 1005 throw new AssertionError(mnem(op)); 1006 } 1007 } 1008 1009 /** Emit an opcode with a two-byte operand field. 1010 */ 1011 public void emitop2(int op, int od) { 1012 emitop(op); 1013 if (!alive) return; 1014 emit2(od); 1015 switch (op) { 1016 case getstatic: 1017 state.push(((Symbol)(pool.pool[od])).erasure(types)); 1018 break; 1019 case putstatic: 1020 state.pop(((Symbol)(pool.pool[od])).erasure(types)); 1021 break; 1022 case new_: 1023 Symbol sym; 1024 if (pool.pool[od] instanceof UniqueType) { 1025 // Required by change in Gen.makeRef to allow 1026 // annotated types. 1027 // TODO: is this needed anywhere else? 1028 sym = ((UniqueType)(pool.pool[od])).type.tsym; 1029 } else { 1030 sym = (Symbol)(pool.pool[od]); 1031 } 1032 state.push(uninitializedObject(sym.erasure(types), cp-3)); 1033 break; 1034 case sipush: 1035 state.push(syms.intType); 1036 break; 1037 case if_acmp_null: 1038 case if_acmp_nonnull: 1039 case ifeq: 1040 case ifne: 1041 case iflt: 1042 case ifge: 1043 case ifgt: 1044 case ifle: 1045 state.pop(1); 1046 break; 1047 case if_icmpeq: 1048 case if_icmpne: 1049 case if_icmplt: 1050 case if_icmpge: 1051 case if_icmpgt: 1052 case if_icmple: 1053 case if_acmpeq: 1054 case if_acmpne: 1055 state.pop(2); 1056 break; 1057 case goto_: 1058 markDead(); 1059 break; 1060 case putfield: 1061 state.pop(((Symbol)(pool.pool[od])).erasure(types)); 1062 state.pop(1); // object ref 1063 break; 1064 case getfield: 1065 state.pop(1); // object ref 1066 state.push(((Symbol)(pool.pool[od])).erasure(types)); 1067 break; 1068 case checkcast: { 1069 state.pop(1); // object ref 1070 Object o = pool.pool[od]; 1071 Type t = (o instanceof Symbol) 1072 ? ((Symbol)o).erasure(types) 1073 : types.erasure((((UniqueType)o).type)); 1074 state.push(t); 1075 break; } 1076 case ldc2w: 1077 state.push(typeForPool(pool.pool[od])); 1078 break; 1079 case instanceof_: 1080 state.pop(1); 1081 state.push(syms.intType); 1082 break; 1083 case ldc2: 1084 state.push(typeForPool(pool.pool[od])); 1085 break; 1086 case jsr: 1087 break; 1088 default: 1089 throw new AssertionError(mnem(op)); 1090 } 1091 // postop(); 1092 } 1093 1094 /** Emit an opcode with a four-byte operand field. 1095 */ 1096 public void emitop4(int op, int od) { 1097 emitop(op); 1098 if (!alive) return; 1099 emit4(od); 1100 switch (op) { 1101 case goto_w: 1102 markDead(); 1103 break; 1104 case jsr_w: 1105 break; 1106 default: 1107 throw new AssertionError(mnem(op)); 1108 } 1109 // postop(); 1110 } 1111 1112 /** Align code pointer to next `incr' boundary. 1113 */ 1114 public void align(int incr) { 1115 if (alive) 1116 while (cp % incr != 0) emitop0(nop); 1117 } 1118 1119 /** Place a byte into code at address pc. 1120 * Pre: {@literal pc + 1 <= cp }. 1121 */ 1122 private void put1(int pc, int op) { 1123 code[pc] = (byte)op; 1124 } 1125 1126 /** Place two bytes into code at address pc. 1127 * Pre: {@literal pc + 2 <= cp }. 1128 */ 1129 private void put2(int pc, int od) { 1130 // pre: pc + 2 <= cp 1131 put1(pc, od >> 8); 1132 put1(pc+1, od); 1133 } 1134 1135 /** Place four bytes into code at address pc. 1136 * Pre: {@literal pc + 4 <= cp }. 1137 */ 1138 public void put4(int pc, int od) { 1139 // pre: pc + 4 <= cp 1140 put1(pc , od >> 24); 1141 put1(pc+1, od >> 16); 1142 put1(pc+2, od >> 8); 1143 put1(pc+3, od); 1144 } 1145 1146 /** Return code byte at position pc as an unsigned int. 1147 */ 1148 private int get1(int pc) { 1149 return code[pc] & 0xFF; 1150 } 1151 1152 /** Return two code bytes at position pc as an unsigned int. 1153 */ 1154 private int get2(int pc) { 1155 return (get1(pc) << 8) | get1(pc+1); 1156 } 1157 1158 /** Return four code bytes at position pc as an int. 1159 */ 1160 public int get4(int pc) { 1161 // pre: pc + 4 <= cp 1162 return 1163 (get1(pc) << 24) | 1164 (get1(pc+1) << 16) | 1165 (get1(pc+2) << 8) | 1166 (get1(pc+3)); 1167 } 1168 1169 /** Is code generation currently enabled? 1170 */ 1171 public boolean isAlive() { 1172 return alive || pendingJumps != null; 1173 } 1174 1175 /** Switch code generation on/off. 1176 */ 1177 public void markDead() { 1178 alive = false; 1179 } 1180 1181 /** Declare an entry point; return current code pointer 1182 */ 1183 public int entryPoint() { 1184 int pc = curCP(); 1185 alive = true; 1186 pendingStackMap = needStackMap; 1187 return pc; 1188 } 1189 1190 /** Declare an entry point with initial state; 1191 * return current code pointer 1192 */ 1193 public int entryPoint(State state) { 1194 int pc = curCP(); 1195 alive = true; 1196 this.state = state.dup(); 1197 Assert.check(state.stacksize <= max_stack); 1198 if (debugCode) System.err.println("entry point " + state); 1199 pendingStackMap = needStackMap; 1200 return pc; 1201 } 1202 1203 /** Declare an entry point with initial state plus a pushed value; 1204 * return current code pointer 1205 */ 1206 public int entryPoint(State state, Type pushed) { 1207 int pc = curCP(); 1208 alive = true; 1209 this.state = state.dup(); 1210 Assert.check(state.stacksize <= max_stack); 1211 this.state.push(pushed); 1212 if (debugCode) System.err.println("entry point " + state); 1213 pendingStackMap = needStackMap; 1214 return pc; 1215 } 1216 1217 1218/************************************************************************** 1219 * Stack map generation 1220 *************************************************************************/ 1221 1222 /** An entry in the stack map. */ 1223 static class StackMapFrame { 1224 int pc; 1225 Type[] locals; 1226 Type[] stack; 1227 } 1228 1229 /** A buffer of cldc stack map entries. */ 1230 StackMapFrame[] stackMapBuffer = null; 1231 1232 /** A buffer of compressed StackMapTable entries. */ 1233 StackMapTableFrame[] stackMapTableBuffer = null; 1234 int stackMapBufferSize = 0; 1235 1236 /** The last PC at which we generated a stack map. */ 1237 int lastStackMapPC = -1; 1238 1239 /** The last stack map frame in StackMapTable. */ 1240 StackMapFrame lastFrame = null; 1241 1242 /** The stack map frame before the last one. */ 1243 StackMapFrame frameBeforeLast = null; 1244 1245 /** Emit a stack map entry. */ 1246 public void emitStackMap() { 1247 int pc = curCP(); 1248 if (!needStackMap) return; 1249 1250 1251 1252 switch (stackMap) { 1253 case CLDC: 1254 emitCLDCStackMap(pc, getLocalsSize()); 1255 break; 1256 case JSR202: 1257 emitStackMapFrame(pc, getLocalsSize()); 1258 break; 1259 default: 1260 throw new AssertionError("Should have chosen a stackmap format"); 1261 } 1262 // DEBUG code follows 1263 if (debugCode) state.dump(pc); 1264 } 1265 1266 private int getLocalsSize() { 1267 int nextLocal = 0; 1268 for (int i=max_locals-1; i>=0; i--) { 1269 if (state.defined.isMember(i) && lvar[i] != null) { 1270 nextLocal = i + width(lvar[i].sym.erasure(types)); 1271 break; 1272 } 1273 } 1274 return nextLocal; 1275 } 1276 1277 /** Emit a CLDC stack map frame. */ 1278 void emitCLDCStackMap(int pc, int localsSize) { 1279 if (lastStackMapPC == pc) { 1280 // drop existing stackmap at this offset 1281 stackMapBuffer[--stackMapBufferSize] = null; 1282 } 1283 lastStackMapPC = pc; 1284 1285 if (stackMapBuffer == null) { 1286 stackMapBuffer = new StackMapFrame[20]; 1287 } else { 1288 stackMapBuffer = ArrayUtils.ensureCapacity(stackMapBuffer, stackMapBufferSize); 1289 } 1290 StackMapFrame frame = 1291 stackMapBuffer[stackMapBufferSize++] = new StackMapFrame(); 1292 frame.pc = pc; 1293 1294 frame.locals = new Type[localsSize]; 1295 for (int i=0; i<localsSize; i++) { 1296 if (state.defined.isMember(i) && lvar[i] != null) { 1297 Type vtype = lvar[i].sym.type; 1298 if (!(vtype instanceof UninitializedType)) 1299 vtype = types.erasure(vtype); 1300 frame.locals[i] = vtype; 1301 } 1302 } 1303 frame.stack = new Type[state.stacksize]; 1304 for (int i=0; i<state.stacksize; i++) 1305 frame.stack[i] = state.stack[i]; 1306 } 1307 1308 void emitStackMapFrame(int pc, int localsSize) { 1309 if (lastFrame == null) { 1310 // first frame 1311 lastFrame = getInitialFrame(); 1312 } else if (lastFrame.pc == pc) { 1313 // drop existing stackmap at this offset 1314 stackMapTableBuffer[--stackMapBufferSize] = null; 1315 lastFrame = frameBeforeLast; 1316 frameBeforeLast = null; 1317 } 1318 1319 StackMapFrame frame = new StackMapFrame(); 1320 frame.pc = pc; 1321 1322 int localCount = 0; 1323 Type[] locals = new Type[localsSize]; 1324 for (int i=0; i<localsSize; i++, localCount++) { 1325 if (state.defined.isMember(i) && lvar[i] != null) { 1326 Type vtype = lvar[i].sym.type; 1327 if (!(vtype instanceof UninitializedType)) 1328 vtype = types.erasure(vtype); 1329 locals[i] = vtype; 1330 if (width(vtype) > 1) i++; 1331 } 1332 } 1333 frame.locals = new Type[localCount]; 1334 for (int i=0, j=0; i<localsSize; i++, j++) { 1335 Assert.check(j < localCount); 1336 frame.locals[j] = locals[i]; 1337 if (width(locals[i]) > 1) i++; 1338 } 1339 1340 int stackCount = 0; 1341 for (int i=0; i<state.stacksize; i++) { 1342 if (state.stack[i] != null) { 1343 stackCount++; 1344 } 1345 } 1346 frame.stack = new Type[stackCount]; 1347 stackCount = 0; 1348 for (int i=0; i<state.stacksize; i++) { 1349 if (state.stack[i] != null) { 1350 frame.stack[stackCount++] = types.erasure(state.stack[i]); 1351 } 1352 } 1353 1354 if (stackMapTableBuffer == null) { 1355 stackMapTableBuffer = new StackMapTableFrame[20]; 1356 } else { 1357 stackMapTableBuffer = ArrayUtils.ensureCapacity( 1358 stackMapTableBuffer, 1359 stackMapBufferSize); 1360 } 1361 stackMapTableBuffer[stackMapBufferSize++] = 1362 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types); 1363 1364 frameBeforeLast = lastFrame; 1365 lastFrame = frame; 1366 } 1367 1368 StackMapFrame getInitialFrame() { 1369 StackMapFrame frame = new StackMapFrame(); 1370 List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes; 1371 int len = arg_types.length(); 1372 int count = 0; 1373 if (!meth.isStatic()) { 1374 Type thisType = meth.owner.type; 1375 frame.locals = new Type[len+1]; 1376 if (meth.isConstructor() && thisType != syms.objectType) { 1377 frame.locals[count++] = UninitializedType.uninitializedThis(thisType); 1378 } else { 1379 frame.locals[count++] = types.erasure(thisType); 1380 } 1381 } else { 1382 frame.locals = new Type[len]; 1383 } 1384 for (Type arg_type : arg_types) { 1385 frame.locals[count++] = types.erasure(arg_type); 1386 } 1387 frame.pc = -1; 1388 frame.stack = null; 1389 return frame; 1390 } 1391 1392 1393/************************************************************************** 1394 * Operations having to do with jumps 1395 *************************************************************************/ 1396 1397 /** A chain represents a list of unresolved jumps. Jump locations 1398 * are sorted in decreasing order. 1399 */ 1400 public static class Chain { 1401 1402 /** The position of the jump instruction. 1403 */ 1404 public final int pc; 1405 1406 /** The machine state after the jump instruction. 1407 * Invariant: all elements of a chain list have the same stacksize 1408 * and compatible stack and register contents. 1409 */ 1410 Code.State state; 1411 1412 /** The next jump in the list. 1413 */ 1414 public final Chain next; 1415 1416 /** Construct a chain from its jump position, stacksize, previous 1417 * chain, and machine state. 1418 */ 1419 public Chain(int pc, Chain next, Code.State state) { 1420 this.pc = pc; 1421 this.next = next; 1422 this.state = state; 1423 } 1424 } 1425 1426 /** Negate a branch opcode. 1427 */ 1428 public static int negate(int opcode) { 1429 if (opcode == if_acmp_null) return if_acmp_nonnull; 1430 else if (opcode == if_acmp_nonnull) return if_acmp_null; 1431 else return ((opcode + 1) ^ 1) - 1; 1432 } 1433 1434 /** Emit a jump instruction. 1435 * Return code pointer of instruction to be patched. 1436 */ 1437 public int emitJump(int opcode) { 1438 if (fatcode) { 1439 if (opcode == goto_ || opcode == jsr) { 1440 emitop4(opcode + goto_w - goto_, 0); 1441 } else { 1442 emitop2(negate(opcode), 8); 1443 emitop4(goto_w, 0); 1444 alive = true; 1445 pendingStackMap = needStackMap; 1446 } 1447 return cp - 5; 1448 } else { 1449 emitop2(opcode, 0); 1450 return cp - 3; 1451 } 1452 } 1453 1454 /** Emit a branch with given opcode; return its chain. 1455 * branch differs from jump in that jsr is treated as no-op. 1456 */ 1457 public Chain branch(int opcode) { 1458 Chain result = null; 1459 if (opcode == goto_) { 1460 result = pendingJumps; 1461 pendingJumps = null; 1462 } 1463 if (opcode != dontgoto && isAlive()) { 1464 result = new Chain(emitJump(opcode), 1465 result, 1466 state.dup()); 1467 fixedPc = fatcode; 1468 if (opcode == goto_) alive = false; 1469 } 1470 return result; 1471 } 1472 1473 /** Resolve chain to point to given target. 1474 */ 1475 public void resolve(Chain chain, int target) { 1476 boolean changed = false; 1477 State newState = state; 1478 for (; chain != null; chain = chain.next) { 1479 Assert.check(state != chain.state 1480 && (target > chain.pc || state.stacksize == 0)); 1481 if (target >= cp) { 1482 target = cp; 1483 } else if (get1(target) == goto_) { 1484 if (fatcode) target = target + get4(target + 1); 1485 else target = target + get2(target + 1); 1486 } 1487 if (get1(chain.pc) == goto_ && 1488 chain.pc + 3 == target && target == cp && !fixedPc) { 1489 // If goto the next instruction, the jump is not needed: 1490 // compact the code. 1491 if (varDebugInfo) { 1492 adjustAliveRanges(cp, -3); 1493 } 1494 cp = cp - 3; 1495 target = target - 3; 1496 if (chain.next == null) { 1497 // This is the only jump to the target. Exit the loop 1498 // without setting new state. The code is reachable 1499 // from the instruction before goto_. 1500 alive = true; 1501 break; 1502 } 1503 } else { 1504 if (fatcode) 1505 put4(chain.pc + 1, target - chain.pc); 1506 else if (target - chain.pc < Short.MIN_VALUE || 1507 target - chain.pc > Short.MAX_VALUE) 1508 fatcode = true; 1509 else 1510 put2(chain.pc + 1, target - chain.pc); 1511 Assert.check(!alive || 1512 chain.state.stacksize == newState.stacksize && 1513 chain.state.nlocks == newState.nlocks); 1514 } 1515 fixedPc = true; 1516 if (cp == target) { 1517 changed = true; 1518 if (debugCode) 1519 System.err.println("resolving chain state=" + chain.state); 1520 if (alive) { 1521 newState = chain.state.join(newState); 1522 } else { 1523 newState = chain.state; 1524 alive = true; 1525 } 1526 } 1527 } 1528 Assert.check(!changed || state != newState); 1529 if (state != newState) { 1530 setDefined(newState.defined); 1531 state = newState; 1532 pendingStackMap = needStackMap; 1533 } 1534 } 1535 1536 /** Resolve chain to point to current code pointer. 1537 */ 1538 public void resolve(Chain chain) { 1539 Assert.check( 1540 !alive || 1541 chain==null || 1542 state.stacksize == chain.state.stacksize && 1543 state.nlocks == chain.state.nlocks); 1544 pendingJumps = mergeChains(chain, pendingJumps); 1545 } 1546 1547 /** Resolve any pending jumps. 1548 */ 1549 public void resolvePending() { 1550 Chain x = pendingJumps; 1551 pendingJumps = null; 1552 resolve(x, cp); 1553 } 1554 1555 /** Merge the jumps in of two chains into one. 1556 */ 1557 public static Chain mergeChains(Chain chain1, Chain chain2) { 1558 // recursive merge sort 1559 if (chain2 == null) return chain1; 1560 if (chain1 == null) return chain2; 1561 Assert.check( 1562 chain1.state.stacksize == chain2.state.stacksize && 1563 chain1.state.nlocks == chain2.state.nlocks); 1564 if (chain1.pc < chain2.pc) 1565 return new Chain( 1566 chain2.pc, 1567 mergeChains(chain1, chain2.next), 1568 chain2.state); 1569 return new Chain( 1570 chain1.pc, 1571 mergeChains(chain1.next, chain2), 1572 chain1.state); 1573 } 1574 1575 1576/* ************************************************************************** 1577 * Catch clauses 1578 ****************************************************************************/ 1579 1580 /** Add a catch clause to code. 1581 */ 1582 public void addCatch(char startPc, char endPc, 1583 char handlerPc, char catchType) { 1584 catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType}); 1585 } 1586 1587 1588 public void compressCatchTable() { 1589 ListBuffer<char[]> compressedCatchInfo = new ListBuffer<>(); 1590 List<Integer> handlerPcs = List.nil(); 1591 for (char[] catchEntry : catchInfo) { 1592 handlerPcs = handlerPcs.prepend((int)catchEntry[2]); 1593 } 1594 for (char[] catchEntry : catchInfo) { 1595 int startpc = catchEntry[0]; 1596 int endpc = catchEntry[1]; 1597 if (startpc == endpc || 1598 (startpc == (endpc - 1) && 1599 handlerPcs.contains(startpc))) { 1600 continue; 1601 } else { 1602 compressedCatchInfo.append(catchEntry); 1603 } 1604 } 1605 catchInfo = compressedCatchInfo; 1606 } 1607 1608 1609/* ************************************************************************** 1610 * Line numbers 1611 ****************************************************************************/ 1612 1613 /** Add a line number entry. 1614 */ 1615 public void addLineNumber(char startPc, char lineNumber) { 1616 if (lineDebugInfo) { 1617 if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc) 1618 lineInfo = lineInfo.tail; 1619 if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber) 1620 lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber}); 1621 } 1622 } 1623 1624 /** Mark beginning of statement. 1625 */ 1626 public void statBegin(int pos) { 1627 if (pos != Position.NOPOS) { 1628 pendingStatPos = pos; 1629 } 1630 } 1631 1632 /** Force stat begin eagerly 1633 */ 1634 public void markStatBegin() { 1635 if (alive && lineDebugInfo) { 1636 int line = lineMap.getLineNumber(pendingStatPos); 1637 char cp1 = (char)cp; 1638 char line1 = (char)line; 1639 if (cp1 == cp && line1 == line) 1640 addLineNumber(cp1, line1); 1641 } 1642 pendingStatPos = Position.NOPOS; 1643 } 1644 1645 1646/* ************************************************************************** 1647 * Simulated VM machine state 1648 ****************************************************************************/ 1649 1650 class State implements Cloneable { 1651 /** The set of registers containing values. */ 1652 Bits defined; 1653 1654 /** The (types of the) contents of the machine stack. */ 1655 Type[] stack; 1656 1657 /** The first stack position currently unused. */ 1658 int stacksize; 1659 1660 /** The numbers of registers containing locked monitors. */ 1661 int[] locks; 1662 int nlocks; 1663 1664 State() { 1665 defined = new Bits(); 1666 stack = new Type[16]; 1667 } 1668 1669 State dup() { 1670 try { 1671 State state = (State)super.clone(); 1672 state.defined = new Bits(defined); 1673 state.stack = stack.clone(); 1674 if (locks != null) state.locks = locks.clone(); 1675 if (debugCode) { 1676 System.err.println("duping state " + this); 1677 dump(); 1678 } 1679 return state; 1680 } catch (CloneNotSupportedException ex) { 1681 throw new AssertionError(ex); 1682 } 1683 } 1684 1685 void lock(int register) { 1686 if (locks == null) { 1687 locks = new int[20]; 1688 } else { 1689 locks = ArrayUtils.ensureCapacity(locks, nlocks); 1690 } 1691 locks[nlocks] = register; 1692 nlocks++; 1693 } 1694 1695 void unlock(int register) { 1696 nlocks--; 1697 Assert.check(locks[nlocks] == register); 1698 locks[nlocks] = -1; 1699 } 1700 1701 void push(Type t) { 1702 if (debugCode) System.err.println(" pushing " + t); 1703 switch (t.getTag()) { 1704 case VOID: 1705 return; 1706 case BYTE: 1707 case CHAR: 1708 case SHORT: 1709 case BOOLEAN: 1710 t = syms.intType; 1711 break; 1712 default: 1713 break; 1714 } 1715 stack = ArrayUtils.ensureCapacity(stack, stacksize+2); 1716 stack[stacksize++] = t; 1717 switch (width(t)) { 1718 case 1: 1719 break; 1720 case 2: 1721 stack[stacksize++] = null; 1722 break; 1723 default: 1724 throw new AssertionError(t); 1725 } 1726 if (stacksize > max_stack) 1727 max_stack = stacksize; 1728 } 1729 1730 Type pop1() { 1731 if (debugCode) System.err.println(" popping " + 1); 1732 stacksize--; 1733 Type result = stack[stacksize]; 1734 stack[stacksize] = null; 1735 Assert.check(result != null && width(result) == 1); 1736 return result; 1737 } 1738 1739 Type peek() { 1740 return stack[stacksize-1]; 1741 } 1742 1743 Type pop2() { 1744 if (debugCode) System.err.println(" popping " + 2); 1745 stacksize -= 2; 1746 Type result = stack[stacksize]; 1747 stack[stacksize] = null; 1748 Assert.check(stack[stacksize+1] == null 1749 && result != null && width(result) == 2); 1750 return result; 1751 } 1752 1753 void pop(int n) { 1754 if (debugCode) System.err.println(" popping " + n); 1755 while (n > 0) { 1756 stack[--stacksize] = null; 1757 n--; 1758 } 1759 } 1760 1761 void pop(Type t) { 1762 pop(width(t)); 1763 } 1764 1765 /** Force the top of the stack to be treated as this supertype 1766 * of its current type. */ 1767 void forceStackTop(Type t) { 1768 if (!alive) return; 1769 switch (t.getTag()) { 1770 case CLASS: 1771 case ARRAY: 1772 int width = width(t); 1773 Type old = stack[stacksize-width]; 1774 Assert.check(types.isSubtype(types.erasure(old), 1775 types.erasure(t))); 1776 stack[stacksize-width] = t; 1777 break; 1778 default: 1779 } 1780 } 1781 1782 void markInitialized(UninitializedType old) { 1783 Type newtype = old.initializedType(); 1784 for (int i=0; i<stacksize; i++) { 1785 if (stack[i] == old) stack[i] = newtype; 1786 } 1787 for (int i=0; i<lvar.length; i++) { 1788 LocalVar lv = lvar[i]; 1789 if (lv != null && lv.sym.type == old) { 1790 VarSymbol sym = lv.sym; 1791 sym = sym.clone(sym.owner); 1792 sym.type = newtype; 1793 LocalVar newlv = lvar[i] = new LocalVar(sym); 1794 newlv.aliveRanges = lv.aliveRanges; 1795 } 1796 } 1797 } 1798 1799 State join(State other) { 1800 defined.andSet(other.defined); 1801 Assert.check(stacksize == other.stacksize 1802 && nlocks == other.nlocks); 1803 for (int i=0; i<stacksize; ) { 1804 Type t = stack[i]; 1805 Type tother = other.stack[i]; 1806 Type result = 1807 t==tother ? t : 1808 types.isSubtype(t, tother) ? tother : 1809 types.isSubtype(tother, t) ? t : 1810 error(); 1811 int w = width(result); 1812 stack[i] = result; 1813 if (w == 2) Assert.checkNull(stack[i+1]); 1814 i += w; 1815 } 1816 return this; 1817 } 1818 1819 Type error() { 1820 throw new AssertionError("inconsistent stack types at join point"); 1821 } 1822 1823 void dump() { 1824 dump(-1); 1825 } 1826 1827 void dump(int pc) { 1828 System.err.print("stackMap for " + meth.owner + "." + meth); 1829 if (pc == -1) 1830 System.out.println(); 1831 else 1832 System.out.println(" at " + pc); 1833 System.err.println(" stack (from bottom):"); 1834 for (int i=0; i<stacksize; i++) 1835 System.err.println(" " + i + ": " + stack[i]); 1836 1837 int lastLocal = 0; 1838 for (int i=max_locals-1; i>=0; i--) { 1839 if (defined.isMember(i)) { 1840 lastLocal = i; 1841 break; 1842 } 1843 } 1844 if (lastLocal >= 0) 1845 System.err.println(" locals:"); 1846 for (int i=0; i<=lastLocal; i++) { 1847 System.err.print(" " + i + ": "); 1848 if (defined.isMember(i)) { 1849 LocalVar var = lvar[i]; 1850 if (var == null) { 1851 System.err.println("(none)"); 1852 } else if (var.sym == null) 1853 System.err.println("UNKNOWN!"); 1854 else 1855 System.err.println("" + var.sym + " of type " + 1856 var.sym.erasure(types)); 1857 } else { 1858 System.err.println("undefined"); 1859 } 1860 } 1861 if (nlocks != 0) { 1862 System.err.print(" locks:"); 1863 for (int i=0; i<nlocks; i++) { 1864 System.err.print(" " + locks[i]); 1865 } 1866 System.err.println(); 1867 } 1868 } 1869 } 1870 1871 static final Type jsrReturnValue = new JCPrimitiveType(INT, null); 1872 1873 1874/* ************************************************************************** 1875 * Local variables 1876 ****************************************************************************/ 1877 1878 /** A live range of a local variable. */ 1879 static class LocalVar { 1880 final VarSymbol sym; 1881 final char reg; 1882 1883 class Range { 1884 char start_pc = Character.MAX_VALUE; 1885 char length = Character.MAX_VALUE; 1886 1887 Range() {} 1888 1889 Range(char start) { 1890 this.start_pc = start; 1891 } 1892 1893 Range(char start, char length) { 1894 this.start_pc = start; 1895 this.length = length; 1896 } 1897 1898 boolean closed() { 1899 return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE; 1900 } 1901 1902 @Override 1903 public String toString() { 1904 int currentStartPC = start_pc; 1905 int currentLength = length; 1906 return "startpc = " + currentStartPC + " length " + currentLength; 1907 } 1908 } 1909 1910 java.util.List<Range> aliveRanges = new java.util.ArrayList<>(); 1911 1912 LocalVar(VarSymbol v) { 1913 this.sym = v; 1914 this.reg = (char)v.adr; 1915 } 1916 public LocalVar dup() { 1917 return new LocalVar(sym); 1918 } 1919 1920 Range firstRange() { 1921 return aliveRanges.isEmpty() ? null : aliveRanges.get(0); 1922 } 1923 1924 Range lastRange() { 1925 return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1); 1926 } 1927 1928 void removeLastRange() { 1929 Range lastRange = lastRange(); 1930 if (lastRange != null) { 1931 aliveRanges.remove(lastRange); 1932 } 1933 } 1934 1935 @Override 1936 public String toString() { 1937 if (aliveRanges == null) { 1938 return "empty local var"; 1939 } 1940 StringBuilder sb = new StringBuilder().append(sym) 1941 .append(" in register ").append((int)reg).append(" \n"); 1942 for (Range r : aliveRanges) { 1943 sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc))) 1944 .append(" length=").append(Integer.toString(((int)r.length))) 1945 .append("\n"); 1946 } 1947 return sb.toString(); 1948 } 1949 1950 public void openRange(char start) { 1951 if (!hasOpenRange()) { 1952 aliveRanges.add(new Range(start)); 1953 } 1954 } 1955 1956 public void closeRange(char length) { 1957 if (isLastRangeInitialized() && length > 0) { 1958 Range range = lastRange(); 1959 if (range != null) { 1960 if (range.length == Character.MAX_VALUE) { 1961 range.length = length; 1962 } 1963 } 1964 } else { 1965 removeLastRange(); 1966 } 1967 } 1968 1969 public boolean hasOpenRange() { 1970 if (aliveRanges.isEmpty()) { 1971 return false; 1972 } 1973 return lastRange().length == Character.MAX_VALUE; 1974 } 1975 1976 public boolean isLastRangeInitialized() { 1977 if (aliveRanges.isEmpty()) { 1978 return false; 1979 } 1980 return lastRange().start_pc != Character.MAX_VALUE; 1981 } 1982 1983 public Range getWidestRange() { 1984 if (aliveRanges.isEmpty()) { 1985 return new Range(); 1986 } else { 1987 Range firstRange = firstRange(); 1988 Range lastRange = lastRange(); 1989 char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc)); 1990 return new Range(firstRange.start_pc, length); 1991 } 1992 } 1993 1994 } 1995 1996 /** Local variables, indexed by register. */ 1997 LocalVar[] lvar; 1998 1999 /** Add a new local variable. */ 2000 private void addLocalVar(VarSymbol v) { 2001 int adr = v.adr; 2002 lvar = ArrayUtils.ensureCapacity(lvar, adr+1); 2003 Assert.checkNull(lvar[adr]); 2004 if (pendingJumps != null) { 2005 resolvePending(); 2006 } 2007 lvar[adr] = new LocalVar(v); 2008 state.defined.excl(adr); 2009 } 2010 2011 2012 public void closeAliveRanges(JCTree tree) { 2013 closeAliveRanges(tree, cp); 2014 } 2015 2016 public void closeAliveRanges(JCTree tree, int closingCP) { 2017 List<VarSymbol> locals = lvtRanges.getVars(meth, tree); 2018 for (LocalVar localVar: lvar) { 2019 for (VarSymbol aliveLocal : locals) { 2020 if (localVar != null) { 2021 if (localVar.sym == aliveLocal && localVar.lastRange() != null) { 2022 char length = (char)(closingCP - localVar.lastRange().start_pc); 2023 if (length < Character.MAX_VALUE) { 2024 localVar.closeRange(length); 2025 } 2026 } 2027 } 2028 } 2029 } 2030 } 2031 2032 void adjustAliveRanges(int oldCP, int delta) { 2033 for (LocalVar localVar: lvar) { 2034 if (localVar != null) { 2035 for (LocalVar.Range range: localVar.aliveRanges) { 2036 if (range.closed() && range.start_pc + range.length >= oldCP) { 2037 range.length += delta; 2038 } 2039 } 2040 } 2041 } 2042 } 2043 2044 /** 2045 * Calculates the size of the LocalVariableTable. 2046 */ 2047 public int getLVTSize() { 2048 int result = varBufferSize; 2049 for (int i = 0; i < varBufferSize; i++) { 2050 LocalVar var = varBuffer[i]; 2051 result += var.aliveRanges.size() - 1; 2052 } 2053 return result; 2054 } 2055 2056 /** Set the current variable defined state. */ 2057 public void setDefined(Bits newDefined) { 2058 if (alive && newDefined != state.defined) { 2059 Bits diff = new Bits(state.defined).xorSet(newDefined); 2060 for (int adr = diff.nextBit(0); 2061 adr >= 0; 2062 adr = diff.nextBit(adr+1)) { 2063 if (adr >= nextreg) 2064 state.defined.excl(adr); 2065 else if (state.defined.isMember(adr)) 2066 setUndefined(adr); 2067 else 2068 setDefined(adr); 2069 } 2070 } 2071 } 2072 2073 /** Mark a register as being (possibly) defined. */ 2074 public void setDefined(int adr) { 2075 LocalVar v = lvar[adr]; 2076 if (v == null) { 2077 state.defined.excl(adr); 2078 } else { 2079 state.defined.incl(adr); 2080 if (cp < Character.MAX_VALUE) { 2081 v.openRange((char)cp); 2082 } 2083 } 2084 } 2085 2086 /** Mark a register as being undefined. */ 2087 public void setUndefined(int adr) { 2088 state.defined.excl(adr); 2089 if (adr < lvar.length && 2090 lvar[adr] != null && 2091 lvar[adr].isLastRangeInitialized()) { 2092 LocalVar v = lvar[adr]; 2093 char length = (char)(curCP() - v.lastRange().start_pc); 2094 if (length < Character.MAX_VALUE) { 2095 lvar[adr] = v.dup(); 2096 v.closeRange(length); 2097 putVar(v); 2098 } else { 2099 v.removeLastRange(); 2100 } 2101 } 2102 } 2103 2104 /** End the scope of a variable. */ 2105 private void endScope(int adr) { 2106 LocalVar v = lvar[adr]; 2107 if (v != null) { 2108 if (v.isLastRangeInitialized()) { 2109 char length = (char)(curCP() - v.lastRange().start_pc); 2110 if (length < Character.MAX_VALUE) { 2111 v.closeRange(length); 2112 putVar(v); 2113 fillLocalVarPosition(v); 2114 } 2115 } 2116 /** the call to curCP() can implicitly adjust the current cp, if so 2117 * the alive range of local variables may be modified. Thus we need 2118 * all of them. For this reason assigning null to the given address 2119 * should be the last action to do. 2120 */ 2121 lvar[adr] = null; 2122 } 2123 state.defined.excl(adr); 2124 } 2125 2126 private void fillLocalVarPosition(LocalVar lv) { 2127 if (lv == null || lv.sym == null || !lv.sym.hasTypeAnnotations()) 2128 return; 2129 for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) { 2130 TypeAnnotationPosition p = ta.position; 2131 LocalVar.Range widestRange = lv.getWidestRange(); 2132 p.lvarOffset = new int[] { (int)widestRange.start_pc }; 2133 p.lvarLength = new int[] { (int)widestRange.length }; 2134 p.lvarIndex = new int[] { (int)lv.reg }; 2135 p.isValidOffset = true; 2136 } 2137 } 2138 2139 // Method to be called after compressCatchTable to 2140 // fill in the exception table index for type 2141 // annotations on exception parameters. 2142 public void fillExceptionParameterPositions() { 2143 for (int i = 0; i < varBufferSize; ++i) { 2144 LocalVar lv = varBuffer[i]; 2145 if (lv == null || lv.sym == null 2146 || !lv.sym.hasTypeAnnotations() 2147 || !lv.sym.isExceptionParameter()) 2148 continue; 2149 2150 for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) { 2151 TypeAnnotationPosition p = ta.position; 2152 if (p.hasCatchType()) { 2153 final int idx = findExceptionIndex(p); 2154 if (idx == -1) 2155 Assert.error("Could not find exception index for type annotation " + 2156 ta + " on exception parameter"); 2157 p.setExceptionIndex(idx); 2158 } 2159 } 2160 } 2161 } 2162 2163 private int findExceptionIndex(TypeAnnotationPosition p) { 2164 final int catchType = p.getCatchType(); 2165 final int startPos = p.getStartPos(); 2166 final int len = catchInfo.length(); 2167 List<char[]> iter = catchInfo.toList(); 2168 for (int i = 0; i < len; ++i) { 2169 char[] catchEntry = iter.head; 2170 iter = iter.tail; 2171 int ct = catchEntry[3]; 2172 int sp = catchEntry[0]; 2173 if (catchType == ct && sp == startPos) { 2174 return i; 2175 } 2176 } 2177 return -1; 2178 } 2179 2180 /** Put a live variable range into the buffer to be output to the 2181 * class file. 2182 */ 2183 void putVar(LocalVar var) { 2184 // Keep local variables if 2185 // 1) we need them for debug information 2186 // 2) it is an exception type and it contains type annotations 2187 boolean keepLocalVariables = varDebugInfo || 2188 (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations()); 2189 if (!keepLocalVariables) return; 2190 if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return; 2191 if (varBuffer == null) 2192 varBuffer = new LocalVar[20]; 2193 else 2194 varBuffer = ArrayUtils.ensureCapacity(varBuffer, varBufferSize); 2195 varBuffer[varBufferSize++] = var; 2196 } 2197 2198 /** Previously live local variables, to be put into the variable table. */ 2199 LocalVar[] varBuffer; 2200 int varBufferSize; 2201 2202 /** Create a new local variable address and return it. 2203 */ 2204 private int newLocal(int typecode) { 2205 int reg = nextreg; 2206 int w = width(typecode); 2207 nextreg = reg + w; 2208 if (nextreg > max_locals) max_locals = nextreg; 2209 return reg; 2210 } 2211 2212 private int newLocal(Type type) { 2213 return newLocal(typecode(type)); 2214 } 2215 2216 public int newLocal(VarSymbol v) { 2217 int reg = v.adr = newLocal(v.erasure(types)); 2218 addLocalVar(v); 2219 return reg; 2220 } 2221 2222 /** Start a set of fresh registers. 2223 */ 2224 public void newRegSegment() { 2225 nextreg = max_locals; 2226 } 2227 2228 /** End scopes of all variables with registers ≥ first. 2229 */ 2230 public void endScopes(int first) { 2231 int prevNextReg = nextreg; 2232 nextreg = first; 2233 for (int i = nextreg; i < prevNextReg; i++) endScope(i); 2234 } 2235 2236/************************************************************************** 2237 * static tables 2238 *************************************************************************/ 2239 2240 public static String mnem(int opcode) { 2241 return Mneumonics.mnem[opcode]; 2242 } 2243 2244 private static class Mneumonics { 2245 private final static String[] mnem = new String[ByteCodeCount]; 2246 static { 2247 mnem[nop] = "nop"; 2248 mnem[aconst_null] = "aconst_null"; 2249 mnem[iconst_m1] = "iconst_m1"; 2250 mnem[iconst_0] = "iconst_0"; 2251 mnem[iconst_1] = "iconst_1"; 2252 mnem[iconst_2] = "iconst_2"; 2253 mnem[iconst_3] = "iconst_3"; 2254 mnem[iconst_4] = "iconst_4"; 2255 mnem[iconst_5] = "iconst_5"; 2256 mnem[lconst_0] = "lconst_0"; 2257 mnem[lconst_1] = "lconst_1"; 2258 mnem[fconst_0] = "fconst_0"; 2259 mnem[fconst_1] = "fconst_1"; 2260 mnem[fconst_2] = "fconst_2"; 2261 mnem[dconst_0] = "dconst_0"; 2262 mnem[dconst_1] = "dconst_1"; 2263 mnem[bipush] = "bipush"; 2264 mnem[sipush] = "sipush"; 2265 mnem[ldc1] = "ldc1"; 2266 mnem[ldc2] = "ldc2"; 2267 mnem[ldc2w] = "ldc2w"; 2268 mnem[iload] = "iload"; 2269 mnem[lload] = "lload"; 2270 mnem[fload] = "fload"; 2271 mnem[dload] = "dload"; 2272 mnem[aload] = "aload"; 2273 mnem[iload_0] = "iload_0"; 2274 mnem[lload_0] = "lload_0"; 2275 mnem[fload_0] = "fload_0"; 2276 mnem[dload_0] = "dload_0"; 2277 mnem[aload_0] = "aload_0"; 2278 mnem[iload_1] = "iload_1"; 2279 mnem[lload_1] = "lload_1"; 2280 mnem[fload_1] = "fload_1"; 2281 mnem[dload_1] = "dload_1"; 2282 mnem[aload_1] = "aload_1"; 2283 mnem[iload_2] = "iload_2"; 2284 mnem[lload_2] = "lload_2"; 2285 mnem[fload_2] = "fload_2"; 2286 mnem[dload_2] = "dload_2"; 2287 mnem[aload_2] = "aload_2"; 2288 mnem[iload_3] = "iload_3"; 2289 mnem[lload_3] = "lload_3"; 2290 mnem[fload_3] = "fload_3"; 2291 mnem[dload_3] = "dload_3"; 2292 mnem[aload_3] = "aload_3"; 2293 mnem[iaload] = "iaload"; 2294 mnem[laload] = "laload"; 2295 mnem[faload] = "faload"; 2296 mnem[daload] = "daload"; 2297 mnem[aaload] = "aaload"; 2298 mnem[baload] = "baload"; 2299 mnem[caload] = "caload"; 2300 mnem[saload] = "saload"; 2301 mnem[istore] = "istore"; 2302 mnem[lstore] = "lstore"; 2303 mnem[fstore] = "fstore"; 2304 mnem[dstore] = "dstore"; 2305 mnem[astore] = "astore"; 2306 mnem[istore_0] = "istore_0"; 2307 mnem[lstore_0] = "lstore_0"; 2308 mnem[fstore_0] = "fstore_0"; 2309 mnem[dstore_0] = "dstore_0"; 2310 mnem[astore_0] = "astore_0"; 2311 mnem[istore_1] = "istore_1"; 2312 mnem[lstore_1] = "lstore_1"; 2313 mnem[fstore_1] = "fstore_1"; 2314 mnem[dstore_1] = "dstore_1"; 2315 mnem[astore_1] = "astore_1"; 2316 mnem[istore_2] = "istore_2"; 2317 mnem[lstore_2] = "lstore_2"; 2318 mnem[fstore_2] = "fstore_2"; 2319 mnem[dstore_2] = "dstore_2"; 2320 mnem[astore_2] = "astore_2"; 2321 mnem[istore_3] = "istore_3"; 2322 mnem[lstore_3] = "lstore_3"; 2323 mnem[fstore_3] = "fstore_3"; 2324 mnem[dstore_3] = "dstore_3"; 2325 mnem[astore_3] = "astore_3"; 2326 mnem[iastore] = "iastore"; 2327 mnem[lastore] = "lastore"; 2328 mnem[fastore] = "fastore"; 2329 mnem[dastore] = "dastore"; 2330 mnem[aastore] = "aastore"; 2331 mnem[bastore] = "bastore"; 2332 mnem[castore] = "castore"; 2333 mnem[sastore] = "sastore"; 2334 mnem[pop] = "pop"; 2335 mnem[pop2] = "pop2"; 2336 mnem[dup] = "dup"; 2337 mnem[dup_x1] = "dup_x1"; 2338 mnem[dup_x2] = "dup_x2"; 2339 mnem[dup2] = "dup2"; 2340 mnem[dup2_x1] = "dup2_x1"; 2341 mnem[dup2_x2] = "dup2_x2"; 2342 mnem[swap] = "swap"; 2343 mnem[iadd] = "iadd"; 2344 mnem[ladd] = "ladd"; 2345 mnem[fadd] = "fadd"; 2346 mnem[dadd] = "dadd"; 2347 mnem[isub] = "isub"; 2348 mnem[lsub] = "lsub"; 2349 mnem[fsub] = "fsub"; 2350 mnem[dsub] = "dsub"; 2351 mnem[imul] = "imul"; 2352 mnem[lmul] = "lmul"; 2353 mnem[fmul] = "fmul"; 2354 mnem[dmul] = "dmul"; 2355 mnem[idiv] = "idiv"; 2356 mnem[ldiv] = "ldiv"; 2357 mnem[fdiv] = "fdiv"; 2358 mnem[ddiv] = "ddiv"; 2359 mnem[imod] = "imod"; 2360 mnem[lmod] = "lmod"; 2361 mnem[fmod] = "fmod"; 2362 mnem[dmod] = "dmod"; 2363 mnem[ineg] = "ineg"; 2364 mnem[lneg] = "lneg"; 2365 mnem[fneg] = "fneg"; 2366 mnem[dneg] = "dneg"; 2367 mnem[ishl] = "ishl"; 2368 mnem[lshl] = "lshl"; 2369 mnem[ishr] = "ishr"; 2370 mnem[lshr] = "lshr"; 2371 mnem[iushr] = "iushr"; 2372 mnem[lushr] = "lushr"; 2373 mnem[iand] = "iand"; 2374 mnem[land] = "land"; 2375 mnem[ior] = "ior"; 2376 mnem[lor] = "lor"; 2377 mnem[ixor] = "ixor"; 2378 mnem[lxor] = "lxor"; 2379 mnem[iinc] = "iinc"; 2380 mnem[i2l] = "i2l"; 2381 mnem[i2f] = "i2f"; 2382 mnem[i2d] = "i2d"; 2383 mnem[l2i] = "l2i"; 2384 mnem[l2f] = "l2f"; 2385 mnem[l2d] = "l2d"; 2386 mnem[f2i] = "f2i"; 2387 mnem[f2l] = "f2l"; 2388 mnem[f2d] = "f2d"; 2389 mnem[d2i] = "d2i"; 2390 mnem[d2l] = "d2l"; 2391 mnem[d2f] = "d2f"; 2392 mnem[int2byte] = "int2byte"; 2393 mnem[int2char] = "int2char"; 2394 mnem[int2short] = "int2short"; 2395 mnem[lcmp] = "lcmp"; 2396 mnem[fcmpl] = "fcmpl"; 2397 mnem[fcmpg] = "fcmpg"; 2398 mnem[dcmpl] = "dcmpl"; 2399 mnem[dcmpg] = "dcmpg"; 2400 mnem[ifeq] = "ifeq"; 2401 mnem[ifne] = "ifne"; 2402 mnem[iflt] = "iflt"; 2403 mnem[ifge] = "ifge"; 2404 mnem[ifgt] = "ifgt"; 2405 mnem[ifle] = "ifle"; 2406 mnem[if_icmpeq] = "if_icmpeq"; 2407 mnem[if_icmpne] = "if_icmpne"; 2408 mnem[if_icmplt] = "if_icmplt"; 2409 mnem[if_icmpge] = "if_icmpge"; 2410 mnem[if_icmpgt] = "if_icmpgt"; 2411 mnem[if_icmple] = "if_icmple"; 2412 mnem[if_acmpeq] = "if_acmpeq"; 2413 mnem[if_acmpne] = "if_acmpne"; 2414 mnem[goto_] = "goto_"; 2415 mnem[jsr] = "jsr"; 2416 mnem[ret] = "ret"; 2417 mnem[tableswitch] = "tableswitch"; 2418 mnem[lookupswitch] = "lookupswitch"; 2419 mnem[ireturn] = "ireturn"; 2420 mnem[lreturn] = "lreturn"; 2421 mnem[freturn] = "freturn"; 2422 mnem[dreturn] = "dreturn"; 2423 mnem[areturn] = "areturn"; 2424 mnem[return_] = "return_"; 2425 mnem[getstatic] = "getstatic"; 2426 mnem[putstatic] = "putstatic"; 2427 mnem[getfield] = "getfield"; 2428 mnem[putfield] = "putfield"; 2429 mnem[invokevirtual] = "invokevirtual"; 2430 mnem[invokespecial] = "invokespecial"; 2431 mnem[invokestatic] = "invokestatic"; 2432 mnem[invokeinterface] = "invokeinterface"; 2433 mnem[invokedynamic] = "invokedynamic"; 2434 mnem[new_] = "new_"; 2435 mnem[newarray] = "newarray"; 2436 mnem[anewarray] = "anewarray"; 2437 mnem[arraylength] = "arraylength"; 2438 mnem[athrow] = "athrow"; 2439 mnem[checkcast] = "checkcast"; 2440 mnem[instanceof_] = "instanceof_"; 2441 mnem[monitorenter] = "monitorenter"; 2442 mnem[monitorexit] = "monitorexit"; 2443 mnem[wide] = "wide"; 2444 mnem[multianewarray] = "multianewarray"; 2445 mnem[if_acmp_null] = "if_acmp_null"; 2446 mnem[if_acmp_nonnull] = "if_acmp_nonnull"; 2447 mnem[goto_w] = "goto_w"; 2448 mnem[jsr_w] = "jsr_w"; 2449 mnem[breakpoint] = "breakpoint"; 2450 } 2451 } 2452} 2453