1 30 package org.objectweb.asm.commons; 31 32 import org.objectweb.asm.AnnotationVisitor; 33 import org.objectweb.asm.MethodVisitor; 34 import org.objectweb.asm.Label; 35 import org.objectweb.asm.Opcodes; 36 import org.objectweb.asm.Type; 37 import org.objectweb.asm.util.ASMifierAbstractVisitor; 38 import org.objectweb.asm.util.ASMifierAnnotationVisitor; 39 40 import java.util.ArrayList ; 41 import java.util.HashMap ; 42 import java.util.List ; 43 import java.util.Map ; 44 45 52 public class GASMifierMethodVisitor extends ASMifierAbstractVisitor implements 53 MethodVisitor, 54 Opcodes 55 { 56 57 int access; 58 59 Type[] argumentTypes; 60 61 int firstLocal; 62 63 Map locals; 64 65 List localTypes; 66 67 int lastOpcode = -1; 68 69 HashMap labelNames; 70 71 public GASMifierMethodVisitor(int access, String desc) { 72 super("mg"); 73 this.access = access; 74 this.labelNames = new HashMap (); 75 this.argumentTypes = Type.getArgumentTypes(desc); 76 int nextLocal = ((Opcodes.ACC_STATIC & access) != 0) ? 0 : 1; 77 for (int i = 0; i < argumentTypes.length; i++) { 78 nextLocal += argumentTypes[i].getSize(); 79 } 80 this.firstLocal = nextLocal; 81 this.locals = new HashMap (); 82 this.localTypes = new ArrayList (); 83 } 84 85 public AnnotationVisitor visitAnnotationDefault() { 86 buf.setLength(0); 87 buf.append("{\n").append("av0 = mg.visitAnnotationDefault();\n"); 88 text.add(buf.toString()); 89 ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); 90 text.add(av.getText()); 91 text.add("}\n"); 92 return av; 93 } 94 95 public AnnotationVisitor visitParameterAnnotation( 96 final int parameter, 97 final String desc, 98 final boolean visible) 99 { 100 buf.setLength(0); 101 buf.append("{\n") 102 .append("av0 = mg.visitParameterAnnotation(") 103 .append(parameter) 104 .append(", \""); 105 buf.append(desc); 106 buf.append("\", ").append(visible).append(");\n"); 107 text.add(buf.toString()); 108 ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); 109 text.add(av.getText()); 110 text.add("}\n"); 111 return av; 112 } 113 114 public void visitCode() { 115 116 } 117 118 public void visitInsn(final int opcode) { 119 buf.setLength(0); 120 switch (opcode) { 121 case IRETURN: 122 case LRETURN: 123 case FRETURN: 124 case DRETURN: 125 case ARETURN: 126 case RETURN: 127 buf.append("mg.returnValue();\n"); 128 break; 129 case NOP: 130 break; 131 case ACONST_NULL: 132 buf.append("mg.push((String)null);\n"); 133 break; 134 case ICONST_M1: 135 case ICONST_0: 136 case ICONST_1: 137 case ICONST_2: 138 case ICONST_3: 139 case ICONST_4: 140 case ICONST_5: 141 buf.append("mg.push(").append(opcode - ICONST_0).append(");\n"); 142 break; 143 case LCONST_0: 144 case LCONST_1: 145 buf.append("mg.push(") 146 .append(opcode - LCONST_0) 147 .append("L);\n"); 148 break; 149 case FCONST_0: 150 case FCONST_1: 151 case FCONST_2: 152 buf.append("mg.push(") 153 .append(opcode - FCONST_0) 154 .append("f);\n"); 155 break; 156 case DCONST_0: 157 case DCONST_1: 158 buf.append("mg.push(") 159 .append(opcode - DCONST_0) 160 .append("d);\n"); 161 break; 162 case POP: 163 buf.append("mg.pop();\n"); 164 break; 165 case POP2: 166 buf.append("mg.pop2();\n"); 167 break; 168 case DUP: 169 buf.append("mg.dup();\n"); 170 break; 171 case DUP_X1: 172 buf.append("mg.dupX1();\n"); 173 break; 174 case DUP_X2: 175 buf.append("mg.dupX2();\n"); 176 break; 177 case DUP2: 178 buf.append("mg.dup2();\n"); 179 break; 180 case DUP2_X1: 181 buf.append("mg.dup2X1();\n"); 182 break; 183 case DUP2_X2: 184 buf.append("mg.dup2X2();\n"); 185 break; 186 case SWAP: 187 buf.append("mg.swap();\n"); 188 break; 189 case MONITORENTER: 190 buf.append("mg.monitorEnter();\n"); 191 break; 192 case MONITOREXIT: 193 buf.append("mg.monitorExit();\n"); 194 break; 195 case ARRAYLENGTH: 196 buf.append("mg.arrayLength();\n"); 197 break; 198 case IALOAD: 199 buf.append("mg.arrayLoad(Type.INT_TYPE);\n"); 200 break; 201 case LALOAD: 202 buf.append("mg.arrayLoad(Type.LONG_TYPE);\n"); 203 break; 204 case FALOAD: 205 buf.append("mg.arrayLoad(Type.FLOAT_TYPE);\n"); 206 break; 207 case DALOAD: 208 buf.append("mg.arrayLoad(Type.DOUBLE_TYPE);\n"); 209 break; 210 case AALOAD: 211 buf.append("mg.arrayLoad(" + getType("java/lang/Object") 212 + ");\n"); 213 break; 214 case BALOAD: 215 buf.append("mg.arrayLoad(Type.BYTE_TYPE);\n"); 216 break; 217 case CALOAD: 218 buf.append("mg.arrayLoad(Type.CHAR_TYPE);\n"); 219 break; 220 case SALOAD: 221 buf.append("mg.arrayLoad(Type.SHORT_TYPE);\n"); 222 break; 223 case IASTORE: 224 buf.append("mg.arrayStore(Type.INT_TYPE);\n"); 225 break; 226 case LASTORE: 227 buf.append("mg.arrayStore(Type.LONG_TYPE);\n"); 228 break; 229 case FASTORE: 230 buf.append("mg.arrayStore(Type.FLOAT_TYPE);\n"); 231 break; 232 case DASTORE: 233 buf.append("mg.arrayStore(Type.DOUBLE_TYPE);\n"); 234 break; 235 case AASTORE: 236 buf.append("mg.arrayStore(" + getType("java/lang/Object") 237 + ");\n"); 238 break; 239 case BASTORE: 240 buf.append("mg.arrayStore(Type.BYTE_TYPE);\n"); 241 break; 242 case CASTORE: 243 buf.append("mg.arrayStore(Type.CHAR_TYPE);\n"); 244 break; 245 case SASTORE: 246 buf.append("mg.arrayStore(Type.SHORT_TYPE);\n"); 247 break; 248 case IADD: 249 buf.append("mg.math(GeneratorAdapter.ADD, Type.INT_TYPE);\n"); 250 break; 251 case LADD: 252 buf.append("mg.math(GeneratorAdapter.ADD, Type.LONG_TYPE);\n"); 253 break; 254 case FADD: 255 buf.append("mg.math(GeneratorAdapter.ADD, Type.FLOAT_TYPE);\n"); 256 break; 257 case DADD: 258 buf.append("mg.math(GeneratorAdapter.ADD, Type.DOUBLE_TYPE);\n"); 259 break; 260 case ISUB: 261 buf.append("mg.math(GeneratorAdapter.SUB, Type.INT_TYPE);\n"); 262 break; 263 case LSUB: 264 buf.append("mg.math(GeneratorAdapter.SUB, Type.LONG_TYPE);\n"); 265 break; 266 case FSUB: 267 buf.append("mg.math(GeneratorAdapter.SUB, Type.FLOAT_TYPE);\n"); 268 break; 269 case DSUB: 270 buf.append("mg.math(GeneratorAdapter.SUB, Type.DOUBLE_TYPE);\n"); 271 break; 272 case IMUL: 273 buf.append("mg.math(GeneratorAdapter.MUL, Type.INT_TYPE);\n"); 274 break; 275 case LMUL: 276 buf.append("mg.math(GeneratorAdapter.MUL, Type.LONG_TYPE);\n"); 277 break; 278 case FMUL: 279 buf.append("mg.math(GeneratorAdapter.MUL, Type.FLOAT_TYPE);\n"); 280 break; 281 case DMUL: 282 buf.append("mg.math(GeneratorAdapter.MUL, Type.DOUBLE_TYPE);\n"); 283 break; 284 case IDIV: 285 buf.append("mg.math(GeneratorAdapter.DIV, Type.INT_TYPE);\n"); 286 break; 287 case LDIV: 288 buf.append("mg.math(GeneratorAdapter.DIV, Type.LONG_TYPE);\n"); 289 break; 290 case FDIV: 291 buf.append("mg.math(GeneratorAdapter.DIV, Type.FLOAT_TYPE);\n"); 292 break; 293 case DDIV: 294 buf.append("mg.math(GeneratorAdapter.DIV, Type.DOUBLE_TYPE);\n"); 295 break; 296 case IREM: 297 buf.append("mg.math(GeneratorAdapter.REM, Type.INT_TYPE);\n"); 298 break; 299 case LREM: 300 buf.append("mg.math(GeneratorAdapter.REM, Type.LONG_TYPE);\n"); 301 break; 302 case FREM: 303 buf.append("mg.math(GeneratorAdapter.REM, Type.FLOAT_TYPE);\n"); 304 break; 305 case DREM: 306 buf.append("mg.math(GeneratorAdapter.REM, Type.DOUBLE_TYPE);\n"); 307 break; 308 case INEG: 309 buf.append("mg.math(GeneratorAdapter.NEG, Type.INT_TYPE);\n"); 310 break; 311 case LNEG: 312 buf.append("mg.math(GeneratorAdapter.NEG, Type.LONG_TYPE);\n"); 313 break; 314 case FNEG: 315 buf.append("mg.math(GeneratorAdapter.NEG, Type.FLOAT_TYPE);\n"); 316 break; 317 case DNEG: 318 buf.append("mg.math(GeneratorAdapter.NEG, Type.DOUBLE_TYPE);\n"); 319 break; 320 case ISHL: 321 buf.append("mg.math(GeneratorAdapter.SHL, Type.INT_TYPE);\n"); 322 break; 323 case LSHL: 324 buf.append("mg.math(GeneratorAdapter.SHL, Type.LONG_TYPE);\n"); 325 break; 326 case ISHR: 327 buf.append("mg.math(GeneratorAdapter.SHR, Type.INT_TYPE);\n"); 328 break; 329 case LSHR: 330 buf.append("mg.math(GeneratorAdapter.SHR, Type.LONG_TYPE);\n"); 331 break; 332 case IUSHR: 333 buf.append("mg.math(GeneratorAdapter.USHR, Type.INT_TYPE);\n"); 334 break; 335 case LUSHR: 336 buf.append("mg.math(GeneratorAdapter.USHR, Type.LONG_TYPE);\n"); 337 break; 338 case IAND: 339 buf.append("mg.math(GeneratorAdapter.AND, Type.INT_TYPE);\n"); 340 break; 341 case LAND: 342 buf.append("mg.math(GeneratorAdapter.AND, Type.LONG_TYPE);\n"); 343 break; 344 case IOR: 345 buf.append("mg.math(GeneratorAdapter.OR, Type.INT_TYPE);\n"); 346 break; 347 case LOR: 348 buf.append("mg.math(GeneratorAdapter.OR, Type.LONG_TYPE);\n"); 349 break; 350 case IXOR: 351 buf.append("mg.math(GeneratorAdapter.XOR, Type.INT_TYPE);\n"); 352 break; 353 case LXOR: 354 buf.append("mg.math(GeneratorAdapter.XOR, Type.LONG_TYPE);\n"); 355 break; 356 case ATHROW: 357 buf.append("mg.throwException();\n"); 358 break; 359 case I2L: 360 buf.append("mg.cast(Type.INT_TYPE, Type.LONG_TYPE);\n"); 361 break; 362 case I2F: 363 buf.append("mg.cast(Type.INT_TYPE, Type.FLOAT_TYPE);\n"); 364 break; 365 case I2D: 366 buf.append("mg.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);\n"); 367 break; 368 case L2I: 369 buf.append("mg.cast(Type.LONG_TYPE, Type.INT_TYPE);\n"); 370 break; 371 case L2F: 372 buf.append("mg.cast(Type.LONG_TYPE, Type.FLOAT_TYPE);\n"); 373 break; 374 case L2D: 375 buf.append("mg.cast(Type.LONG_TYPE, Type.DOUBLE_TYPE);\n"); 376 break; 377 case F2I: 378 buf.append("mg.cast(Type.FLOAT_TYPE, Type.INT_TYPE);\n"); 379 break; 380 case F2L: 381 buf.append("mg.cast(Type.FLOAT_TYPE, Type.LONG_TYPE);\n"); 382 break; 383 case F2D: 384 buf.append("mg.cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);\n"); 385 break; 386 case D2I: 387 buf.append("mg.cast(Type.DOUBLE_TYPE, Type.INT_TYPE);\n"); 388 break; 389 case D2L: 390 buf.append("mg.cast(Type.DOUBLE_TYPE, Type.LONG_TYPE);\n"); 391 break; 392 case D2F: 393 buf.append("mg.cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);\n"); 394 break; 395 case I2B: 396 buf.append("mg.cast(Type.INT_TYPE, Type.BYTE_TYPE);\n"); 400 break; 401 case I2C: buf.append("mg.cast(Type.INT_TYPE, Type.CHAR_TYPE);\n"); 403 break; 404 case I2S: buf.append("mg.cast(Type.INT_TYPE, Type.SHORT_TYPE);\n"); 406 break; 407 case LCMP: 408 case FCMPL: 409 case FCMPG: 410 case DCMPL: 411 case DCMPG: 412 buf.append("mg.visitInsn(") 414 .append(OPCODES[opcode]) 415 .append(");\n"); 416 break; 417 default: 418 throw new RuntimeException ("unexpected case"); 419 } 420 text.add(buf.toString()); 421 lastOpcode = opcode; 422 } 423 424 public void visitIntInsn(final int opcode, final int operand) { 425 buf.setLength(0); 426 if (opcode == NEWARRAY) { 427 String type; 428 switch (operand) { 429 case T_BOOLEAN: 430 type = "Type.BOOLEAN_TYPE"; 431 break; 432 case T_CHAR: 433 type = "Type.CHAR_TYPE"; 434 break; 435 case T_FLOAT: 436 type = "Type.FLOAT_TYPE"; 437 break; 438 case T_DOUBLE: 439 type = "Type.DOUBLE_TYPE"; 440 break; 441 case T_BYTE: 442 type = "Type.BYTE_TYPE"; 443 break; 444 case T_SHORT: 445 type = "Type.SHORT_TYPE"; 446 break; 447 case T_INT: 448 type = "Type.INT_TYPE"; 449 break; 450 case T_LONG: 451 type = "Type.LONG_TYPE"; 452 break; 453 default: 454 throw new RuntimeException ("unexpected case"); 455 } 456 buf.append("mg.newArray(").append(type).append(");\n"); 457 } else { 458 buf.append("mg.push(").append(operand).append(");\n"); 459 } 460 text.add(buf.toString()); 461 lastOpcode = opcode; 462 } 463 464 public void visitVarInsn(final int opcode, int var) { 465 buf.setLength(0); 466 switch (opcode) { 467 case RET: 468 buf.append("mg.ret("); 469 if (var < firstLocal) { 470 buf.append(var); 471 } else { 472 int v = generateNewLocal(var, "Type.INT_TYPE"); 473 buf.append("local").append(v); 474 } 475 buf.append(");\n"); 476 break; 477 478 case ILOAD: 479 generateLoadLocal(var, "Type.INT_TYPE"); 480 break; 481 case LLOAD: 482 generateLoadLocal(var, "Type.LONG_TYPE"); 483 break; 484 case FLOAD: 485 generateLoadLocal(var, "Type.FLOAT_TYPE"); 486 break; 487 case DLOAD: 488 generateLoadLocal(var, "Type.DOUBLE_TYPE"); 489 break; 490 case ALOAD: 491 generateLoadLocal(var, getType("java/lang/Object")); 492 break; 493 494 case ISTORE: 495 generateStoreLocal(var, "Type.INT_TYPE"); 496 break; 497 case LSTORE: 498 generateStoreLocal(var, "Type.LONG_TYPE"); 499 break; 500 case FSTORE: 501 generateStoreLocal(var, "Type.FLOAT_TYPE"); 502 break; 503 case DSTORE: 504 generateStoreLocal(var, "Type.DOUBLE_TYPE"); 505 break; 506 case ASTORE: 507 generateStoreLocal(var, getType("java/lang/Object")); 508 break; 509 510 default: 511 throw new RuntimeException ("unexpected case"); 512 } 513 514 text.add(buf.toString()); 515 lastOpcode = opcode; 516 } 517 518 private void generateLoadLocal(int var, String type) { 519 if (var < firstLocal) { 520 if (var == 0 && (access & ACC_STATIC) == 0) { 521 buf.append("mg.loadThis();\n"); 522 } else { 523 buf.append("mg.loadArg(") 524 .append(getArgIndex(var)) 525 .append(");\n"); 526 } 527 } else { 528 int local = generateNewLocal(var, type); 529 buf.append("mg.loadLocal(local").append(local); 530 if (!type.equals(localTypes.get(local))) { 531 localTypes.set(local, type); 532 buf.append(", ").append(type); 533 } 534 buf.append(");\n"); 535 } 536 } 537 538 private void generateStoreLocal(int var, String type) { 539 if (var < firstLocal) { 540 buf.append("mg.storeArg(").append(getArgIndex(var)).append(");\n"); 541 } else { 542 int local = generateNewLocal(var, type); 543 buf.append("mg.storeLocal(local").append(local); 544 if (!type.equals(localTypes.get(local))) { 545 localTypes.set(local, type); 546 buf.append(", ").append(type); 547 } 548 buf.append(");\n"); 549 } 550 } 551 552 private int generateNewLocal(int var, String type) { 553 Integer i = (Integer ) locals.get(new Integer (var)); 554 if (i == null) { 555 int local = locals.size(); 556 locals.put(new Integer (var), new Integer (local)); 557 localTypes.add(type); 558 buf.append("int local" + local + " = mg.newLocal(" + type + ");\n"); 559 return local; 560 } 561 return i.intValue(); 562 } 563 564 private int getArgIndex(int var) { 565 int nextLocal = ((Opcodes.ACC_STATIC & access) != 0) ? 0 : 1; 566 int i = 0; 567 while (nextLocal != var) { 568 nextLocal += argumentTypes[i++].getSize(); 569 } 570 return i; 571 } 572 573 public void visitTypeInsn(final int opcode, final String desc) { 574 String type; 575 if (desc.charAt(0) == '[') { 576 type = getDescType(desc); 577 } else { 578 type = getType(desc); 579 } 580 buf.setLength(0); 581 if (opcode == NEW) { 582 buf.append("mg.newInstance(").append(type).append(");\n"); 583 } else if (opcode == ANEWARRAY) { 584 buf.append("mg.newArray(").append(type).append(");\n"); 585 } else if (opcode == CHECKCAST) { 586 buf.append("mg.checkCast(").append(type).append(");\n"); 587 } else if (opcode == INSTANCEOF) { 588 buf.append("mg.instanceOf(").append(type).append(");\n"); 589 } 590 text.add(buf.toString()); 591 lastOpcode = opcode; 592 } 593 594 public void visitFieldInsn( 595 final int opcode, 596 final String owner, 597 final String name, 598 final String desc) 599 { 600 buf.setLength(0); 601 switch (opcode) { 602 case GETFIELD: 603 buf.append("mg.getField("); 604 break; 605 case PUTFIELD: 606 buf.append("mg.putField("); 607 break; 608 case GETSTATIC: 609 buf.append("mg.getStatic("); 610 break; 611 case PUTSTATIC: 612 buf.append("mg.putStatic("); 613 break; 614 default: 615 throw new RuntimeException ("unexpected case"); 616 } 617 buf.append(getType(owner)); 618 buf.append(", \""); 619 buf.append(name); 620 buf.append("\", "); 621 buf.append(getDescType(desc)); 622 buf.append(");\n"); 623 text.add(buf.toString()); 624 lastOpcode = opcode; 625 } 626 627 public void visitMethodInsn( 628 final int opcode, 629 final String owner, 630 final String name, 631 final String desc) 632 { 633 buf.setLength(0); 634 switch (opcode) { 635 case INVOKEVIRTUAL: 636 buf.append("mg.invokeVirtual("); 637 break; 638 case INVOKESPECIAL: 639 buf.append("mg.invokeConstructor("); 640 break; 641 case INVOKESTATIC: 642 buf.append("mg.invokeStatic("); 643 break; 644 case INVOKEINTERFACE: 645 buf.append("mg.invokeInterface("); 646 break; 647 default: 648 throw new RuntimeException ("unexpected case"); 649 } 650 if (owner.charAt(0) == '[') { 651 buf.append(getDescType(owner)); 652 } else { 653 buf.append(getType(owner)); 654 } 655 buf.append(", "); 656 buf.append(getMethod(name, desc)); 657 buf.append(");\n"); 658 text.add(buf.toString()); 659 lastOpcode = opcode; 660 } 661 662 public void visitJumpInsn(final int opcode, final Label label) { 663 buf.setLength(0); 664 declareLabel(label); 665 if (opcode == GOTO || opcode == IFNULL || opcode == IFNONNULL) { 666 if (opcode == GOTO) 667 buf.append("mg.goTo("); 668 if (opcode == IFNULL) 669 buf.append("mg.ifNull("); 670 if (opcode == IFNONNULL) 671 buf.append("mg.ifNonNull("); 672 appendLabel(label); 673 buf.append(");\n"); 674 } else if (opcode == IF_ICMPEQ) { 675 buf.append("mg.ifICmp(GeneratorAdapter.EQ, "); 676 appendLabel(label); 677 buf.append(");\n"); 678 } else if (opcode == IF_ICMPNE) { 679 buf.append("mg.ifICmp(GeneratorAdapter.NE, "); 680 appendLabel(label); 681 buf.append(");\n"); 682 } else if (opcode == IF_ICMPLT) { 683 buf.append("mg.ifICmp(GeneratorAdapter.LT, "); 684 appendLabel(label); 685 buf.append(");\n"); 686 } else if (opcode == IF_ICMPGE) { 687 buf.append("mg.ifICmp(GeneratorAdapter.GE, "); 688 appendLabel(label); 689 buf.append(");\n"); 690 } else if (opcode == IF_ICMPGT) { 691 buf.append("mg.ifICmp(GeneratorAdapter.GT, "); 692 appendLabel(label); 693 buf.append(");\n"); 694 } else if (opcode == IF_ICMPLE) { 695 buf.append("mg.ifICmp(GeneratorAdapter.LE, "); 696 appendLabel(label); 697 buf.append(");\n"); 698 } else if (opcode == IF_ACMPEQ) { 699 buf.append("mg.ifCmp("); 700 buf.append(getType("java/lang/Object")) 701 .append(", ") 702 .append("GeneratorAdapter.EQ, "); 703 appendLabel(label); 704 buf.append(");\n"); 705 } else if (opcode == IF_ACMPNE) { 706 buf.append("mg.ifCmp("); 707 buf.append(getType("java/lang/Object")) 708 .append(", ") 709 .append("GeneratorAdapter.NE, "); 710 appendLabel(label); 711 buf.append(");\n"); 712 } else if (opcode == IFEQ) { 713 buf.append("mg.ifZCmp(GeneratorAdapter.EQ, "); 714 appendLabel(label); 715 buf.append(");\n"); 716 } else if (opcode == IFNE) { 717 buf.append("mg.ifZCmp(GeneratorAdapter.NE, "); 718 appendLabel(label); 719 buf.append(");\n"); 720 } else if (opcode == IFLT) { 721 buf.append("mg.ifZCmp(GeneratorAdapter.LT, "); 722 appendLabel(label); 723 buf.append(");\n"); 724 } else if (opcode == IFGE) { 725 buf.append("mg.ifZCmp(GeneratorAdapter.GE, "); 726 appendLabel(label); 727 buf.append(");\n"); 728 } else if (opcode == IFGT) { 729 buf.append("mg.ifZCmp(GeneratorAdapter.GT, "); 730 appendLabel(label); 731 buf.append(");\n"); 732 } else if (opcode == IFLE) { 733 buf.append("mg.ifZCmp(GeneratorAdapter.LE, "); 734 appendLabel(label); 735 buf.append(");\n"); 736 } else { 737 buf.append("mg.visitJumpInsn(") 738 .append(OPCODES[opcode]) 739 .append(", "); 740 appendLabel(label); 741 buf.append(");\n"); 742 } 743 text.add(buf.toString()); 744 lastOpcode = opcode; 745 } 746 747 public void visitLabel(final Label label) { 748 buf.setLength(0); 749 declareLabel(label); 750 buf.append("mg.mark("); 751 appendLabel(label); 752 buf.append(");\n"); 753 text.add(buf.toString()); 754 lastOpcode = -1; 755 } 756 757 public void visitLdcInsn(final Object cst) { 758 buf.setLength(0); 759 buf.append("mg.push("); 760 if (cst == null) { 761 buf.append("(String)null"); 762 } else if (cst instanceof Long ) { 763 buf.append(cst + "L"); 764 } else if (cst instanceof Float ) { 765 float f = ((Float ) cst).floatValue(); 766 if (Float.isNaN(f)) { 767 buf.append("Float.NaN"); 768 } else if (Float.isInfinite(f)) { 769 buf.append(f > 0 770 ? "Float.POSITIVE_INFINITY" 771 : "Float.NEGATIVE_INFINITY"); 772 } else { 773 buf.append(cst + "f"); 774 } 775 } else if (cst instanceof Double ) { 776 double d = ((Double ) cst).doubleValue(); 777 if (Double.isNaN(d)) { 778 buf.append("Double.NaN"); 779 } else if (Double.isInfinite(d)) { 780 buf.append(d > 0 781 ? "Double.POSITIVE_INFINITY" 782 : "Double.NEGATIVE_INFINITY"); 783 } else { 784 buf.append(cst + "d"); 785 } 786 } else if (cst instanceof String ) { 787 appendString(buf, (String ) cst); 788 } else if (cst instanceof Type) { 789 buf.append("Type.getType(\"").append(cst).append("\")"); 790 } else { 791 buf.append(cst); 792 } 793 buf.append(");\n"); 794 text.add(buf.toString()); 795 lastOpcode = LDC; 796 } 797 798 public void visitIincInsn(final int var, final int increment) { 799 buf.setLength(0); 800 if (var < firstLocal) { 801 buf.append("mg.iinc(").append(var); 802 } else { 803 int v = generateNewLocal(var, "Type.INT_TYPE"); 804 buf.append("mg.iinc(local").append(v); 805 } 806 buf.append(", ").append(increment).append(");\n"); 807 text.add(buf.toString()); 808 lastOpcode = IINC; 809 } 810 811 public void visitTableSwitchInsn( 812 final int min, 813 final int max, 814 final Label dflt, 815 final Label labels[]) 816 { 817 buf.setLength(0); 818 for (int i = 0; i < labels.length; ++i) { 819 declareLabel(labels[i]); 820 } 821 declareLabel(dflt); 822 823 buf.append("mg.visitTableSwitchInsn(") 824 .append(min) 825 .append(", ") 826 .append(max) 827 .append(", "); 828 appendLabel(dflt); 829 buf.append(", new Label[] {"); 830 for (int i = 0; i < labels.length; ++i) { 831 buf.append(i == 0 ? " " : ", "); 832 appendLabel(labels[i]); 833 } 834 buf.append(" }); // TODO\n"); 835 text.add(buf.toString()); 836 lastOpcode = TABLESWITCH; 837 } 838 839 public void visitLookupSwitchInsn( 840 final Label dflt, 841 final int keys[], 842 final Label labels[]) 843 { 844 buf.setLength(0); 845 for (int i = 0; i < labels.length; ++i) { 846 declareLabel(labels[i]); 847 } 848 declareLabel(dflt); 849 850 buf.append("mg.visitLookupSwitchInsn("); 851 appendLabel(dflt); 852 buf.append(", new int[] {"); 853 for (int i = 0; i < keys.length; ++i) { 854 buf.append(i == 0 ? " " : ", ").append(keys[i]); 855 } 856 buf.append(" }, new Label[] {"); 857 for (int i = 0; i < labels.length; ++i) { 858 buf.append(i == 0 ? " " : ", "); 859 appendLabel(labels[i]); 860 } 861 buf.append(" }); // TODO\n"); 862 text.add(buf.toString()); 863 lastOpcode = LOOKUPSWITCH; 864 } 865 866 public void visitMultiANewArrayInsn(final String desc, final int dims) { 867 buf.setLength(0); 868 buf.append("mg.visitMultiANewArrayInsn(\""); 869 buf.append(desc); 870 buf.append("\", ").append(dims).append(");\n"); 871 text.add(buf.toString()); 872 lastOpcode = MULTIANEWARRAY; 873 } 874 875 public void visitTryCatchBlock( 876 final Label start, 877 final Label end, 878 final Label handler, 879 final String type) 880 { 881 buf.setLength(0); 882 buf.append("mg.visitTryCatchBlock("); 883 appendLabel(start); 884 buf.append(", "); 885 appendLabel(end); 886 buf.append(", "); 887 appendLabel(handler); 888 buf.append(", "); 889 if (type == null) { 890 buf.append("null"); 891 } else { 892 buf.append('"').append(type).append('"'); 893 } 894 buf.append("); // TODO\n"); 895 text.add(buf.toString()); 896 lastOpcode = -1; 897 } 898 899 public void visitLocalVariable( 900 final String name, 901 final String desc, 902 final String signature, 903 final Label start, 904 final Label end, 905 final int index) 906 { 907 buf.setLength(0); 908 buf.append("mg.visitLocalVariable(\""); 909 buf.append(name); 910 buf.append("\", \""); 911 buf.append(desc); 912 buf.append("\", "); 913 if (signature == null) { 914 buf.append("null"); 915 } else { 916 buf.append('"').append(signature).append('"'); 917 } 918 buf.append(", "); 919 appendLabel(start); 920 buf.append(", "); 921 appendLabel(end); 922 buf.append(", ").append(index).append(");\n"); 923 text.add(buf.toString()); 924 lastOpcode = -1; 925 } 926 927 public void visitLineNumber(final int line, final Label start) { 928 buf.setLength(0); 929 buf.append("mg.visitLineNumber(").append(line).append(", "); 930 appendLabel(start); 931 buf.append(");\n"); 932 text.add(buf.toString()); 933 lastOpcode = -1; 934 } 935 936 public void visitMaxs(final int maxStack, final int maxLocals) { 937 text.add("mg.endMethod();\n"); 938 lastOpcode = -1; 939 } 940 941 public void visitEnd() { 942 } 944 945 static String getType(String internalName) { 946 return "Type.getType(\"L" + internalName + ";\")"; 947 } 948 949 static String getDescType(String desc) { 950 if (desc.equals("Z")) 951 return "Type.BOOLEAN_TYPE"; 952 if (desc.equals("B")) 953 return "Type.BYTE_TYPE"; 954 if (desc.equals("C")) 955 return "Type.CHAR_TYPE"; 956 if (desc.equals("D")) 957 return "Type.DOUBLE_TYPE"; 958 if (desc.equals("F")) 959 return "Type.FLOAT_TYPE"; 960 if (desc.equals("I")) 961 return "Type.INT_TYPE"; 962 if (desc.equals("J")) 963 return "Type.LONG_TYPE"; 964 if (desc.equals("S")) 965 return "Type.SHORT_TYPE"; 966 if (desc.equals("V")) 967 return "Type.VOID_TYPE"; 968 return "Type.getType(\"" + desc + "\")"; 969 } 970 971 static String getMethod(String name, String desc) { 972 Type rt = Type.getReturnType(desc); 973 Type[] argt = Type.getArgumentTypes(desc); 974 StringBuffer buf = new StringBuffer (); 975 buf.append("Method.getMethod(\""); 976 buf.append(rt.getClassName()).append(" "); 977 buf.append(name).append("("); 978 for (int i = 0; i < argt.length; ++i) { 979 if (i > 0) 980 buf.append(','); 981 buf.append(argt[i].getClassName()); 982 } 983 buf.append(")\")"); 984 return buf.toString(); 985 } 986 987 994 private void declareLabel(final Label l) { 995 String name = (String ) labelNames.get(l); 996 if (name == null) { 997 name = "label" + labelNames.size(); 998 labelNames.put(l, name); 999 buf.append("Label ").append(name).append(" = mg.newLabel();\n"); 1000 } 1001 } 1002 1003 1010 private void appendLabel(final Label l) { 1011 buf.append((String ) labelNames.get(l)); 1012 } 1013} 1014 | Popular Tags |