1 22 package org.jboss.proxy.compiler; 23 24 import java.lang.reflect.*; 25 import java.util.*; 26 import java.io.*; 27 28 36 public class ProxyAssembler 37 { 38 Vector cv = new Vector(); 40 Hashtable ct = new Hashtable(); 41 Hashtable ut = new Hashtable(); 42 short cn = 1; 43 44 Vector members; 46 AMember current; 47 ByteArrayOutputStream code; Stack stack; 50 String className; 52 int modifiers; 53 Class superClass; 54 Class interfaces[]; 55 56 public short getIndex(Object x) { 57 Object n = ct.get(x); 58 if (n == null) { 59 n = new Short (cn++); 60 ct.put(x, n); 61 cv.addElement(x); 62 } 63 return ((Short )n).shortValue(); 64 } 65 66 public short getUtfIndex(String x) { 67 Object n = ut.get(x); 68 if (n == null) { 69 n = new Short (cn++); 70 ut.put(x, n); 71 int xlen = 2 + x.length(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(xlen); 73 DataOutputStream ds = new DataOutputStream(bytes); 74 try { 75 ds.writeByte(CONSTANT_UTF8); 76 ds.writeUTF(x); 77 } catch (IOException ee) { 78 throw new RuntimeException (ee.toString()); 79 } 80 cv.addElement(bytes.toByteArray()); 81 } 82 return ((Short )n).shortValue(); 83 } 84 85 public short getNTIndex(String name, String sig) { 86 NameAndType nt = new NameAndType(); 87 nt.name = getUtfIndex(name); 88 nt.sig = getUtfIndex(sig); 89 return getIndex(nt); 90 } 91 92 public short getClassIndex( Class c ) 93 { 94 short ci = getUtfIndex(c.getName().replace('.', '/')); 95 short data[] = { CONSTANT_CLASS, ci }; 96 return getIndex( data ); 97 } 98 99 public short getMemberIndex(Object cls, String name, Class ptypes[]) { 100 if (cls instanceof Class ) { 101 Class c = (Class ) cls; 102 Member m; 103 try { 104 if (ptypes == null) { 105 m = c.getField(name); 106 } else if (name.equals("<init>")) { 107 m = c.getConstructor(ptypes); 108 } else { 109 m = c.getMethod(name, ptypes); 110 } 111 } catch (NoSuchMethodException ee) { 112 throw new IllegalArgumentException (ee+" in "+c); 113 } catch (NoSuchFieldException ee) { 114 throw new IllegalArgumentException (ee+" in "+c); 115 } 116 return getIndex(m); 117 } else if (cls instanceof ProxyAssembler) { 118 ProxyAssembler asm = (ProxyAssembler) cls; 119 String sig = getSig(null, ptypes); 120 AMember m = asm.findMember(sig, name); 121 if (m == null) { 122 throw new IllegalArgumentException (sig + " " + name); 123 } 124 return getIndex(m); 125 } else { 126 throw new IllegalArgumentException ("not a type: "+cls); 127 } 128 } 129 public short getMemberIndex(Object cls, String name) { 130 return getMemberIndex(cls, name, null); 131 } 132 133 public static String getSig(Class t) { 134 if (t == null) { 135 return ""; 136 } else if (t.isPrimitive()) { 137 if (false) { 138 return ""; 139 } else if (t == Boolean.TYPE) { 140 return "Z"; 141 } else if (t == Character.TYPE) { 142 return "C"; 143 } else if (t == Byte.TYPE) { 144 return "B"; 145 } else if (t == Short.TYPE) { 146 return "S"; 147 } else if (t == Integer.TYPE) { 148 return "I"; 149 } else if (t == Long.TYPE) { 150 return "J"; 151 } else if (t == Float.TYPE) { 152 return "F"; 153 } else if (t == Double.TYPE) { 154 return "D"; 155 } else if (t == Void.TYPE) { 156 return "V"; 157 } else { 158 Class a = java.lang.reflect.Array.newInstance(t, 0).getClass(); 159 return getSig(a).substring(1); 160 } 161 } else if (t.isArray()) { 162 return t.getName().replace('.', '/'); 163 } else { 164 return "L" + t.getName().replace('.', '/') + ";"; 165 } 166 } 167 168 public static String getSig(Class rt, Class pt[]) { 169 if (pt == null) { 170 return getSig(rt); 171 } 172 StringBuffer sb = new StringBuffer (); 173 sb.append("("); 174 for (int i = 0; i < pt.length; i++) { 175 sb.append(getSig(pt[i])); 176 } 177 sb.append(")"); 178 sb.append(getSig(rt)); 179 return sb.toString(); 180 } 181 182 boolean isInterface() { 183 return Modifier.isInterface(modifiers); 184 } 185 186 public ProxyAssembler(String className, int modifiers, 187 Class superClass, Class interfaces[]) { 188 if (interfaces == null) interfaces = new Class [0]; 189 this.className = className; 190 this.modifiers = modifiers; 191 this.superClass = superClass; 192 this.interfaces = interfaces; 193 cv.addElement(null); members = new Vector(); 195 addMember(0, "", null, "" ); 196 } 197 198 private static class AMember { 199 int mods; 200 int sp; 201 int spmax; 202 int locmax; 203 int index; 204 Class type; String sig; 206 String name; 207 Vector attr; 208 Stack stack; 209 ByteArrayOutputStream code; 210 ProxyAssembler asm; 211 } 212 private static class Attr { 213 String name; 214 Object data; 215 } 216 private static class AValue { int num; 218 Object type; 219 } 220 private static class NameAndType { 221 short name; 222 short sig; 223 public boolean equals(Object x) { 225 if (x instanceof NameAndType) { 226 NameAndType that = (NameAndType)x; 227 return that.name == name && that.sig == sig; 228 } 229 return false; 230 } 231 public int hashCode() { 232 return name + sig * 1000; 233 } 234 } 235 236 public Object getCurrentMember() { 237 return current; 238 } 239 public void setCurrentMember(Object m) { 240 if (m == null) { 241 m = members.elementAt(0); 242 } 243 current = (AMember) m; 244 code = current.code; 245 stack = current.stack; 246 } 247 248 AMember findMember(String sig, String name) { 249 for (int i = 0; i < members.size(); i++) { 250 AMember m = (AMember) members.elementAt(i); 251 if (m.name.equals(name)) { 252 if (!sig.startsWith("(") ? !m.sig.startsWith("(") 253 : m.sig.startsWith(sig)) { 254 return m; 255 } 256 } 257 } 258 return null; 259 } 260 261 262 void addExceptionAttribute( Class [] classes ) 263 { 264 try 265 { 266 267 if ((classes == null) || (classes.length == 0)) 268 return; 269 270 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 271 DataOutputStream dos = new DataOutputStream( baos ); 272 short count = (short) classes.length; 273 dos.writeShort( count ); 274 for (int iter=0; iter<classes.length; iter++) 275 { 276 dos.writeShort( getClassIndex(classes[iter]) ); 277 } 278 dos.flush(); 279 baos.flush(); 280 addAttribute( "Exception", baos.toByteArray() ); 281 } 282 catch (IOException cantHappen) 283 { 284 cantHappen.printStackTrace(); 285 } 286 } 287 288 AMember addMember(int mods, String sig, Class [] exceptionClasses, String name) { 289 String qsig = sig.substring(0, 1 + sig.indexOf(')')); 290 AMember m = findMember(qsig, name); 291 if (m != null) { 292 setCurrentMember(m); 293 current.mods |= mods; 294 modifiers |= (mods & Modifier.ABSTRACT); 295 return m; 296 } 297 m = new AMember(); 298 m.asm = this; 299 if (isMethodSig(sig)) { 300 m.code = new ByteArrayOutputStream(); 301 m.stack = new Stack(); 302 } 303 m.sig = sig; 304 m.name = name; 305 m.attr = new Vector(); 306 m.index = members.size(); 307 m.mods = mods; 308 members.addElement(m); 309 setCurrentMember(m); 310 this.addExceptionAttribute( exceptionClasses ); 311 return m; 312 } 313 314 public Object addMember(int mods, Class rtype, String name, Class ptypes[], Class [] exceptionClasses) { 315 AMember m = addMember(mods, getSig(rtype, ptypes), exceptionClasses, name); 316 if (ptypes != null && stack.size() == 0) { 317 if (!Modifier.isStatic(mods)) { 319 declare(this); 320 } 321 for (int i = 0; i < ptypes.length; i++) { 322 declare(ptypes[i]); 323 } 324 } 325 m.type = rtype; 326 this.addExceptionAttribute( exceptionClasses ); 327 return m; 328 } 329 330 public Object addMember(int mods, Class type, Class [] exceptionClasses, String name ) { 331 return addMember(mods, type, name, null, exceptionClasses); 332 } 333 334 public void addAttribute(AMember m, String name, Object data) { 335 if (m == null) { 336 m = (AMember) members.elementAt(0); 337 } 338 Attr a = new Attr(); 339 a.name = name; a.data = data; 340 m.attr.addElement(a); 341 } 342 343 public void addAttribute(String name, Object data) { 344 addAttribute(current, name, data); 345 } 346 347 private final static int opc_iconst_0 = 3, 349 opc_bipush = 16, 350 opc_sipush = 17, 351 opc_ldc = 18, 352 opc_ldc_w = 19, 353 opc_ldc2_w = 20, 354 opc_aaload = 50, 355 opc_aastore = 83, 356 opc_dup = 89, 357 opc_getfield = 180, 358 field_put = 1, 359 field_static = -2, 360 opc_invokevirtual = 182, 361 opc_invokespecial = 183, 362 opc_invokestatic = 184, 363 opc_invokeinterface = 185, 364 opc_new = 187, 365 opc_newarray = 188, 366 opc_anewarray = 189, 367 opc_aload = 25, 368 opc_aload_0 = 42, 369 opc_wide = 196, 370 opc_areturn = 176, 371 opc_return = 177, 372 opc_checkcast = 192, 373 kind_a = 0, 374 kind_i = -4, 375 kind_l = -3, 376 kind_f = -2, 377 kind_d = -1, 378 kind_b = 1, 379 kind_c = 2, 380 kind_s = 3; 381 382 public int declare(Object t) { 383 int n = current.sp; 384 current.sp += 1; 385 if (t == Double.TYPE || t == Long.TYPE) { 386 current.sp += 1; 387 } 388 if (current.spmax < current.sp) { 389 current.spmax = current.sp; 390 } 391 AValue se = new AValue(); 392 se.num = n; se.type = t; 393 stack.push(se); 394 return stack.size() - 1; 395 } 396 397 public void undeclare(Object t) { 398 AValue se = (AValue) stack.pop(); 399 current.sp = se.num; 400 } 401 402 public void pushConstant(Object x) { 403 int op = opc_ldc_w; 404 if (x instanceof Integer ) { 405 declare(Integer.TYPE); 406 int v = ((Integer )x).intValue(); 407 if (v >= -1 && v <= 5) { 408 code.write(opc_iconst_0 + v); 409 return; 410 } else if ((v > -(1 << 7)) && (v < (1 << 7))) { 411 code.write(opc_bipush); 412 code.write(v); 413 return; 414 } else if ((v > -(1 << 15)) && (v < (1 << 15))) { 415 code.write(opc_sipush); 416 codeShort(v); 417 return; 418 } 419 } else if (x instanceof Float ) { 420 declare(Float.TYPE); 421 } else if (x instanceof String ) { 422 declare(String .class); 423 } else if (x instanceof Long ) { 424 declare(Long.TYPE); 425 op = opc_ldc2_w; 426 } else if (x instanceof Double ) { 427 declare(Double.TYPE); 428 op = opc_ldc2_w; 429 } else { 430 throw new RuntimeException ("unexpected: "+x); 431 } 432 int xi = getIndex(x); 433 if (op == opc_ldc_w && xi < (1 << 8)) { 434 code.write(opc_ldc); 435 code.write(xi); 436 } else { 437 code.write(op); 438 codeShort(xi); 439 } 440 } 441 public void pushConstant(int x) { 442 pushConstant(new Integer (x)); 443 } 444 445 public int pushLocal(int loc) { 446 if (current.locmax < loc) { 447 current.locmax = loc; 448 } 449 AValue se = (AValue) stack.elementAt(loc); 450 int kind = typeKind(se.type, false); 451 if (se.num <= 3) { 452 code.write(opc_aload_0 + (kind * 4) + se.num); 453 } else { 454 codeWide(opc_aload + kind, se.num); 455 } 456 return declare(se.type); 457 } 458 459 public int dup() { 460 code.write(opc_dup); 461 return declare(stack.peek()); 462 } 463 464 public void checkCast(Object t) { 465 code.write(opc_checkcast); 466 codeShort(getIndex(t)); 467 AValue se = (AValue) stack.pop(); 468 if (se.type instanceof Class && ((Class )se.type).isPrimitive()) { 469 undeclare(Object .class); declare(t); 471 } 472 se.type = t; 473 } 474 475 public int pushNewArray(Object etype) { 476 int kind = typeKind(etype, true); 477 int tcode; 478 Class t; 479 switch (kind) { 480 case kind_a: 481 code.write(opc_anewarray); 482 codeShort(getIndex(etype)); 483 return declare(Object [].class); 484 case kind_f: 485 tcode = 0x00000006; 486 t = float[].class; 487 break; 488 case kind_d: 489 tcode = 0x00000007; 490 t = double[].class; 491 break; 492 case kind_i: 493 tcode = 0x0000000a; 494 t = int[].class; 495 break; 496 case kind_l: 497 tcode = 0x0000000b; 498 t = long[].class; 499 break; 500 case kind_b: 501 if (etype == Boolean.TYPE) { 502 tcode = 0x00000004; 503 t = boolean[].class; 504 } else { 505 tcode = 0x00000008; 506 t = byte[].class; 507 } 508 break; 509 case kind_c: 510 tcode = 0x00000005; 511 t = char[].class; 512 break; 513 case kind_s: 514 tcode = 0x00000009; 515 t = short[].class; 516 break; 517 default: 518 return 0; 519 } 520 code.write(opc_newarray); 521 code.write(tcode); 522 return declare(t); } 524 525 public void setElement(Object etype) { 526 int kind = typeKind(etype, true); 527 code.write(opc_aastore + kind); 528 undeclare(etype); 529 undeclare(Integer.TYPE); 530 undeclare(null); } 532 533 public void pushElement(Object etype) { 534 int kind = typeKind(etype, true); 535 code.write(opc_aaload + kind); 536 undeclare(Integer.TYPE); 537 undeclare(null); declare(etype); 539 } 540 541 public void ret() { 542 if (current.sig.endsWith("V")) { 543 code.write(opc_return); 544 return; 545 } 546 Object t = current.type; 547 undeclare(t); 548 code.write(opc_areturn + typeKind(t, false)); 549 stack = null; 550 } 551 552 private int dofield(Object cls, String name, boolean isPut) { 553 int fi = getMemberIndex(cls, name); 554 Object x = cv.elementAt(fi); 555 int op = opc_getfield; 556 int mod; 557 Object t; 558 if (x instanceof Field) { 559 Field f = (Field) x; 560 mod = f.getModifiers(); 561 t = f.getType(); 562 } else { 563 AMember m = (AMember) x; 564 mod = m.mods; 565 t = m.type; 566 } 567 if (isPut) { 568 op += field_put; 569 undeclare(t); 570 } 571 if (Modifier.isStatic(mod)) { 572 op += field_static; 573 } else { 574 undeclare(cls); 575 } 576 code.write(op); 577 codeShort(fi); 578 return isPut ? -1 : declare(t); 579 } 580 581 public int pushField(Object cls, String name) { 582 return dofield(cls, name, false); 583 } 584 585 public void setField(Object cls, String name) { 586 dofield(cls, name, true); 587 } 588 589 public int invoke(Object cls, String name, Class ptypes[]) { 590 int mi = getMemberIndex(cls, name, ptypes); 591 Object x = cv.elementAt(mi); 592 int mod; 593 Object rtype; 594 int op = opc_invokevirtual; 595 if (x instanceof Method) { 596 Method m = (Method)x; 597 mod = m.getModifiers(); 598 rtype = m.getReturnType(); 599 if (m.getDeclaringClass().isInterface()) { 600 op = opc_invokeinterface; 601 } 602 } else if (x instanceof Constructor) { 603 Constructor m = (Constructor)x; 604 mod = m.getModifiers(); 605 rtype = Void.TYPE; 606 op = opc_invokespecial; 607 } else { 608 AMember m = (AMember) x; 609 mod = m.mods; 610 rtype = m.type; 611 if (m.asm.isInterface()) { 612 op = opc_invokeinterface; 613 } 614 } 615 if (Modifier.isStatic(mod)) { 616 op = opc_invokestatic; 617 } else { 618 undeclare(cls); 619 } 620 for (int i = ptypes.length; --i >= 0; ) { 621 undeclare(ptypes[i]); 622 } 623 code.write(op); 624 codeShort(mi); 625 return declare(rtype); 626 } 627 628 private int typeKind(Object t, boolean subwords) { 629 if (t != null && t instanceof Class && ((Class )t).isPrimitive()) { 630 if (t == Float.TYPE) { 631 return kind_f; 632 } else if (t == Long.TYPE) { 633 return kind_l; 634 } else if (t == Double.TYPE) { 635 return kind_d; 636 } else if (t == Integer.TYPE || !subwords) { 637 return kind_i; 638 } else if (t == Character.TYPE) { 639 return kind_c; 640 } else if (t == Short.TYPE) { 641 return kind_s; 642 } else { 643 return kind_b; 644 } 645 } else { 646 return kind_a; 647 } 648 } 649 650 private void codeWide(int op, int n) { 651 if (n < (1 << 8)) { 652 code.write(op); 653 code.write(n); 654 } else { 655 code.write(opc_wide); 656 code.write(op); 657 codeShort(n); 658 } 659 } 660 661 private void codeShort(int v) { 662 code.write(v >>> 8); 663 code.write(v); 664 } 665 666 private static boolean isMethodSig(String sig) { 667 return (sig.indexOf('(') >= 0); 668 } 669 670 public byte[] getCode() { 671 try { 672 return internalGetCode(); 673 } catch (IOException ee) { 674 throw new RuntimeException (ee.toString()); 675 } 676 } 677 678 public byte[] internalGetCode() throws IOException { 679 getIndex(this); 681 getIndex(superClass); 682 for (int i = 0; i < interfaces.length; i++) { 683 getIndex(interfaces[i]); 684 } 685 int nfields = 0; 686 int nmethods = 0; 687 for (int i = 0; i < members.size(); i++) { 688 AMember m = (AMember) members.elementAt(i); 689 690 if (m.code != null) { 691 byte[] codeAttr = getMethodCode(m, m.code); 692 if (codeAttr != null) { 693 addAttribute(m, "Code", codeAttr); 694 } 695 } 696 697 for (int j = 0; j < m.attr.size(); j++) { 698 Attr a = (Attr) m.attr.elementAt(j); 699 getUtfIndex(a.name); 700 } 701 702 if (m.name.length() == 0) { 703 continue; 704 } 705 getUtfIndex(m.name); 706 getUtfIndex(m.sig); 707 if (isMethodSig(m.sig)) { 708 nmethods += 1; 709 } else { 710 nfields += 1; 711 } 712 } 713 for (int i = 0; i < cv.size(); i++) { 715 Object x = cv.elementAt(i); 716 if (x == null) { 717 continue; 718 } else if (x instanceof String ) { 719 String s = (String )x; 720 short si = getUtfIndex(s); 721 short data[] = { CONSTANT_STRING, si }; 722 x = data; 723 } 724 else if (x instanceof Class ) { 725 Class c = (Class )x; 726 short ci = getUtfIndex(c.getName().replace('.', '/')); 727 short data[] = { CONSTANT_CLASS, ci }; 728 x = data; 729 } else if (x instanceof Field) { 730 Field m = (Field)x; 731 short ci = getIndex(m.getDeclaringClass()); 732 short nt = getNTIndex(m.getName(), 733 getSig(m.getType())); 734 short data[] = { CONSTANT_FIELD, ci, nt }; 735 x = data; 736 } else if (x instanceof Constructor) { 737 Constructor m = (Constructor)x; 738 short ci = getIndex(m.getDeclaringClass()); 739 short nt = getNTIndex("<init>", 740 getSig(Void.TYPE, 741 m.getParameterTypes())); 742 short data[] = { CONSTANT_METHOD, ci, nt }; 743 x = data; 744 } else if (x instanceof Method) { 745 Method m = (Method)x; 746 Class c = m.getDeclaringClass(); 747 short kind = c.isInterface() ? CONSTANT_INTERFACEMETHOD 748 : CONSTANT_METHOD; 749 short ci = getIndex(c); 750 short nt = getNTIndex(m.getName(), 751 getSig(m.getReturnType(), 752 m.getParameterTypes())); 753 short data[] = { kind, ci, nt }; 754 x = data; 755 } else if (x instanceof ProxyAssembler) { 756 ProxyAssembler asm = (ProxyAssembler)x; 757 short ci = getUtfIndex(asm.className.replace('.', '/')); 758 short data[] = { CONSTANT_CLASS, ci }; 759 x = data; 760 } else if (x instanceof AMember) { 761 AMember m = (AMember) x; 762 short kind = !isMethodSig(m.sig) ? CONSTANT_FIELD 763 : m.asm.isInterface() ? CONSTANT_INTERFACEMETHOD 764 : CONSTANT_METHOD; 765 short ci = getIndex(m.asm); 766 short nt = getNTIndex(m.name, m.sig); 767 short data[] = { kind, ci, nt }; 768 x = data; 769 } else if (x instanceof NameAndType) { 770 NameAndType nt = (NameAndType) x; 771 short data[] = { CONSTANT_NAMEANDTYPE, nt.name, nt.sig }; 772 x = data; 773 } 774 cv.setElementAt(x, i); } 776 777 ByteArrayOutputStream bytes = new ByteArrayOutputStream(400); 778 DataOutputStream ds = new DataOutputStream(bytes); 779 ds.writeInt(JAVA_MAGIC); 780 ds.writeShort(JAVA_MINOR_VERSION); 781 ds.writeShort(JAVA_VERSION); 782 int cvsize = cv.size(); 783 ds.writeShort(cvsize); 784 for (int i = 0; i < cv.size(); i++) { 785 Object x = cv.elementAt(i); 786 if (x == null) { 787 continue; 788 } else if (x instanceof short[]) { 789 short data[] = (short[])x; 790 ds.writeByte(data[0]); 791 for (int j = 1; j < data.length; j++) { 792 ds.writeShort(data[j]); 793 } 794 } else if (x instanceof byte[]) { 795 ds.write((byte[])x); 796 } else if (x instanceof Integer ) { 797 ds.writeByte(CONSTANT_INTEGER); 798 ds.writeInt(((Integer )x).intValue()); 799 } else { 801 throw new RuntimeException ("unexpected"); 802 } 803 } 804 ds.writeShort(modifiers); 805 ds.writeShort(getIndex(this)); 806 ds.writeShort(getIndex(superClass)); 807 ds.writeShort(interfaces.length); 808 for (int i = 0; i < interfaces.length; i++) { 809 ds.writeShort(getIndex(interfaces[i])); 810 } 811 for (int pass = 0; pass <= 1; pass++) { 812 boolean methods = (pass > 0); 813 ds.writeShort(methods ? nmethods : nfields); 814 for (int i = 0; i < members.size(); i++) { 815 AMember m = (AMember) members.elementAt(i); 816 if (m.name.length() == 0 || isMethodSig(m.sig) != methods) { 817 continue; 818 } 819 ds.writeShort(m.mods); 820 ds.writeShort(getUtfIndex(m.name)); 821 ds.writeShort(getUtfIndex(m.sig)); 822 writeAttrs(ds, m.attr); 823 } 824 } 825 AMember m0 = (AMember) members.elementAt(0); 826 writeAttrs(ds, (Vector) m0.attr); 827 828 if (cvsize != cv.size()) { 830 throw new RuntimeException ("cvsize"); 831 } 832 833 return bytes.toByteArray(); 834 } 835 836 private byte[] getMethodCode(AMember m, ByteArrayOutputStream code) throws IOException { 837 if (code.size() == 0) { 838 if ((current.mods & (Modifier.NATIVE | Modifier.ABSTRACT)) == 0) { 839 current.mods |= Modifier.ABSTRACT; 840 modifiers |= Modifier.ABSTRACT; 841 } 842 return null; 843 } 844 ByteArrayOutputStream bytes 845 = new ByteArrayOutputStream(code.size()+30); 846 DataOutputStream ds = new DataOutputStream(bytes); 847 int slop = 10; int max_stack = current.locmax + slop; 849 int max_locals = current.spmax + slop; 850 ds.writeShort(max_stack); 851 ds.writeShort(max_locals); 852 ds.writeInt(code.size()); 853 code.writeTo(ds); 854 ds.writeShort(0); 856 Vector attrs = new Vector(); 857 for (int i = m.attr.size(); --i >= 0; ) { 858 Attr ma = (Attr) m.attr.elementAt(i); 859 if (ma.name.startsWith("Code.")) { 860 m.attr.removeElementAt(i); 861 ma.name = ma.name.substring("Code.".length()); 862 attrs.addElement(ma); 863 getUtfIndex(ma.name); 864 } 865 } 866 writeAttrs(ds, attrs); 867 868 return bytes.toByteArray(); 869 } 870 871 872 private void writeAttrs(DataOutputStream ds, Vector attrs) throws IOException { 873 ds.writeShort(attrs.size()); 874 for (int i = 0; i < attrs.size(); i++) { 875 Attr a = (Attr) attrs.elementAt(i); 876 ds.writeShort(getUtfIndex(a.name)); 877 if (a.data instanceof byte[]) { 878 byte[] xa = (byte[])a.data; 879 ds.writeInt(xa.length); 880 ds.write(xa); 881 } else { 882 throw new RuntimeException ("unexpected"); 883 } 884 } 885 } 886 887 private static final int JAVA_MAGIC = 0xcafebabe; 888 889 private static final short JAVA_VERSION = 45, 890 JAVA_MINOR_VERSION = 3; 891 892 private static final short CONSTANT_UTF8 = 1, 893 CONSTANT_UNICODE = 2, 894 CONSTANT_INTEGER = 3, 895 CONSTANT_FLOAT = 4, 896 CONSTANT_LONG = 5, 897 CONSTANT_DOUBLE = 6, 898 CONSTANT_CLASS = 7, 899 CONSTANT_STRING = 8, 900 CONSTANT_FIELD = 9, 901 CONSTANT_METHOD = 10, 902 CONSTANT_INTERFACEMETHOD = 11, 903 CONSTANT_NAMEANDTYPE = 12; 904 905 } 906 907 | Popular Tags |