1 30 31 package oracle.toplink.libraries.asm.util; 32 33 import java.io.FileInputStream ; 34 import java.io.PrintWriter ; 35 36 import oracle.toplink.libraries.asm.Attribute; 37 import oracle.toplink.libraries.asm.ClassReader; 38 import oracle.toplink.libraries.asm.CodeVisitor; 39 import oracle.toplink.libraries.asm.Constants; 40 import oracle.toplink.libraries.asm.Type; 41 import oracle.toplink.libraries.asm.util.attrs.ASMifiable; 42 43 111 112 public class ASMifierClassVisitor extends PrintClassVisitor { 113 114 private static final int ACCESS_CLASS = 262144; 115 private static final int ACCESS_FIELD = 524288; 116 private static final int ACCESS_INNER = 1048576; 117 118 130 131 public static void main (final String [] args) throws Exception { 132 if (args.length < 1 || args.length > 2) { 133 printUsage(); 134 } 135 int i = 0; 136 boolean skipDebug = true; 137 if (args[0].equals("-debug")) { 138 i = 1; 139 skipDebug = false; 140 if (args.length != 2) { 141 printUsage(); 142 } 143 } 144 ClassReader cr; 145 if (args[i].endsWith(".class")) { 146 cr = new ClassReader(new FileInputStream (args[i])); 147 } else { 148 cr = new ClassReader(args[i]); 149 } 150 cr.accept(new ASMifierClassVisitor( 151 new PrintWriter (System.out)), getDefaultAttributes(), skipDebug); 152 } 153 154 private static void printUsage () { 155 System.err.println("Prints the ASM code to generate the given class."); 156 System.err.println("Usage: ASMifierClassVisitor [-debug] " + 157 "<fully qualified class name or class file name>"); 158 System.exit(-1); 159 } 160 161 166 167 public ASMifierClassVisitor (final PrintWriter pw) { 168 super(pw); 169 } 170 171 public void visit ( 172 final int version, 173 final int access, 174 final String name, 175 final String superName, 176 final String [] interfaces, 177 final String sourceFile) 178 { 179 int n = name.lastIndexOf( "/"); 180 if( n>-1) { 181 text.add("package asm."+name.substring( 0, n).replace( '/', '.')+";\n"); 182 } 183 184 text.add("import oracle.toplink.libraries.asm.*;\n"); 185 text.add("import oracle.toplink.libraries.asm.attrs.*;\n"); 186 text.add("import java.util.*;\n\n"); 187 text.add("public class "+(n==-1 ? name : name.substring( n+1))+"Dump implements Constants {\n\n"); 188 text.add("public static byte[] dump () throws Exception {\n\n"); 189 text.add("ClassWriter cw = new ClassWriter(false);\n"); 190 text.add("CodeVisitor cv;\n\n"); 191 192 buf.setLength(0); 193 buf.append("cw.visit("); 194 switch(version) { 195 case Constants.V1_1: 196 buf.append("V1_1"); 197 break; 198 199 case Constants.V1_2: 200 buf.append("V1_2"); 201 break; 202 203 case Constants.V1_3: 204 buf.append("V1_3"); 205 break; 206 207 case Constants.V1_4: 208 buf.append("V1_4"); 209 break; 210 211 case Constants.V1_5: 212 buf.append("V1_5"); 213 break; 214 215 default: 216 buf.append(version); 217 break; 218 } 219 buf.append(", "); 220 appendAccess(access | ACCESS_CLASS); 221 buf.append(", "); 222 appendConstant(buf, name); 223 buf.append(", "); 224 appendConstant(buf, superName); 225 buf.append(", "); 226 if (interfaces != null && interfaces.length > 0) { 227 buf.append("new String[] {"); 228 for (int i = 0; i < interfaces.length; ++i) { 229 buf.append(i == 0 ? " " : ", "); 230 appendConstant(buf, interfaces[i]); 231 } 232 buf.append(" }"); 233 } else { 234 buf.append("null"); 235 } 236 buf.append(", "); 237 appendConstant(buf, sourceFile); 238 buf.append(");\n\n"); 239 text.add(buf.toString()); 240 } 241 242 public void visitInnerClass ( 243 final String name, 244 final String outerName, 245 final String innerName, 246 final int access) 247 { 248 buf.setLength(0); 249 buf.append("cw.visitInnerClass("); 250 appendConstant(buf, name); 251 buf.append(", "); 252 appendConstant(buf, outerName); 253 buf.append(", "); 254 appendConstant(buf, innerName); 255 buf.append(", "); 256 appendAccess(access | ACCESS_INNER); 257 buf.append(");\n\n"); 258 text.add(buf.toString()); 259 } 260 261 public void visitField ( 262 final int access, 263 final String name, 264 final String desc, 265 final Object value, 266 final Attribute attrs) 267 { 268 buf.setLength(0); 269 270 int n = 1; 271 if (attrs != null) { 272 buf.append("{\n"); 273 buf.append("// FIELD ATTRIBUTES\n"); 274 Attribute a = attrs; 275 while (a != null) { 276 if (a instanceof ASMifiable) { 277 ((ASMifiable)a).asmify(buf, "fieldAttrs" + n, null); 278 if (n > 1) { 279 buf.append("fieldAttrs" + (n - 1) + " = fieldAttrs" + n + ";\n"); 280 } 281 n++; 282 } else { 283 buf.append("// WARNING! skipped non standard field attribute of type "); 284 buf.append(a.type).append("\n"); 285 } 286 a = a.next; 287 } 288 } 289 290 buf.append("cw.visitField("); 291 appendAccess(access | ACCESS_FIELD); 292 buf.append(", "); 293 appendConstant(buf, name); 294 buf.append(", "); 295 appendConstant(buf, desc); 296 buf.append(", "); 297 appendConstant(buf, value); 298 299 if (n==1) { 300 buf.append(", null);\n\n"); 301 } else { 302 buf.append(", fieldAttrs1);\n"); 303 buf.append("}\n\n"); 304 } 305 306 text.add(buf.toString()); 307 } 308 309 public CodeVisitor visitMethod ( 310 final int access, 311 final String name, 312 final String desc, 313 final String [] exceptions, 314 final Attribute attrs) 315 { 316 buf.setLength(0); 317 318 buf.append("{\n"); 319 320 int n = 1; 321 if (attrs != null) { 322 buf.append("// METHOD ATTRIBUTES\n"); 323 Attribute a = attrs; 324 while (a != null) { 325 if (a instanceof ASMifiable) { 326 ((ASMifiable)a).asmify(buf, "methodAttrs" + n, null); 327 if (n > 1) { 328 buf.append("methodAttrs" + (n - 1) + ".next = methodAttrs" + n + ";\n"); 329 } 330 n++; 331 } else { 332 buf.append("// WARNING! skipped non standard method attribute of type "); 333 buf.append(a.type).append("\n"); 334 } 335 a = a.next; 336 } 337 } 338 339 buf.append("cv = cw.visitMethod("); 340 appendAccess(access); 341 buf.append(", "); 342 appendConstant(buf, name); 343 buf.append(", "); 344 appendConstant(buf, desc); 345 buf.append(", "); 346 if (exceptions != null && exceptions.length > 0) { 347 buf.append("new String[] {"); 348 for (int i = 0; i < exceptions.length; ++i) { 349 buf.append(i == 0 ? " " : ", "); 350 appendConstant(buf, exceptions[i]); 351 } 352 buf.append(" }"); 353 } else { 354 buf.append("null"); 355 } 356 if (n==1) { 357 buf.append(", null);\n"); 358 } else { 359 buf.append(", methodAttrs1);\n"); 360 } 361 362 text.add(buf.toString()); 363 PrintCodeVisitor pcv = new ASMifierCodeVisitor(); 364 text.add(pcv.getText()); 365 text.add("}\n"); 366 return pcv; 367 } 368 369 public void visitAttribute (final Attribute attr) { 370 buf.setLength(0); 371 if (attr instanceof ASMifiable) { 372 buf.append("{\n"); 373 buf.append("// CLASS ATRIBUTE\n"); 374 ((ASMifiable)attr).asmify(buf, "attr", null); 375 buf.append("cw.visitAttribute(attr);\n"); 376 buf.append("}\n"); 377 } else { 378 buf.append("// WARNING! skipped a non standard class attribute of type \""); 379 buf.append(attr.type).append("\"\n"); 380 } 381 text.add(buf.toString()); 382 } 383 384 public void visitEnd () { 385 text.add("cw.visitEnd();\n\n"); 386 text.add("return cw.toByteArray();\n"); 390 text.add("}\n"); 391 text.add("}\n"); 392 super.visitEnd(); 393 } 394 395 401 402 void appendAccess (final int access) { 403 boolean first = true; 404 if ((access & Constants.ACC_PUBLIC) != 0) { 405 buf.append("ACC_PUBLIC"); 406 first = false; 407 } 408 if ((access & Constants.ACC_PRIVATE) != 0) { 409 if (!first) { 410 buf.append(" + "); 411 } 412 buf.append("ACC_PRIVATE"); 413 first = false; 414 } 415 if ((access & Constants.ACC_PROTECTED) != 0) { 416 if (!first) { 417 buf.append(" + "); 418 } 419 buf.append("ACC_PROTECTED"); 420 first = false; 421 } 422 if ((access & Constants.ACC_FINAL) != 0) { 423 if (!first) { 424 buf.append(" + "); 425 } 426 buf.append("ACC_FINAL"); 427 first = false; 428 } 429 if ((access & Constants.ACC_STATIC) != 0) { 430 if (!first) { 431 buf.append(" + "); 432 } 433 buf.append("ACC_STATIC"); 434 first = false; 435 } 436 if ((access & Constants.ACC_SYNCHRONIZED) != 0) { 437 if (!first) { 438 buf.append(" + "); 439 } 440 if ((access & ACCESS_CLASS) != 0) { 441 buf.append("ACC_SUPER"); 442 } else { 443 buf.append("ACC_SYNCHRONIZED"); 444 } 445 first = false; 446 } 447 if ((access & Constants.ACC_VOLATILE) != 0 && (access & ACCESS_FIELD) != 0 ) { 448 if (!first) { 449 buf.append(" + "); 450 } 451 buf.append("ACC_VOLATILE"); 452 first = false; 453 } 454 if ((access & Constants.ACC_BRIDGE) != 0 && 455 (access & ACCESS_CLASS) == 0 && (access & ACCESS_FIELD) == 0) { 456 if (!first) { 457 buf.append(" + "); 458 } 459 buf.append("ACC_BRIDGE"); 460 first = false; 461 } 462 if ((access & Constants.ACC_VARARGS) != 0 && 463 (access & ACCESS_CLASS) == 0 && (access & ACCESS_FIELD) == 0) { 464 if (!first) { 465 buf.append(" + "); 466 } 467 buf.append("ACC_VARARGS"); 468 first = false; 469 } 470 if ((access & Constants.ACC_TRANSIENT) != 0 && 471 (access & ACCESS_FIELD) != 0) { 472 if (!first) { 473 buf.append(" + "); 474 } 475 buf.append("ACC_TRANSIENT"); 476 first = false; 477 } 478 if ((access & Constants.ACC_NATIVE) != 0 && 479 (access & ACCESS_CLASS) == 0 && 480 (access & ACCESS_FIELD) == 0) { 481 if (!first) { 482 buf.append(" + "); 483 } 484 buf.append("ACC_NATIVE"); 485 first = false; 486 } 487 if ((access & Constants.ACC_ENUM) != 0 && 488 ((access & ACCESS_CLASS) != 0 || 489 (access & ACCESS_FIELD) != 0 || 490 (access & ACCESS_INNER) != 0)) { 491 if (!first) { 492 buf.append(" + "); 493 } 494 buf.append("ACC_ENUM"); 495 first = false; 496 } 497 if ((access & Constants.ACC_ANNOTATION) != 0 && 498 ((access & ACCESS_CLASS) != 0)) { 499 if (!first) { 500 buf.append(" + "); 501 } 502 buf.append("ACC_ANNOTATION"); 503 first = false; 504 } 505 if ((access & Constants.ACC_ABSTRACT) != 0) { 506 if (!first) { 507 buf.append(" + "); 508 } 509 buf.append("ACC_ABSTRACT"); 510 first = false; 511 } 512 if ((access & Constants.ACC_INTERFACE) != 0) { 513 if (!first) { 514 buf.append(" + "); 515 } 516 buf.append("ACC_INTERFACE"); 517 first = false; 518 } 519 if ((access & Constants.ACC_STRICT) != 0) { 520 if (!first) { 521 buf.append(" + "); 522 } 523 buf.append("ACC_STRICT"); 524 first = false; 525 } 526 if ((access & Constants.ACC_SYNTHETIC) != 0) { 527 if (!first) { 528 buf.append(" + "); 529 } 530 buf.append("ACC_SYNTHETIC"); 531 first = false; 532 } 533 if ((access & Constants.ACC_DEPRECATED) != 0) { 534 if (!first) { 535 buf.append(" + "); 536 } 537 buf.append("ACC_DEPRECATED"); 538 first = false; 539 } 540 if (first) { 541 buf.append("0"); 542 } 543 } 544 545 553 554 static void appendConstant (final StringBuffer buf, final Object cst) { 555 if (cst == null) { 556 buf.append("null"); 557 } else if (cst instanceof String ) { 558 String s = (String )cst; 559 buf.append("\""); 560 for (int i = 0; i < s.length(); ++i) { 561 char c = s.charAt(i); 562 if (c == '\n') { 563 buf.append("\\n"); 564 } else if (c == '\r') { 565 buf.append("\\r"); 566 } else if (c == '\\') { 567 buf.append("\\\\"); 568 } else if (c == '"') { 569 buf.append("\\\""); 570 } else if( c<0x20 || c>0x7f) { 571 buf.append( "\\u"); 572 if( c<0x10) { 573 buf.append( "000"); 574 } else if( c<0x100) { 575 buf.append( "00"); 576 } else if( c<0x1000) { 577 buf.append( "0"); 578 } 579 buf.append( Integer.toString( c, 16)); 580 } else { 581 buf.append(c); 582 } 583 } 584 buf.append("\""); 585 } else if (cst instanceof Type) { 586 buf.append("Type.getType(\""); 587 buf.append(((Type)cst).getDescriptor()); 588 buf.append("\")"); 589 } else if (cst instanceof Integer ) { 590 buf.append("new Integer(") 591 .append(cst) 592 .append(")"); 593 } else if (cst instanceof Float ) { 594 buf.append("new Float(\"") 595 .append(cst).append("\")"); 596 } else if (cst instanceof Long ) { 597 buf.append("new Long(") 598 .append(cst) 599 .append("L)"); 600 } else if (cst instanceof Double ) { 601 buf.append("new Double(\"") 602 .append(cst).append("\")"); 603 } 604 } 605 } 606 | Popular Tags |