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