001/*** 002 * ASM: a very small and fast Java bytecode manipulation framework 003 * Copyright (c) 2000-2011 INRIA, France Telecom 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions 008 * are met: 009 * 1. Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 2. Redistributions in binary form must reproduce the above copyright 012 * notice, this list of conditions and the following disclaimer in the 013 * documentation and/or other materials provided with the distribution. 014 * 3. Neither the name of the copyright holders nor the names of its 015 * contributors may be used to endorse or promote products derived from 016 * this software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 028 * THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030 031package io.ebean.enhance.asm.commons; 032 033import io.ebean.enhance.asm.Handle; 034import io.ebean.enhance.asm.Label; 035import io.ebean.enhance.asm.MethodVisitor; 036import io.ebean.enhance.asm.Opcodes; 037import io.ebean.enhance.asm.Type; 038 039/** 040 * A {@link MethodVisitor} providing a more detailed API to generate and 041 * transform instructions. 042 * 043 * @author Eric Bruneton 044 */ 045public class InstructionAdapter extends MethodVisitor { 046 047 public final static Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;"); 048 049 /** 050 * Creates a new {@link InstructionAdapter}. <i>Subclasses must not use this 051 * constructor</i>. Instead, they must use the 052 * {@link #InstructionAdapter(int, MethodVisitor)} version. 053 * 054 * @param mv 055 * the method visitor to which this adapter delegates calls. 056 * @throws IllegalStateException 057 * If a subclass calls this constructor. 058 */ 059 public InstructionAdapter(final MethodVisitor mv) { 060 this(Opcodes.ASM6, mv); 061 if (getClass() != InstructionAdapter.class) { 062 throw new IllegalStateException(); 063 } 064 } 065 066 /** 067 * Creates a new {@link InstructionAdapter}. 068 * 069 * @param api 070 * the ASM API version implemented by this visitor. Must be one 071 * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. 072 * @param mv 073 * the method visitor to which this adapter delegates calls. 074 */ 075 protected InstructionAdapter(final int api, final MethodVisitor mv) { 076 super(api, mv); 077 } 078 079 @Override 080 public void visitInsn(final int opcode) { 081 switch (opcode) { 082 case Opcodes.NOP: 083 nop(); 084 break; 085 case Opcodes.ACONST_NULL: 086 aconst(null); 087 break; 088 case Opcodes.ICONST_M1: 089 case Opcodes.ICONST_0: 090 case Opcodes.ICONST_1: 091 case Opcodes.ICONST_2: 092 case Opcodes.ICONST_3: 093 case Opcodes.ICONST_4: 094 case Opcodes.ICONST_5: 095 iconst(opcode - Opcodes.ICONST_0); 096 break; 097 case Opcodes.LCONST_0: 098 case Opcodes.LCONST_1: 099 lconst(opcode - Opcodes.LCONST_0); 100 break; 101 case Opcodes.FCONST_0: 102 case Opcodes.FCONST_1: 103 case Opcodes.FCONST_2: 104 fconst(opcode - Opcodes.FCONST_0); 105 break; 106 case Opcodes.DCONST_0: 107 case Opcodes.DCONST_1: 108 dconst(opcode - Opcodes.DCONST_0); 109 break; 110 case Opcodes.IALOAD: 111 aload(Type.INT_TYPE); 112 break; 113 case Opcodes.LALOAD: 114 aload(Type.LONG_TYPE); 115 break; 116 case Opcodes.FALOAD: 117 aload(Type.FLOAT_TYPE); 118 break; 119 case Opcodes.DALOAD: 120 aload(Type.DOUBLE_TYPE); 121 break; 122 case Opcodes.AALOAD: 123 aload(OBJECT_TYPE); 124 break; 125 case Opcodes.BALOAD: 126 aload(Type.BYTE_TYPE); 127 break; 128 case Opcodes.CALOAD: 129 aload(Type.CHAR_TYPE); 130 break; 131 case Opcodes.SALOAD: 132 aload(Type.SHORT_TYPE); 133 break; 134 case Opcodes.IASTORE: 135 astore(Type.INT_TYPE); 136 break; 137 case Opcodes.LASTORE: 138 astore(Type.LONG_TYPE); 139 break; 140 case Opcodes.FASTORE: 141 astore(Type.FLOAT_TYPE); 142 break; 143 case Opcodes.DASTORE: 144 astore(Type.DOUBLE_TYPE); 145 break; 146 case Opcodes.AASTORE: 147 astore(OBJECT_TYPE); 148 break; 149 case Opcodes.BASTORE: 150 astore(Type.BYTE_TYPE); 151 break; 152 case Opcodes.CASTORE: 153 astore(Type.CHAR_TYPE); 154 break; 155 case Opcodes.SASTORE: 156 astore(Type.SHORT_TYPE); 157 break; 158 case Opcodes.POP: 159 pop(); 160 break; 161 case Opcodes.POP2: 162 pop2(); 163 break; 164 case Opcodes.DUP: 165 dup(); 166 break; 167 case Opcodes.DUP_X1: 168 dupX1(); 169 break; 170 case Opcodes.DUP_X2: 171 dupX2(); 172 break; 173 case Opcodes.DUP2: 174 dup2(); 175 break; 176 case Opcodes.DUP2_X1: 177 dup2X1(); 178 break; 179 case Opcodes.DUP2_X2: 180 dup2X2(); 181 break; 182 case Opcodes.SWAP: 183 swap(); 184 break; 185 case Opcodes.IADD: 186 add(Type.INT_TYPE); 187 break; 188 case Opcodes.LADD: 189 add(Type.LONG_TYPE); 190 break; 191 case Opcodes.FADD: 192 add(Type.FLOAT_TYPE); 193 break; 194 case Opcodes.DADD: 195 add(Type.DOUBLE_TYPE); 196 break; 197 case Opcodes.ISUB: 198 sub(Type.INT_TYPE); 199 break; 200 case Opcodes.LSUB: 201 sub(Type.LONG_TYPE); 202 break; 203 case Opcodes.FSUB: 204 sub(Type.FLOAT_TYPE); 205 break; 206 case Opcodes.DSUB: 207 sub(Type.DOUBLE_TYPE); 208 break; 209 case Opcodes.IMUL: 210 mul(Type.INT_TYPE); 211 break; 212 case Opcodes.LMUL: 213 mul(Type.LONG_TYPE); 214 break; 215 case Opcodes.FMUL: 216 mul(Type.FLOAT_TYPE); 217 break; 218 case Opcodes.DMUL: 219 mul(Type.DOUBLE_TYPE); 220 break; 221 case Opcodes.IDIV: 222 div(Type.INT_TYPE); 223 break; 224 case Opcodes.LDIV: 225 div(Type.LONG_TYPE); 226 break; 227 case Opcodes.FDIV: 228 div(Type.FLOAT_TYPE); 229 break; 230 case Opcodes.DDIV: 231 div(Type.DOUBLE_TYPE); 232 break; 233 case Opcodes.IREM: 234 rem(Type.INT_TYPE); 235 break; 236 case Opcodes.LREM: 237 rem(Type.LONG_TYPE); 238 break; 239 case Opcodes.FREM: 240 rem(Type.FLOAT_TYPE); 241 break; 242 case Opcodes.DREM: 243 rem(Type.DOUBLE_TYPE); 244 break; 245 case Opcodes.INEG: 246 neg(Type.INT_TYPE); 247 break; 248 case Opcodes.LNEG: 249 neg(Type.LONG_TYPE); 250 break; 251 case Opcodes.FNEG: 252 neg(Type.FLOAT_TYPE); 253 break; 254 case Opcodes.DNEG: 255 neg(Type.DOUBLE_TYPE); 256 break; 257 case Opcodes.ISHL: 258 shl(Type.INT_TYPE); 259 break; 260 case Opcodes.LSHL: 261 shl(Type.LONG_TYPE); 262 break; 263 case Opcodes.ISHR: 264 shr(Type.INT_TYPE); 265 break; 266 case Opcodes.LSHR: 267 shr(Type.LONG_TYPE); 268 break; 269 case Opcodes.IUSHR: 270 ushr(Type.INT_TYPE); 271 break; 272 case Opcodes.LUSHR: 273 ushr(Type.LONG_TYPE); 274 break; 275 case Opcodes.IAND: 276 and(Type.INT_TYPE); 277 break; 278 case Opcodes.LAND: 279 and(Type.LONG_TYPE); 280 break; 281 case Opcodes.IOR: 282 or(Type.INT_TYPE); 283 break; 284 case Opcodes.LOR: 285 or(Type.LONG_TYPE); 286 break; 287 case Opcodes.IXOR: 288 xor(Type.INT_TYPE); 289 break; 290 case Opcodes.LXOR: 291 xor(Type.LONG_TYPE); 292 break; 293 case Opcodes.I2L: 294 cast(Type.INT_TYPE, Type.LONG_TYPE); 295 break; 296 case Opcodes.I2F: 297 cast(Type.INT_TYPE, Type.FLOAT_TYPE); 298 break; 299 case Opcodes.I2D: 300 cast(Type.INT_TYPE, Type.DOUBLE_TYPE); 301 break; 302 case Opcodes.L2I: 303 cast(Type.LONG_TYPE, Type.INT_TYPE); 304 break; 305 case Opcodes.L2F: 306 cast(Type.LONG_TYPE, Type.FLOAT_TYPE); 307 break; 308 case Opcodes.L2D: 309 cast(Type.LONG_TYPE, Type.DOUBLE_TYPE); 310 break; 311 case Opcodes.F2I: 312 cast(Type.FLOAT_TYPE, Type.INT_TYPE); 313 break; 314 case Opcodes.F2L: 315 cast(Type.FLOAT_TYPE, Type.LONG_TYPE); 316 break; 317 case Opcodes.F2D: 318 cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE); 319 break; 320 case Opcodes.D2I: 321 cast(Type.DOUBLE_TYPE, Type.INT_TYPE); 322 break; 323 case Opcodes.D2L: 324 cast(Type.DOUBLE_TYPE, Type.LONG_TYPE); 325 break; 326 case Opcodes.D2F: 327 cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE); 328 break; 329 case Opcodes.I2B: 330 cast(Type.INT_TYPE, Type.BYTE_TYPE); 331 break; 332 case Opcodes.I2C: 333 cast(Type.INT_TYPE, Type.CHAR_TYPE); 334 break; 335 case Opcodes.I2S: 336 cast(Type.INT_TYPE, Type.SHORT_TYPE); 337 break; 338 case Opcodes.LCMP: 339 lcmp(); 340 break; 341 case Opcodes.FCMPL: 342 cmpl(Type.FLOAT_TYPE); 343 break; 344 case Opcodes.FCMPG: 345 cmpg(Type.FLOAT_TYPE); 346 break; 347 case Opcodes.DCMPL: 348 cmpl(Type.DOUBLE_TYPE); 349 break; 350 case Opcodes.DCMPG: 351 cmpg(Type.DOUBLE_TYPE); 352 break; 353 case Opcodes.IRETURN: 354 areturn(Type.INT_TYPE); 355 break; 356 case Opcodes.LRETURN: 357 areturn(Type.LONG_TYPE); 358 break; 359 case Opcodes.FRETURN: 360 areturn(Type.FLOAT_TYPE); 361 break; 362 case Opcodes.DRETURN: 363 areturn(Type.DOUBLE_TYPE); 364 break; 365 case Opcodes.ARETURN: 366 areturn(OBJECT_TYPE); 367 break; 368 case Opcodes.RETURN: 369 areturn(Type.VOID_TYPE); 370 break; 371 case Opcodes.ARRAYLENGTH: 372 arraylength(); 373 break; 374 case Opcodes.ATHROW: 375 athrow(); 376 break; 377 case Opcodes.MONITORENTER: 378 monitorenter(); 379 break; 380 case Opcodes.MONITOREXIT: 381 monitorexit(); 382 break; 383 default: 384 throw new IllegalArgumentException(); 385 } 386 } 387 388 @Override 389 public void visitIntInsn(final int opcode, final int operand) { 390 switch (opcode) { 391 case Opcodes.BIPUSH: 392 iconst(operand); 393 break; 394 case Opcodes.SIPUSH: 395 iconst(operand); 396 break; 397 case Opcodes.NEWARRAY: 398 switch (operand) { 399 case Opcodes.T_BOOLEAN: 400 newarray(Type.BOOLEAN_TYPE); 401 break; 402 case Opcodes.T_CHAR: 403 newarray(Type.CHAR_TYPE); 404 break; 405 case Opcodes.T_BYTE: 406 newarray(Type.BYTE_TYPE); 407 break; 408 case Opcodes.T_SHORT: 409 newarray(Type.SHORT_TYPE); 410 break; 411 case Opcodes.T_INT: 412 newarray(Type.INT_TYPE); 413 break; 414 case Opcodes.T_FLOAT: 415 newarray(Type.FLOAT_TYPE); 416 break; 417 case Opcodes.T_LONG: 418 newarray(Type.LONG_TYPE); 419 break; 420 case Opcodes.T_DOUBLE: 421 newarray(Type.DOUBLE_TYPE); 422 break; 423 default: 424 throw new IllegalArgumentException(); 425 } 426 break; 427 default: 428 throw new IllegalArgumentException(); 429 } 430 } 431 432 @Override 433 public void visitVarInsn(final int opcode, final int var) { 434 switch (opcode) { 435 case Opcodes.ILOAD: 436 load(var, Type.INT_TYPE); 437 break; 438 case Opcodes.LLOAD: 439 load(var, Type.LONG_TYPE); 440 break; 441 case Opcodes.FLOAD: 442 load(var, Type.FLOAT_TYPE); 443 break; 444 case Opcodes.DLOAD: 445 load(var, Type.DOUBLE_TYPE); 446 break; 447 case Opcodes.ALOAD: 448 load(var, OBJECT_TYPE); 449 break; 450 case Opcodes.ISTORE: 451 store(var, Type.INT_TYPE); 452 break; 453 case Opcodes.LSTORE: 454 store(var, Type.LONG_TYPE); 455 break; 456 case Opcodes.FSTORE: 457 store(var, Type.FLOAT_TYPE); 458 break; 459 case Opcodes.DSTORE: 460 store(var, Type.DOUBLE_TYPE); 461 break; 462 case Opcodes.ASTORE: 463 store(var, OBJECT_TYPE); 464 break; 465 case Opcodes.RET: 466 ret(var); 467 break; 468 default: 469 throw new IllegalArgumentException(); 470 } 471 } 472 473 @Override 474 public void visitTypeInsn(final int opcode, final String type) { 475 Type t = Type.getObjectType(type); 476 switch (opcode) { 477 case Opcodes.NEW: 478 anew(t); 479 break; 480 case Opcodes.ANEWARRAY: 481 newarray(t); 482 break; 483 case Opcodes.CHECKCAST: 484 checkcast(t); 485 break; 486 case Opcodes.INSTANCEOF: 487 instanceOf(t); 488 break; 489 default: 490 throw new IllegalArgumentException(); 491 } 492 } 493 494 @Override 495 public void visitFieldInsn(final int opcode, final String owner, 496 final String name, final String desc) { 497 switch (opcode) { 498 case Opcodes.GETSTATIC: 499 getstatic(owner, name, desc); 500 break; 501 case Opcodes.PUTSTATIC: 502 putstatic(owner, name, desc); 503 break; 504 case Opcodes.GETFIELD: 505 getfield(owner, name, desc); 506 break; 507 case Opcodes.PUTFIELD: 508 putfield(owner, name, desc); 509 break; 510 default: 511 throw new IllegalArgumentException(); 512 } 513 } 514 515 @Deprecated 516 @Override 517 public void visitMethodInsn(final int opcode, final String owner, 518 final String name, final String desc) { 519 if (api >= Opcodes.ASM5) { 520 super.visitMethodInsn(opcode, owner, name, desc); 521 return; 522 } 523 doVisitMethodInsn(opcode, owner, name, desc, 524 opcode == Opcodes.INVOKEINTERFACE); 525 } 526 527 @Override 528 public void visitMethodInsn(final int opcode, final String owner, 529 final String name, final String desc, final boolean itf) { 530 if (api < Opcodes.ASM5) { 531 super.visitMethodInsn(opcode, owner, name, desc, itf); 532 return; 533 } 534 doVisitMethodInsn(opcode, owner, name, desc, itf); 535 } 536 537 private void doVisitMethodInsn(int opcode, final String owner, 538 final String name, final String desc, final boolean itf) { 539 switch (opcode) { 540 case Opcodes.INVOKESPECIAL: 541 invokespecial(owner, name, desc, itf); 542 break; 543 case Opcodes.INVOKEVIRTUAL: 544 invokevirtual(owner, name, desc, itf); 545 break; 546 case Opcodes.INVOKESTATIC: 547 invokestatic(owner, name, desc, itf); 548 break; 549 case Opcodes.INVOKEINTERFACE: 550 invokeinterface(owner, name, desc); 551 break; 552 default: 553 throw new IllegalArgumentException(); 554 } 555 } 556 557 @Override 558 public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, 559 Object... bsmArgs) { 560 invokedynamic(name, desc, bsm, bsmArgs); 561 } 562 563 @Override 564 public void visitJumpInsn(final int opcode, final Label label) { 565 switch (opcode) { 566 case Opcodes.IFEQ: 567 ifeq(label); 568 break; 569 case Opcodes.IFNE: 570 ifne(label); 571 break; 572 case Opcodes.IFLT: 573 iflt(label); 574 break; 575 case Opcodes.IFGE: 576 ifge(label); 577 break; 578 case Opcodes.IFGT: 579 ifgt(label); 580 break; 581 case Opcodes.IFLE: 582 ifle(label); 583 break; 584 case Opcodes.IF_ICMPEQ: 585 ificmpeq(label); 586 break; 587 case Opcodes.IF_ICMPNE: 588 ificmpne(label); 589 break; 590 case Opcodes.IF_ICMPLT: 591 ificmplt(label); 592 break; 593 case Opcodes.IF_ICMPGE: 594 ificmpge(label); 595 break; 596 case Opcodes.IF_ICMPGT: 597 ificmpgt(label); 598 break; 599 case Opcodes.IF_ICMPLE: 600 ificmple(label); 601 break; 602 case Opcodes.IF_ACMPEQ: 603 ifacmpeq(label); 604 break; 605 case Opcodes.IF_ACMPNE: 606 ifacmpne(label); 607 break; 608 case Opcodes.GOTO: 609 goTo(label); 610 break; 611 case Opcodes.JSR: 612 jsr(label); 613 break; 614 case Opcodes.IFNULL: 615 ifnull(label); 616 break; 617 case Opcodes.IFNONNULL: 618 ifnonnull(label); 619 break; 620 default: 621 throw new IllegalArgumentException(); 622 } 623 } 624 625 @Override 626 public void visitLabel(final Label label) { 627 mark(label); 628 } 629 630 @Override 631 public void visitLdcInsn(final Object cst) { 632 if (cst instanceof Integer) { 633 int val = ((Integer) cst).intValue(); 634 iconst(val); 635 } else if (cst instanceof Byte) { 636 int val = ((Byte) cst).intValue(); 637 iconst(val); 638 } else if (cst instanceof Character) { 639 int val = ((Character) cst).charValue(); 640 iconst(val); 641 } else if (cst instanceof Short) { 642 int val = ((Short) cst).intValue(); 643 iconst(val); 644 } else if (cst instanceof Boolean) { 645 int val = ((Boolean) cst).booleanValue() ? 1 : 0; 646 iconst(val); 647 } else if (cst instanceof Float) { 648 float val = ((Float) cst).floatValue(); 649 fconst(val); 650 } else if (cst instanceof Long) { 651 long val = ((Long) cst).longValue(); 652 lconst(val); 653 } else if (cst instanceof Double) { 654 double val = ((Double) cst).doubleValue(); 655 dconst(val); 656 } else if (cst instanceof String) { 657 aconst(cst); 658 } else if (cst instanceof Type) { 659 tconst((Type) cst); 660 } else if (cst instanceof Handle) { 661 hconst((Handle) cst); 662 } else { 663 throw new IllegalArgumentException(); 664 } 665 } 666 667 @Override 668 public void visitIincInsn(final int var, final int increment) { 669 iinc(var, increment); 670 } 671 672 @Override 673 public void visitTableSwitchInsn(final int min, final int max, 674 final Label dflt, final Label... labels) { 675 tableswitch(min, max, dflt, labels); 676 } 677 678 @Override 679 public void visitLookupSwitchInsn(final Label dflt, final int[] keys, 680 final Label[] labels) { 681 lookupswitch(dflt, keys, labels); 682 } 683 684 @Override 685 public void visitMultiANewArrayInsn(final String desc, final int dims) { 686 multianewarray(desc, dims); 687 } 688 689 // ----------------------------------------------------------------------- 690 691 public void nop() { 692 mv.visitInsn(Opcodes.NOP); 693 } 694 695 public void aconst(final Object cst) { 696 if (cst == null) { 697 mv.visitInsn(Opcodes.ACONST_NULL); 698 } else { 699 mv.visitLdcInsn(cst); 700 } 701 } 702 703 public void iconst(final int cst) { 704 if (cst >= -1 && cst <= 5) { 705 mv.visitInsn(Opcodes.ICONST_0 + cst); 706 } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) { 707 mv.visitIntInsn(Opcodes.BIPUSH, cst); 708 } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) { 709 mv.visitIntInsn(Opcodes.SIPUSH, cst); 710 } else { 711 mv.visitLdcInsn(cst); 712 } 713 } 714 715 public void lconst(final long cst) { 716 if (cst == 0L || cst == 1L) { 717 mv.visitInsn(Opcodes.LCONST_0 + (int) cst); 718 } else { 719 mv.visitLdcInsn(cst); 720 } 721 } 722 723 public void fconst(final float cst) { 724 int bits = Float.floatToIntBits(cst); 725 if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { // 0..2 726 mv.visitInsn(Opcodes.FCONST_0 + (int) cst); 727 } else { 728 mv.visitLdcInsn(cst); 729 } 730 } 731 732 public void dconst(final double cst) { 733 long bits = Double.doubleToLongBits(cst); 734 if (bits == 0L || bits == 0x3ff0000000000000L) { // +0.0d and 1.0d 735 mv.visitInsn(Opcodes.DCONST_0 + (int) cst); 736 } else { 737 mv.visitLdcInsn(cst); 738 } 739 } 740 741 public void tconst(final Type type) { 742 mv.visitLdcInsn(type); 743 } 744 745 public void hconst(final Handle handle) { 746 mv.visitLdcInsn(handle); 747 } 748 749 public void load(final int var, final Type type) { 750 mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), var); 751 } 752 753 public void aload(final Type type) { 754 mv.visitInsn(type.getOpcode(Opcodes.IALOAD)); 755 } 756 757 public void store(final int var, final Type type) { 758 mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), var); 759 } 760 761 public void astore(final Type type) { 762 mv.visitInsn(type.getOpcode(Opcodes.IASTORE)); 763 } 764 765 public void pop() { 766 mv.visitInsn(Opcodes.POP); 767 } 768 769 public void pop2() { 770 mv.visitInsn(Opcodes.POP2); 771 } 772 773 public void dup() { 774 mv.visitInsn(Opcodes.DUP); 775 } 776 777 public void dup2() { 778 mv.visitInsn(Opcodes.DUP2); 779 } 780 781 public void dupX1() { 782 mv.visitInsn(Opcodes.DUP_X1); 783 } 784 785 public void dupX2() { 786 mv.visitInsn(Opcodes.DUP_X2); 787 } 788 789 public void dup2X1() { 790 mv.visitInsn(Opcodes.DUP2_X1); 791 } 792 793 public void dup2X2() { 794 mv.visitInsn(Opcodes.DUP2_X2); 795 } 796 797 public void swap() { 798 mv.visitInsn(Opcodes.SWAP); 799 } 800 801 public void add(final Type type) { 802 mv.visitInsn(type.getOpcode(Opcodes.IADD)); 803 } 804 805 public void sub(final Type type) { 806 mv.visitInsn(type.getOpcode(Opcodes.ISUB)); 807 } 808 809 public void mul(final Type type) { 810 mv.visitInsn(type.getOpcode(Opcodes.IMUL)); 811 } 812 813 public void div(final Type type) { 814 mv.visitInsn(type.getOpcode(Opcodes.IDIV)); 815 } 816 817 public void rem(final Type type) { 818 mv.visitInsn(type.getOpcode(Opcodes.IREM)); 819 } 820 821 public void neg(final Type type) { 822 mv.visitInsn(type.getOpcode(Opcodes.INEG)); 823 } 824 825 public void shl(final Type type) { 826 mv.visitInsn(type.getOpcode(Opcodes.ISHL)); 827 } 828 829 public void shr(final Type type) { 830 mv.visitInsn(type.getOpcode(Opcodes.ISHR)); 831 } 832 833 public void ushr(final Type type) { 834 mv.visitInsn(type.getOpcode(Opcodes.IUSHR)); 835 } 836 837 public void and(final Type type) { 838 mv.visitInsn(type.getOpcode(Opcodes.IAND)); 839 } 840 841 public void or(final Type type) { 842 mv.visitInsn(type.getOpcode(Opcodes.IOR)); 843 } 844 845 public void xor(final Type type) { 846 mv.visitInsn(type.getOpcode(Opcodes.IXOR)); 847 } 848 849 public void iinc(final int var, final int increment) { 850 mv.visitIincInsn(var, increment); 851 } 852 853 public void cast(final Type from, final Type to) { 854 if (from != to) { 855 if (from == Type.DOUBLE_TYPE) { 856 if (to == Type.FLOAT_TYPE) { 857 mv.visitInsn(Opcodes.D2F); 858 } else if (to == Type.LONG_TYPE) { 859 mv.visitInsn(Opcodes.D2L); 860 } else { 861 mv.visitInsn(Opcodes.D2I); 862 cast(Type.INT_TYPE, to); 863 } 864 } else if (from == Type.FLOAT_TYPE) { 865 if (to == Type.DOUBLE_TYPE) { 866 mv.visitInsn(Opcodes.F2D); 867 } else if (to == Type.LONG_TYPE) { 868 mv.visitInsn(Opcodes.F2L); 869 } else { 870 mv.visitInsn(Opcodes.F2I); 871 cast(Type.INT_TYPE, to); 872 } 873 } else if (from == Type.LONG_TYPE) { 874 if (to == Type.DOUBLE_TYPE) { 875 mv.visitInsn(Opcodes.L2D); 876 } else if (to == Type.FLOAT_TYPE) { 877 mv.visitInsn(Opcodes.L2F); 878 } else { 879 mv.visitInsn(Opcodes.L2I); 880 cast(Type.INT_TYPE, to); 881 } 882 } else { 883 if (to == Type.BYTE_TYPE) { 884 mv.visitInsn(Opcodes.I2B); 885 } else if (to == Type.CHAR_TYPE) { 886 mv.visitInsn(Opcodes.I2C); 887 } else if (to == Type.DOUBLE_TYPE) { 888 mv.visitInsn(Opcodes.I2D); 889 } else if (to == Type.FLOAT_TYPE) { 890 mv.visitInsn(Opcodes.I2F); 891 } else if (to == Type.LONG_TYPE) { 892 mv.visitInsn(Opcodes.I2L); 893 } else if (to == Type.SHORT_TYPE) { 894 mv.visitInsn(Opcodes.I2S); 895 } 896 } 897 } 898 } 899 900 public void lcmp() { 901 mv.visitInsn(Opcodes.LCMP); 902 } 903 904 public void cmpl(final Type type) { 905 mv.visitInsn(type == Type.FLOAT_TYPE ? Opcodes.FCMPL : Opcodes.DCMPL); 906 } 907 908 public void cmpg(final Type type) { 909 mv.visitInsn(type == Type.FLOAT_TYPE ? Opcodes.FCMPG : Opcodes.DCMPG); 910 } 911 912 public void ifeq(final Label label) { 913 mv.visitJumpInsn(Opcodes.IFEQ, label); 914 } 915 916 public void ifne(final Label label) { 917 mv.visitJumpInsn(Opcodes.IFNE, label); 918 } 919 920 public void iflt(final Label label) { 921 mv.visitJumpInsn(Opcodes.IFLT, label); 922 } 923 924 public void ifge(final Label label) { 925 mv.visitJumpInsn(Opcodes.IFGE, label); 926 } 927 928 public void ifgt(final Label label) { 929 mv.visitJumpInsn(Opcodes.IFGT, label); 930 } 931 932 public void ifle(final Label label) { 933 mv.visitJumpInsn(Opcodes.IFLE, label); 934 } 935 936 public void ificmpeq(final Label label) { 937 mv.visitJumpInsn(Opcodes.IF_ICMPEQ, label); 938 } 939 940 public void ificmpne(final Label label) { 941 mv.visitJumpInsn(Opcodes.IF_ICMPNE, label); 942 } 943 944 public void ificmplt(final Label label) { 945 mv.visitJumpInsn(Opcodes.IF_ICMPLT, label); 946 } 947 948 public void ificmpge(final Label label) { 949 mv.visitJumpInsn(Opcodes.IF_ICMPGE, label); 950 } 951 952 public void ificmpgt(final Label label) { 953 mv.visitJumpInsn(Opcodes.IF_ICMPGT, label); 954 } 955 956 public void ificmple(final Label label) { 957 mv.visitJumpInsn(Opcodes.IF_ICMPLE, label); 958 } 959 960 public void ifacmpeq(final Label label) { 961 mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label); 962 } 963 964 public void ifacmpne(final Label label) { 965 mv.visitJumpInsn(Opcodes.IF_ACMPNE, label); 966 } 967 968 public void goTo(final Label label) { 969 mv.visitJumpInsn(Opcodes.GOTO, label); 970 } 971 972 public void jsr(final Label label) { 973 mv.visitJumpInsn(Opcodes.JSR, label); 974 } 975 976 public void ret(final int var) { 977 mv.visitVarInsn(Opcodes.RET, var); 978 } 979 980 public void tableswitch(final int min, final int max, final Label dflt, 981 final Label... labels) { 982 mv.visitTableSwitchInsn(min, max, dflt, labels); 983 } 984 985 public void lookupswitch(final Label dflt, final int[] keys, 986 final Label[] labels) { 987 mv.visitLookupSwitchInsn(dflt, keys, labels); 988 } 989 990 public void areturn(final Type t) { 991 mv.visitInsn(t.getOpcode(Opcodes.IRETURN)); 992 } 993 994 public void getstatic(final String owner, final String name, 995 final String desc) { 996 mv.visitFieldInsn(Opcodes.GETSTATIC, owner, name, desc); 997 } 998 999 public void putstatic(final String owner, final String name, 1000 final String desc) { 1001 mv.visitFieldInsn(Opcodes.PUTSTATIC, owner, name, desc); 1002 } 1003 1004 public void getfield(final String owner, final String name, 1005 final String desc) { 1006 mv.visitFieldInsn(Opcodes.GETFIELD, owner, name, desc); 1007 } 1008 1009 public void putfield(final String owner, final String name, 1010 final String desc) { 1011 mv.visitFieldInsn(Opcodes.PUTFIELD, owner, name, desc); 1012 } 1013 1014 @Deprecated 1015 public void invokevirtual(final String owner, final String name, 1016 final String desc) { 1017 if (api >= Opcodes.ASM5) { 1018 invokevirtual(owner, name, desc, false); 1019 return; 1020 } 1021 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc); 1022 } 1023 1024 public void invokevirtual(final String owner, final String name, 1025 final String desc, final boolean itf) { 1026 if (api < Opcodes.ASM5) { 1027 if (itf) { 1028 throw new IllegalArgumentException( 1029 "INVOKEVIRTUAL on interfaces require ASM 5"); 1030 } 1031 invokevirtual(owner, name, desc); 1032 return; 1033 } 1034 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc, itf); 1035 } 1036 1037 @Deprecated 1038 public void invokespecial(final String owner, final String name, 1039 final String desc) { 1040 if (api >= Opcodes.ASM5) { 1041 invokespecial(owner, name, desc, false); 1042 return; 1043 } 1044 mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, desc, false); 1045 } 1046 1047 public void invokespecial(final String owner, final String name, 1048 final String desc, final boolean itf) { 1049 if (api < Opcodes.ASM5) { 1050 if (itf) { 1051 throw new IllegalArgumentException( 1052 "INVOKESPECIAL on interfaces require ASM 5"); 1053 } 1054 invokespecial(owner, name, desc); 1055 return; 1056 } 1057 mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, desc, itf); 1058 } 1059 1060 @Deprecated 1061 public void invokestatic(final String owner, final String name, 1062 final String desc) { 1063 if (api >= Opcodes.ASM5) { 1064 invokestatic(owner, name, desc, false); 1065 return; 1066 } 1067 mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc, false); 1068 } 1069 1070 public void invokestatic(final String owner, final String name, 1071 final String desc, final boolean itf) { 1072 if (api < Opcodes.ASM5) { 1073 if (itf) { 1074 throw new IllegalArgumentException( 1075 "INVOKESTATIC on interfaces require ASM 5"); 1076 } 1077 invokestatic(owner, name, desc); 1078 return; 1079 } 1080 mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc, itf); 1081 } 1082 1083 public void invokeinterface(final String owner, final String name, 1084 final String desc) { 1085 mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, owner, name, desc, true); 1086 } 1087 1088 public void invokedynamic(String name, String desc, Handle bsm, 1089 Object[] bsmArgs) { 1090 mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); 1091 } 1092 1093 public void anew(final Type type) { 1094 mv.visitTypeInsn(Opcodes.NEW, type.getInternalName()); 1095 } 1096 1097 public void newarray(final Type type) { 1098 int typ; 1099 switch (type.getSort()) { 1100 case Type.BOOLEAN: 1101 typ = Opcodes.T_BOOLEAN; 1102 break; 1103 case Type.CHAR: 1104 typ = Opcodes.T_CHAR; 1105 break; 1106 case Type.BYTE: 1107 typ = Opcodes.T_BYTE; 1108 break; 1109 case Type.SHORT: 1110 typ = Opcodes.T_SHORT; 1111 break; 1112 case Type.INT: 1113 typ = Opcodes.T_INT; 1114 break; 1115 case Type.FLOAT: 1116 typ = Opcodes.T_FLOAT; 1117 break; 1118 case Type.LONG: 1119 typ = Opcodes.T_LONG; 1120 break; 1121 case Type.DOUBLE: 1122 typ = Opcodes.T_DOUBLE; 1123 break; 1124 default: 1125 mv.visitTypeInsn(Opcodes.ANEWARRAY, type.getInternalName()); 1126 return; 1127 } 1128 mv.visitIntInsn(Opcodes.NEWARRAY, typ); 1129 } 1130 1131 public void arraylength() { 1132 mv.visitInsn(Opcodes.ARRAYLENGTH); 1133 } 1134 1135 public void athrow() { 1136 mv.visitInsn(Opcodes.ATHROW); 1137 } 1138 1139 public void checkcast(final Type type) { 1140 mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName()); 1141 } 1142 1143 public void instanceOf(final Type type) { 1144 mv.visitTypeInsn(Opcodes.INSTANCEOF, type.getInternalName()); 1145 } 1146 1147 public void monitorenter() { 1148 mv.visitInsn(Opcodes.MONITORENTER); 1149 } 1150 1151 public void monitorexit() { 1152 mv.visitInsn(Opcodes.MONITOREXIT); 1153 } 1154 1155 public void multianewarray(final String desc, final int dims) { 1156 mv.visitMultiANewArrayInsn(desc, dims); 1157 } 1158 1159 public void ifnull(final Label label) { 1160 mv.visitJumpInsn(Opcodes.IFNULL, label); 1161 } 1162 1163 public void ifnonnull(final Label label) { 1164 mv.visitJumpInsn(Opcodes.IFNONNULL, label); 1165 } 1166 1167 public void mark(final Label label) { 1168 mv.visitLabel(label); 1169 } 1170}