1 52 53 package com.go.trove.classfile; 54 55 import java.util.*; 56 import java.io.PrintWriter ; 57 58 68 public class CodeAssemblerPrinter implements CodeAssembler { 69 private TypeDescriptor[] mParamTypes; 70 private boolean mIsStatic; 71 private PrintWriter mWriter; 72 private String mLinePrefix; 73 private String mLineSuffix; 74 75 private int mLocalCounter; 76 private int mLabelCounter; 77 78 private int mTypeDescriptorCounter; 79 private Map mTypeDescriptorNames; 81 82 private int mTypeDescriptorArrayCounter; 83 private Map mTypeDescriptorArrayNames; 85 86 public CodeAssemblerPrinter(TypeDescriptor[] paramTypes, boolean isStatic, 87 PrintWriter writer) 88 { 89 this(paramTypes, isStatic, writer, null, null); 90 } 91 92 public CodeAssemblerPrinter(TypeDescriptor[] paramTypes, boolean isStatic, 93 PrintWriter writer, 94 String linePrefix, String lineSuffix) 95 { 96 mParamTypes = paramTypes; 97 mIsStatic = isStatic; 98 mWriter = writer; 99 mLinePrefix = linePrefix; 100 mLineSuffix = lineSuffix; 101 mTypeDescriptorNames = new HashMap(); 102 mTypeDescriptorArrayNames = new HashMap(); 103 } 104 105 public LocalVariable[] getParameters() { 106 LocalVariable[] vars = new LocalVariable[mParamTypes.length]; 107 108 int varNum = (mIsStatic) ? 0 : 1; 109 for (int i = 0; i<mParamTypes.length; i++) { 110 String varName = "var_" + (++mLocalCounter); 111 println("LocalVariable " + varName + 112 " = getParameters()[" + i + ']'); 113 LocalVariable localVar = 114 new NamedLocal(varName, mParamTypes[i], varNum); 115 varNum += (localVar.isDoubleWord() ? 2 : 1); 116 vars[i] = localVar; 117 } 118 119 return vars; 120 } 121 122 public LocalVariable createLocalVariable(String name, 123 TypeDescriptor type) { 124 String varName = "var_" + (++mLocalCounter); 125 if (name != null) { 126 name = '"' + name + '"'; 127 } 128 println("LocalVariable " + varName + 129 " = createLocalVariable(" + name + 130 ", " + getTypeDescriptorName(type) + ')'); 131 return new NamedLocal(varName, type, -1); 132 } 133 134 public Label createLabel() { 135 String name = "label_" + (++mLabelCounter); 136 println("Label " + name + " = createLabel()"); 137 return new NamedLabel(name); 138 } 139 140 public void exceptionHandler(Location startLocation, 141 Location endLocation, 142 String catchClassName) { 143 println("exceptionHandler(" + 144 getLabelName(startLocation) + ", " + 145 getLabelName(endLocation) + ", " + 146 catchClassName + ')'); 147 } 148 149 public void mapLineNumber(int lineNumber) { 150 println("mapLineNumber(" + lineNumber + ')'); 151 } 152 153 public void loadConstant(String value) { 154 if (value == null) { 155 println("loadConstant(null)"); 156 } 157 else { 158 println("loadConstant(\"" + escape(value) + "\")"); 159 } 160 } 161 162 public void loadConstant(boolean value) { 163 println("loadConstant(" + value + ')'); 164 } 165 166 public void loadConstant(int value) { 167 println("loadConstant(" + value + ')'); 168 } 169 170 public void loadConstant(long value) { 171 println("loadConstant(" + value + "L)"); 172 } 173 174 public void loadConstant(float value) { 175 println("loadConstant(" + value + "f)"); 176 } 177 178 public void loadConstant(double value) { 179 println("loadConstant(" + value + "d)"); 180 } 181 182 public void loadLocal(LocalVariable local) { 183 println("loadLocal(" + local.getName() + ')'); 184 } 185 186 public void loadThis() { 187 println("loadThis()"); 188 } 189 190 public void storeLocal(LocalVariable local) { 191 println("storeLocal(" + local.getName() + ')'); 192 } 193 194 public void loadFromArray(Class type) { 195 println("loadFromArray(" + generateClassLiteral(type) + ')'); 196 } 197 198 public void storeToArray(Class type) { 199 println("storeToArray(" + generateClassLiteral(type) + ')'); 200 } 201 202 public void loadField(String fieldName, 203 TypeDescriptor type) { 204 println("loadField(\"" + fieldName + "\", " + 205 getTypeDescriptorName(type) + ')'); 206 } 207 208 public void loadField(String className, 209 String fieldName, 210 TypeDescriptor type) { 211 println("loadField(\"" + className + "\", \"" + fieldName + "\", " + 212 getTypeDescriptorName(type) + ')'); 213 } 214 215 public void loadStaticField(String fieldName, 216 TypeDescriptor type) { 217 println("loadStaticField(\"" + fieldName + "\", " + 218 getTypeDescriptorName(type) + ')'); 219 } 220 221 public void loadStaticField(String className, 222 String fieldName, 223 TypeDescriptor type) { 224 println("loadStaticField(\"" + className + "\", \"" + 225 fieldName + "\", " + 226 getTypeDescriptorName(type) + ')'); 227 } 228 229 public void storeField(String fieldName, 230 TypeDescriptor type) { 231 println("storeField(\"" + fieldName + "\", " + 232 getTypeDescriptorName(type) + ')'); 233 } 234 235 public void storeField(String className, 236 String fieldName, 237 TypeDescriptor type) { 238 println("storeField(\"" + className + "\", \"" + fieldName + "\", " + 239 getTypeDescriptorName(type) + ')'); 240 } 241 242 public void storeStaticField(String fieldName, 243 TypeDescriptor type) { 244 println("storeStaticField(\"" + fieldName + "\", " + 245 getTypeDescriptorName(type) + ')'); 246 } 247 248 public void storeStaticField(String className, 249 String fieldName, 250 TypeDescriptor type) { 251 println("storeStaticField(\"" + className + "\", \"" + 252 fieldName + "\", " + 253 getTypeDescriptorName(type) + ')'); 254 } 255 256 public void returnVoid() { 257 println("returnVoid()"); 258 } 259 260 public void returnValue(Class type) { 261 println("returnValue(" + generateClassLiteral(type) + ')'); 262 } 263 264 public void convert(Class fromType, Class toType) { 265 println("convert(" + 266 generateClassLiteral(fromType) + ", " + 267 generateClassLiteral(toType) + ')'); 268 } 269 270 public void invokeVirtual(String methodName, 271 TypeDescriptor ret, 272 TypeDescriptor[] params) { 273 println("invokeVirtual(\"" + methodName + "\", " + 274 getTypeDescriptorName(ret) + ", " + 275 getTypeDescriptorArrayName(params) + ')'); 276 } 277 278 public void invokeVirtual(String className, 279 String methodName, 280 TypeDescriptor ret, 281 TypeDescriptor[] params) { 282 println("invokeVirtual(\"" + className + "\", \"" + 283 methodName + "\", " + 284 getTypeDescriptorName(ret) + ", " + 285 getTypeDescriptorArrayName(params) + ')'); 286 } 287 288 public void invokeStatic(String methodName, 289 TypeDescriptor ret, 290 TypeDescriptor[] params) { 291 println("invokeStatic(\"" + methodName + "\", " + 292 getTypeDescriptorName(ret) + ", " + 293 getTypeDescriptorArrayName(params) + ')'); 294 } 295 296 public void invokeStatic(String className, 297 String methodName, 298 TypeDescriptor ret, 299 TypeDescriptor[] params) { 300 println("invokeStatic(\"" + className + ", " + 301 methodName + ", " + 302 getTypeDescriptorName(ret) + ", " + 303 getTypeDescriptorArrayName(params) + ')'); 304 } 305 306 public void invokeInterface(String className, 307 String methodName, 308 TypeDescriptor ret, 309 TypeDescriptor[] params) { 310 println("invokeInterface(\"" + className + "\", \"" + 311 methodName + "\", " + 312 getTypeDescriptorName(ret) + ", " + 313 getTypeDescriptorArrayName(params) + ')'); 314 } 315 316 public void invokePrivate(String methodName, 317 TypeDescriptor ret, 318 TypeDescriptor[] params) { 319 println("invokePrivate(\"" + methodName + "\", " + 320 getTypeDescriptorName(ret) + ", " + 321 getTypeDescriptorArrayName(params) + ')'); 322 } 323 324 public void invokeSuper(String superClassName, 325 String methodName, 326 TypeDescriptor ret, 327 TypeDescriptor[] params) { 328 println("invokeSuper(\"" + superClassName + "\", \"" + 329 methodName + "\", " + 330 getTypeDescriptorName(ret) + ", " + 331 getTypeDescriptorArrayName(params) + ')'); 332 } 333 334 public void invokeConstructor(TypeDescriptor[] params) { 335 println("invokeConstructor(" + 336 getTypeDescriptorArrayName(params) + ')'); 337 } 338 339 public void invokeConstructor(String className, TypeDescriptor[] params) { 340 println("invokeConstructor(\"" + className + "\", " + 341 getTypeDescriptorArrayName(params) + ')'); 342 } 343 344 public void invokeSuperConstructor(TypeDescriptor[] params) { 345 println("invokeSuperConstructor(" + 346 getTypeDescriptorArrayName(params) + ')'); 347 } 348 349 public void newObject(TypeDescriptor type) { 350 println("newObject(" + getTypeDescriptorName(type) + ')'); 351 } 352 353 public void dup() { 354 println("dup()"); 355 } 356 357 public void dupX1() { 358 println("dupX1()"); 359 } 360 361 public void dupX2() { 362 println("dupX2()"); 363 } 364 365 public void dup2() { 366 println("dup2()"); 367 } 368 369 public void dup2X1() { 370 println("dup2X1()"); 371 } 372 373 public void dup2X2() { 374 println("dup2X2()"); 375 } 376 377 public void pop() { 378 println("pop()"); 379 } 380 381 public void pop2() { 382 println("pop2()"); 383 } 384 385 public void swap() { 386 println("swap()"); 387 } 388 389 public void swap2() { 390 println("swap2()"); 391 } 392 393 public void branch(Location location) { 394 println("branch(" + getLabelName(location) + ')'); 395 } 396 397 public void ifNullBranch(Location location, boolean choice) { 398 println("ifNullBranch(" + 399 getLabelName(location) + ", " + choice + ')'); 400 } 401 402 public void ifEqualBranch(Location location, boolean choice) { 403 println("ifEqualBranch(" + 404 getLabelName(location) + ", " + choice + ')'); 405 } 406 407 public void ifZeroComparisonBranch(Location location, String choice) { 408 println("ifZeroComparisonBranch(" + 409 getLabelName(location) + ", \"" + choice + "\")"); 410 } 411 412 public void ifComparisonBranch(Location location, String choice) { 413 println("ifComparisonBranch(" + 414 getLabelName(location) + ", \"" + choice + "\")"); 415 } 416 417 public void switchBranch(int[] cases, 418 Location[] locations, Location defaultLocation) { 419 420 StringBuffer buf = new StringBuffer (cases.length * 15); 421 422 buf.append("switchBranch("); 423 424 buf.append("new int[] {"); 425 for (int i=0; i<cases.length; i++) { 426 if (i > 0) { 427 buf.append(", "); 428 } 429 buf.append(cases[i]); 430 } 431 buf.append("}"); 432 433 buf.append(", "); 434 435 buf.append("new Location[] {"); 436 for (int i=0; i<locations.length; i++) { 437 if (i > 0) { 438 buf.append(", "); 439 } 440 buf.append(getLabelName(locations[i])); 441 } 442 buf.append("}"); 443 444 buf.append(", "); 445 buf.append(getLabelName(defaultLocation)); 446 buf.append(')'); 447 448 println(buf.toString()); 449 } 450 451 public void jsr(Location location) { 452 println("jsr(" + getLabelName(location) + ')'); 453 } 454 455 public void ret(LocalVariable local) { 456 println("ret(" + local.getName() + ')'); 457 } 458 459 public void math(byte opcode) { 460 println 461 ("math(Opcode." + Opcode.getMnemonic(opcode).toUpperCase() + ')'); 462 } 463 464 public void arrayLength() { 465 println("arrayLength()"); 466 } 467 468 public void throwObject() { 469 println("throwObject()"); 470 } 471 472 public void checkCast(TypeDescriptor type) { 473 println("checkCast(" + getTypeDescriptorName(type) + ')'); 474 } 475 476 public void instanceOf(TypeDescriptor type) { 477 println("instanceOf(" + getTypeDescriptorName(type) + ')'); 478 } 479 480 public void integerIncrement(LocalVariable local, int amount) { 481 println("integerIncrement(" + local.getName() + ", " + amount + ')'); 482 } 483 484 public void monitorEnter() { 485 println("monitorEnter()"); 486 } 487 488 public void monitorExit() { 489 println("monitorExit()"); 490 } 491 492 public void nop() { 493 println("nop()"); 494 } 495 496 public void breakpoint() { 497 println("breakpoint()"); 498 } 499 500 private void println(String str) { 501 if (mLinePrefix != null) { 502 mWriter.print(mLinePrefix); 503 } 504 if (mLineSuffix == null) { 505 mWriter.println(str); 506 } 507 else { 508 mWriter.print(str); 509 mWriter.println(mLineSuffix); 510 } 511 } 512 513 private String generateClassLiteral(Class type) { 514 StringBuffer buf = new StringBuffer (); 515 516 int dim = 0; 517 while (type.isArray()) { 518 dim++; 519 type = type.getComponentType(); 520 } 521 522 if (!type.isPrimitive()) { 523 buf.append(type.getName()); 524 } 525 else { 526 if (type == int.class) { 527 buf.append("int"); 528 } 529 else if (type == char.class) { 530 buf.append("char"); 531 } 532 else if (type == boolean.class) { 533 buf.append("boolean"); 534 } 535 else if (type == double.class) { 536 buf.append("double"); 537 } 538 else if (type == float.class) { 539 buf.append("float"); 540 } 541 else if (type == long.class) { 542 buf.append("long"); 543 } 544 else if (type == byte.class) { 545 buf.append("byte"); 546 } 547 else if (type == short.class) { 548 buf.append("short"); 549 } 550 else { 551 buf.append("void"); 552 } 553 } 554 555 while (dim-- > 0) { 556 buf.append('['); 557 buf.append(']'); 558 } 559 560 buf.append(".class"); 561 562 return buf.toString(); 563 } 564 565 private String getLabelName(Location location) { 566 if (location instanceof NamedLabel) { 567 return ((NamedLabel)location).mName; 568 } 569 else { 570 return ((NamedLabel)createLabel()).mName; 571 } 572 } 573 574 private String getTypeDescriptorName(TypeDescriptor type) { 575 if (type == null) { 576 return "null"; 577 } 578 579 String name = (String )mTypeDescriptorNames.get(type); 580 581 if (name == null) { 582 name = "type_" + (++mTypeDescriptorCounter); 583 mTypeDescriptorNames.put(type, name); 584 585 StringBuffer buf = new StringBuffer ("TypeDescriptor "); 586 buf.append(name); 587 buf.append(" = new TypeDescriptor("); 588 589 TypeDescriptor componentType = type.getComponentType(); 590 if (componentType != null) { 591 buf.append(getTypeDescriptorName(componentType)); 592 buf.append(", "); 593 buf.append(type.getSpecifiedDimensions()); 594 } 595 else { 596 Class clazz = type.getClassArg(); 597 if (clazz != null) { 598 buf.append(generateClassLiteral(clazz)); 599 } 600 else { 601 buf.append('"'); 602 buf.append(type.getClassName()); 603 buf.append('"'); 604 } 605 } 606 607 buf.append(')'); 608 609 println(buf.toString()); 610 } 611 612 return name; 613 } 614 615 private String getTypeDescriptorArrayName(TypeDescriptor[] types) { 616 if (types == null) { 617 return "null"; 618 } 619 620 Object key = Arrays.asList(types); 621 String name = (String )mTypeDescriptorArrayNames.get(key); 622 623 if (name == null) { 624 name = "params_" + (++mTypeDescriptorArrayCounter); 625 mTypeDescriptorArrayNames.put(key, name); 626 627 StringBuffer buf = new StringBuffer ("TypeDescriptor[] "); 628 buf.append(name); 629 buf.append(" = new TypeDescriptor[] {"); 630 631 for (int i=0; i<types.length; i++) { 632 if (i > 0) { 633 buf.append(", "); 634 } 635 buf.append(getTypeDescriptorName(types[i])); 636 } 637 638 buf.append('}'); 639 640 println(buf.toString()); 641 } 642 643 return name; 644 } 645 646 private String escape(String value) { 647 int length = value.length(); 648 int i = 0; 649 for (; i < length; i++) { 650 char c = value.charAt(i); 651 if (c < 32 || c > 126 || c == '"' || c == '\\') { 652 break; 653 } 654 } 655 656 if (i >= length) { 657 return value; 658 } 659 660 StringBuffer buf = new StringBuffer (length + 16); 661 for (i=0; i<length; i++) { 662 char c = value.charAt(i); 663 if (c >= 32 && c <= 126 && c != '"' && c != '\\') { 664 buf.append(c); 665 continue; 666 } 667 668 switch (c) { 669 case '\0': 670 buf.append("\\0"); 671 break; 672 case '"': 673 buf.append("\\\""); 674 break; 675 case '\\': 676 buf.append("\\\\"); 677 break; 678 case '\b': 679 buf.append("\\b"); 680 break; 681 case '\f': 682 buf.append("\\f"); 683 break; 684 case '\n': 685 buf.append("\\n"); 686 break; 687 case '\r': 688 buf.append("\\r"); 689 break; 690 case '\t': 691 buf.append("\\t"); 692 break; 693 default: 694 String u = Integer.toHexString(c).toLowerCase(); 695 buf.append("\\u"); 696 for (int len = u.length(); len < 4; len++) { 697 buf.append('0'); 698 } 699 buf.append(u); 700 break; 701 } 702 } 703 704 return buf.toString(); 705 } 706 707 private class NamedLocal implements LocalVariable { 708 private String mName; 709 private TypeDescriptor mType; 710 private boolean mIsDoubleWord; 711 private int mNumber; 712 713 public NamedLocal(String name, TypeDescriptor type, int number) { 714 mName = name; 715 mType = type; 716 Class clazz = type.getClassArg(); 717 mIsDoubleWord = clazz == long.class || clazz == double.class; 718 mNumber = number; 719 } 720 721 public String getName() { 722 return mName; 723 } 724 725 public void setName(String name) { 726 println(mName + ".setName(" + name + ')'); 727 } 728 729 public TypeDescriptor getType() { 730 return mType; 731 } 732 733 public boolean isDoubleWord() { 734 return mIsDoubleWord; 735 } 736 737 public int getNumber() { 738 return mNumber; 739 } 740 741 public Location getStartLocation() { 742 return null; 743 } 744 745 public Location getEndLocation() { 746 return null; 747 } 748 749 public SortedSet getLocationRangeSet() { 750 return null; 751 } 752 } 753 754 private class NamedLabel implements Label { 755 public final String mName; 756 757 public NamedLabel(String name) { 758 mName = name; 759 } 760 761 public Label setLocation() { 762 println(mName + ".setLocation()"); 763 return this; 764 } 765 766 public int getLocation() { 767 return -1; 768 } 769 770 public int compareTo(Object obj) { 771 return 0; 772 } 773 } 774 } 775 | Popular Tags |