1 30 package com.tc.asm.xml; 31 32 import java.io.IOException ; 33 import java.io.OutputStream ; 34 import java.util.ArrayList ; 35 import java.util.HashMap ; 36 import java.util.Iterator ; 37 import java.util.List ; 38 import java.util.Map ; 39 40 import com.tc.asm.AnnotationVisitor; 41 import com.tc.asm.ClassVisitor; 42 import com.tc.asm.ClassWriter; 43 import com.tc.asm.FieldVisitor; 44 import com.tc.asm.MethodVisitor; 45 import com.tc.asm.Opcodes; 46 import com.tc.asm.Label; 47 import com.tc.asm.Type; 48 49 import org.xml.sax.Attributes ; 50 import org.xml.sax.SAXException ; 51 import org.xml.sax.helpers.DefaultHandler ; 52 53 63 public class ASMContentHandler extends DefaultHandler implements Opcodes { 64 67 private List stack = new ArrayList (); 68 69 72 private String match = ""; 73 74 78 protected boolean computeMax; 79 80 83 protected OutputStream os; 84 85 89 protected ClassWriter cw; 90 91 94 protected Map labels; 95 96 private static final String BASE = "class"; 97 98 private final RuleSet RULES = new RuleSet(); 99 { 100 RULES.add(BASE, new ClassRule()); 101 RULES.add(BASE + "/interfaces/interface", new InterfaceRule()); 102 RULES.add(BASE + "/interfaces", new InterfacesRule()); 103 RULES.add(BASE + "/outerclass", new OuterClassRule()); 104 RULES.add(BASE + "/innerclass", new InnerClassRule()); 105 RULES.add(BASE + "/source", new SourceRule()); 106 RULES.add(BASE + "/field", new FieldRule()); 107 108 RULES.add(BASE + "/method", new MethodRule()); 109 RULES.add(BASE + "/method/exceptions/exception", new ExceptionRule()); 110 RULES.add(BASE + "/method/exceptions", new ExceptionsRule()); 111 112 RULES.add(BASE + "/method/annotationDefault", 113 new AnnotationDefaultRule()); 114 115 RULES.add(BASE + "/method/code/*", new OpcodesRule()); 117 RULES.add(BASE + "/method/code/TABLESWITCH", new TableSwitchRule()); 118 RULES.add(BASE + "/method/code/TABLESWITCH/label", 119 new TableSwitchLabelRule()); 120 RULES.add(BASE + "/method/code/LOOKUPSWITCH", new LookupSwitchRule()); 121 RULES.add(BASE + "/method/code/LOOKUPSWITCH/label", 122 new LookupSwitchLabelRule()); 123 124 RULES.add(BASE + "/method/code/Label", new LabelRule()); 125 RULES.add(BASE + "/method/code/TryCatch", new TryCatchRule()); 126 RULES.add(BASE + "/method/code/LineNumber", new LineNumberRule()); 127 RULES.add(BASE + "/method/code/LocalVar", new LocalVarRule()); 128 RULES.add(BASE + "/method/code/Max", new MaxRule()); 129 130 RULES.add("*/annotation", new AnnotationRule()); 131 RULES.add("*/parameterAnnotation", new AnnotationParameterRule()); 132 RULES.add("*/annotationValue", new AnnotationValueRule()); 133 RULES.add("*/annotationValueAnnotation", 134 new AnnotationValueAnnotationRule()); 135 RULES.add("*/annotationValueEnum", new AnnotationValueEnumRule()); 136 RULES.add("*/annotationValueArray", new AnnotationValueArrayRule()); 137 }; 138 139 private static interface OpcodeGroup { 140 public static final int INSN = 0; 141 public static final int INSN_INT = 1; 142 public static final int INSN_VAR = 2; 143 public static final int INSN_TYPE = 3; 144 public static final int INSN_FIELD = 4; 145 public static final int INSN_METHOD = 5; 146 public static final int INSN_JUMP = 6; 147 public static final int INSN_LDC = 7; 148 public static final int INSN_IINC = 8; 149 public static final int INSN_MULTIANEWARRAY = 9; 150 } 151 152 155 static final Map OPCODES = new HashMap (); 156 static { 157 OPCODES.put("NOP", new Opcode(NOP, OpcodeGroup.INSN)); 158 OPCODES.put("ACONST_NULL", new Opcode(ACONST_NULL, OpcodeGroup.INSN)); 159 OPCODES.put("ICONST_M1", new Opcode(ICONST_M1, OpcodeGroup.INSN)); 160 OPCODES.put("ICONST_0", new Opcode(ICONST_0, OpcodeGroup.INSN)); 161 OPCODES.put("ICONST_1", new Opcode(ICONST_1, OpcodeGroup.INSN)); 162 OPCODES.put("ICONST_2", new Opcode(ICONST_2, OpcodeGroup.INSN)); 163 OPCODES.put("ICONST_3", new Opcode(ICONST_3, OpcodeGroup.INSN)); 164 OPCODES.put("ICONST_4", new Opcode(ICONST_4, OpcodeGroup.INSN)); 165 OPCODES.put("ICONST_5", new Opcode(ICONST_5, OpcodeGroup.INSN)); 166 OPCODES.put("LCONST_0", new Opcode(LCONST_0, OpcodeGroup.INSN)); 167 OPCODES.put("LCONST_1", new Opcode(LCONST_1, OpcodeGroup.INSN)); 168 OPCODES.put("FCONST_0", new Opcode(FCONST_0, OpcodeGroup.INSN)); 169 OPCODES.put("FCONST_1", new Opcode(FCONST_1, OpcodeGroup.INSN)); 170 OPCODES.put("FCONST_2", new Opcode(FCONST_2, OpcodeGroup.INSN)); 171 OPCODES.put("DCONST_0", new Opcode(DCONST_0, OpcodeGroup.INSN)); 172 OPCODES.put("DCONST_1", new Opcode(DCONST_1, OpcodeGroup.INSN)); 173 OPCODES.put("BIPUSH", new Opcode(BIPUSH, OpcodeGroup.INSN_INT)); 174 OPCODES.put("SIPUSH", new Opcode(SIPUSH, OpcodeGroup.INSN_INT)); 175 OPCODES.put("LDC", new Opcode(LDC, OpcodeGroup.INSN_LDC)); 176 OPCODES.put("ILOAD", new Opcode(ILOAD, OpcodeGroup.INSN_VAR)); 177 OPCODES.put("LLOAD", new Opcode(LLOAD, OpcodeGroup.INSN_VAR)); 178 OPCODES.put("FLOAD", new Opcode(FLOAD, OpcodeGroup.INSN_VAR)); 179 OPCODES.put("DLOAD", new Opcode(DLOAD, OpcodeGroup.INSN_VAR)); 180 OPCODES.put("ALOAD", new Opcode(ALOAD, OpcodeGroup.INSN_VAR)); 181 OPCODES.put("IALOAD", new Opcode(IALOAD, OpcodeGroup.INSN)); 182 OPCODES.put("LALOAD", new Opcode(LALOAD, OpcodeGroup.INSN)); 183 OPCODES.put("FALOAD", new Opcode(FALOAD, OpcodeGroup.INSN)); 184 OPCODES.put("DALOAD", new Opcode(DALOAD, OpcodeGroup.INSN)); 185 OPCODES.put("AALOAD", new Opcode(AALOAD, OpcodeGroup.INSN)); 186 OPCODES.put("BALOAD", new Opcode(BALOAD, OpcodeGroup.INSN)); 187 OPCODES.put("CALOAD", new Opcode(CALOAD, OpcodeGroup.INSN)); 188 OPCODES.put("SALOAD", new Opcode(SALOAD, OpcodeGroup.INSN)); 189 OPCODES.put("ISTORE", new Opcode(ISTORE, OpcodeGroup.INSN_VAR)); 190 OPCODES.put("LSTORE", new Opcode(LSTORE, OpcodeGroup.INSN_VAR)); 191 OPCODES.put("FSTORE", new Opcode(FSTORE, OpcodeGroup.INSN_VAR)); 192 OPCODES.put("DSTORE", new Opcode(DSTORE, OpcodeGroup.INSN_VAR)); 193 OPCODES.put("ASTORE", new Opcode(ASTORE, OpcodeGroup.INSN_VAR)); 194 OPCODES.put("IASTORE", new Opcode(IASTORE, OpcodeGroup.INSN)); 195 OPCODES.put("LASTORE", new Opcode(LASTORE, OpcodeGroup.INSN)); 196 OPCODES.put("FASTORE", new Opcode(FASTORE, OpcodeGroup.INSN)); 197 OPCODES.put("DASTORE", new Opcode(DASTORE, OpcodeGroup.INSN)); 198 OPCODES.put("AASTORE", new Opcode(AASTORE, OpcodeGroup.INSN)); 199 OPCODES.put("BASTORE", new Opcode(BASTORE, OpcodeGroup.INSN)); 200 OPCODES.put("CASTORE", new Opcode(CASTORE, OpcodeGroup.INSN)); 201 OPCODES.put("SASTORE", new Opcode(SASTORE, OpcodeGroup.INSN)); 202 OPCODES.put("POP", new Opcode(POP, OpcodeGroup.INSN)); 203 OPCODES.put("POP2", new Opcode(POP2, OpcodeGroup.INSN)); 204 OPCODES.put("DUP", new Opcode(DUP, OpcodeGroup.INSN)); 205 OPCODES.put("DUP_X1", new Opcode(DUP_X1, OpcodeGroup.INSN)); 206 OPCODES.put("DUP_X2", new Opcode(DUP_X2, OpcodeGroup.INSN)); 207 OPCODES.put("DUP2", new Opcode(DUP2, OpcodeGroup.INSN)); 208 OPCODES.put("DUP2_X1", new Opcode(DUP2_X1, OpcodeGroup.INSN)); 209 OPCODES.put("DUP2_X2", new Opcode(DUP2_X2, OpcodeGroup.INSN)); 210 OPCODES.put("SWAP", new Opcode(SWAP, OpcodeGroup.INSN)); 211 OPCODES.put("IADD", new Opcode(IADD, OpcodeGroup.INSN)); 212 OPCODES.put("LADD", new Opcode(LADD, OpcodeGroup.INSN)); 213 OPCODES.put("FADD", new Opcode(FADD, OpcodeGroup.INSN)); 214 OPCODES.put("DADD", new Opcode(DADD, OpcodeGroup.INSN)); 215 OPCODES.put("ISUB", new Opcode(ISUB, OpcodeGroup.INSN)); 216 OPCODES.put("LSUB", new Opcode(LSUB, OpcodeGroup.INSN)); 217 OPCODES.put("FSUB", new Opcode(FSUB, OpcodeGroup.INSN)); 218 OPCODES.put("DSUB", new Opcode(DSUB, OpcodeGroup.INSN)); 219 OPCODES.put("IMUL", new Opcode(IMUL, OpcodeGroup.INSN)); 220 OPCODES.put("LMUL", new Opcode(LMUL, OpcodeGroup.INSN)); 221 OPCODES.put("FMUL", new Opcode(FMUL, OpcodeGroup.INSN)); 222 OPCODES.put("DMUL", new Opcode(DMUL, OpcodeGroup.INSN)); 223 OPCODES.put("IDIV", new Opcode(IDIV, OpcodeGroup.INSN)); 224 OPCODES.put("LDIV", new Opcode(LDIV, OpcodeGroup.INSN)); 225 OPCODES.put("FDIV", new Opcode(FDIV, OpcodeGroup.INSN)); 226 OPCODES.put("DDIV", new Opcode(DDIV, OpcodeGroup.INSN)); 227 OPCODES.put("IREM", new Opcode(IREM, OpcodeGroup.INSN)); 228 OPCODES.put("LREM", new Opcode(LREM, OpcodeGroup.INSN)); 229 OPCODES.put("FREM", new Opcode(FREM, OpcodeGroup.INSN)); 230 OPCODES.put("DREM", new Opcode(DREM, OpcodeGroup.INSN)); 231 OPCODES.put("INEG", new Opcode(INEG, OpcodeGroup.INSN)); 232 OPCODES.put("LNEG", new Opcode(LNEG, OpcodeGroup.INSN)); 233 OPCODES.put("FNEG", new Opcode(FNEG, OpcodeGroup.INSN)); 234 OPCODES.put("DNEG", new Opcode(DNEG, OpcodeGroup.INSN)); 235 OPCODES.put("ISHL", new Opcode(ISHL, OpcodeGroup.INSN)); 236 OPCODES.put("LSHL", new Opcode(LSHL, OpcodeGroup.INSN)); 237 OPCODES.put("ISHR", new Opcode(ISHR, OpcodeGroup.INSN)); 238 OPCODES.put("LSHR", new Opcode(LSHR, OpcodeGroup.INSN)); 239 OPCODES.put("IUSHR", new Opcode(IUSHR, OpcodeGroup.INSN)); 240 OPCODES.put("LUSHR", new Opcode(LUSHR, OpcodeGroup.INSN)); 241 OPCODES.put("IAND", new Opcode(IAND, OpcodeGroup.INSN)); 242 OPCODES.put("LAND", new Opcode(LAND, OpcodeGroup.INSN)); 243 OPCODES.put("IOR", new Opcode(IOR, OpcodeGroup.INSN)); 244 OPCODES.put("LOR", new Opcode(LOR, OpcodeGroup.INSN)); 245 OPCODES.put("IXOR", new Opcode(IXOR, OpcodeGroup.INSN)); 246 OPCODES.put("LXOR", new Opcode(LXOR, OpcodeGroup.INSN)); 247 OPCODES.put("IINC", new Opcode(IINC, OpcodeGroup.INSN_IINC)); 248 OPCODES.put("I2L", new Opcode(I2L, OpcodeGroup.INSN)); 249 OPCODES.put("I2F", new Opcode(I2F, OpcodeGroup.INSN)); 250 OPCODES.put("I2D", new Opcode(I2D, OpcodeGroup.INSN)); 251 OPCODES.put("L2I", new Opcode(L2I, OpcodeGroup.INSN)); 252 OPCODES.put("L2F", new Opcode(L2F, OpcodeGroup.INSN)); 253 OPCODES.put("L2D", new Opcode(L2D, OpcodeGroup.INSN)); 254 OPCODES.put("F2I", new Opcode(F2I, OpcodeGroup.INSN)); 255 OPCODES.put("F2L", new Opcode(F2L, OpcodeGroup.INSN)); 256 OPCODES.put("F2D", new Opcode(F2D, OpcodeGroup.INSN)); 257 OPCODES.put("D2I", new Opcode(D2I, OpcodeGroup.INSN)); 258 OPCODES.put("D2L", new Opcode(D2L, OpcodeGroup.INSN)); 259 OPCODES.put("D2F", new Opcode(D2F, OpcodeGroup.INSN)); 260 OPCODES.put("I2B", new Opcode(I2B, OpcodeGroup.INSN)); 261 OPCODES.put("I2C", new Opcode(I2C, OpcodeGroup.INSN)); 262 OPCODES.put("I2S", new Opcode(I2S, OpcodeGroup.INSN)); 263 OPCODES.put("LCMP", new Opcode(LCMP, OpcodeGroup.INSN)); 264 OPCODES.put("FCMPL", new Opcode(FCMPL, OpcodeGroup.INSN)); 265 OPCODES.put("FCMPG", new Opcode(FCMPG, OpcodeGroup.INSN)); 266 OPCODES.put("DCMPL", new Opcode(DCMPL, OpcodeGroup.INSN)); 267 OPCODES.put("DCMPG", new Opcode(DCMPG, OpcodeGroup.INSN)); 268 OPCODES.put("IFEQ", new Opcode(IFEQ, OpcodeGroup.INSN_JUMP)); 269 OPCODES.put("IFNE", new Opcode(IFNE, OpcodeGroup.INSN_JUMP)); 270 OPCODES.put("IFLT", new Opcode(IFLT, OpcodeGroup.INSN_JUMP)); 271 OPCODES.put("IFGE", new Opcode(IFGE, OpcodeGroup.INSN_JUMP)); 272 OPCODES.put("IFGT", new Opcode(IFGT, OpcodeGroup.INSN_JUMP)); 273 OPCODES.put("IFLE", new Opcode(IFLE, OpcodeGroup.INSN_JUMP)); 274 OPCODES.put("IF_ICMPEQ", new Opcode(IF_ICMPEQ, OpcodeGroup.INSN_JUMP)); 275 OPCODES.put("IF_ICMPNE", new Opcode(IF_ICMPNE, OpcodeGroup.INSN_JUMP)); 276 OPCODES.put("IF_ICMPLT", new Opcode(IF_ICMPLT, OpcodeGroup.INSN_JUMP)); 277 OPCODES.put("IF_ICMPGE", new Opcode(IF_ICMPGE, OpcodeGroup.INSN_JUMP)); 278 OPCODES.put("IF_ICMPGT", new Opcode(IF_ICMPGT, OpcodeGroup.INSN_JUMP)); 279 OPCODES.put("IF_ICMPLE", new Opcode(IF_ICMPLE, OpcodeGroup.INSN_JUMP)); 280 OPCODES.put("IF_ACMPEQ", new Opcode(IF_ACMPEQ, OpcodeGroup.INSN_JUMP)); 281 OPCODES.put("IF_ACMPNE", new Opcode(IF_ACMPNE, OpcodeGroup.INSN_JUMP)); 282 OPCODES.put("GOTO", new Opcode(GOTO, OpcodeGroup.INSN_JUMP)); 283 OPCODES.put("JSR", new Opcode(JSR, OpcodeGroup.INSN_JUMP)); 284 OPCODES.put("RET", new Opcode(RET, OpcodeGroup.INSN_VAR)); 285 OPCODES.put("IRETURN", new Opcode(IRETURN, OpcodeGroup.INSN)); 290 OPCODES.put("LRETURN", new Opcode(LRETURN, OpcodeGroup.INSN)); 291 OPCODES.put("FRETURN", new Opcode(FRETURN, OpcodeGroup.INSN)); 292 OPCODES.put("DRETURN", new Opcode(DRETURN, OpcodeGroup.INSN)); 293 OPCODES.put("ARETURN", new Opcode(ARETURN, OpcodeGroup.INSN)); 294 OPCODES.put("RETURN", new Opcode(RETURN, OpcodeGroup.INSN)); 295 OPCODES.put("GETSTATIC", new Opcode(GETSTATIC, OpcodeGroup.INSN_FIELD)); 296 OPCODES.put("PUTSTATIC", new Opcode(PUTSTATIC, OpcodeGroup.INSN_FIELD)); 297 OPCODES.put("GETFIELD", new Opcode(GETFIELD, OpcodeGroup.INSN_FIELD)); 298 OPCODES.put("PUTFIELD", new Opcode(PUTFIELD, OpcodeGroup.INSN_FIELD)); 299 OPCODES.put("INVOKEVIRTUAL", new Opcode(INVOKEVIRTUAL, 300 OpcodeGroup.INSN_METHOD)); 301 OPCODES.put("INVOKESPECIAL", new Opcode(INVOKESPECIAL, 302 OpcodeGroup.INSN_METHOD)); 303 OPCODES.put("INVOKESTATIC", new Opcode(INVOKESTATIC, 304 OpcodeGroup.INSN_METHOD)); 305 OPCODES.put("INVOKEINTERFACE", new Opcode(INVOKEINTERFACE, 306 OpcodeGroup.INSN_METHOD)); 307 OPCODES.put("NEW", new Opcode(NEW, OpcodeGroup.INSN_TYPE)); 308 OPCODES.put("NEWARRAY", new Opcode(NEWARRAY, OpcodeGroup.INSN_INT)); 309 OPCODES.put("ANEWARRAY", new Opcode(ANEWARRAY, OpcodeGroup.INSN_TYPE)); 310 OPCODES.put("ARRAYLENGTH", new Opcode(ARRAYLENGTH, OpcodeGroup.INSN)); 311 OPCODES.put("ATHROW", new Opcode(ATHROW, OpcodeGroup.INSN)); 312 OPCODES.put("CHECKCAST", new Opcode(CHECKCAST, OpcodeGroup.INSN_TYPE)); 313 OPCODES.put("INSTANCEOF", new Opcode(INSTANCEOF, OpcodeGroup.INSN_TYPE)); 314 OPCODES.put("MONITORENTER", new Opcode(MONITORENTER, OpcodeGroup.INSN)); 315 OPCODES.put("MONITOREXIT", new Opcode(MONITOREXIT, OpcodeGroup.INSN)); 316 OPCODES.put("MULTIANEWARRAY", new Opcode(MULTIANEWARRAY, 317 OpcodeGroup.INSN_MULTIANEWARRAY)); 318 OPCODES.put("IFNULL", new Opcode(IFNULL, OpcodeGroup.INSN_JUMP)); 319 OPCODES.put("IFNONNULL", new Opcode(IFNONNULL, OpcodeGroup.INSN_JUMP)); 320 } 321 322 330 public ASMContentHandler(OutputStream os, boolean computeMax) { 331 this.os = os; 332 this.computeMax = computeMax; 333 } 334 335 342 public byte[] toByteArray() { 343 return cw == null ? null : cw.toByteArray(); 344 } 345 346 359 public final void startElement( 360 String ns, 361 String localName, 362 String qName, 363 Attributes list) throws SAXException 364 { 365 String name = localName; 368 if (name == null || name.length() < 1) { 369 name = qName; 370 } 371 372 StringBuffer sb = new StringBuffer (match); 374 if (match.length() > 0) { 375 sb.append('/'); 376 } 377 sb.append(name); 378 match = sb.toString(); 379 380 Rule r = (Rule) RULES.match(match); 382 if (r != null) 383 r.begin(name, list); 384 } 385 386 398 public final void endElement(String ns, String localName, String qName) 399 throws SAXException 400 { 401 String name = localName; 404 if (name == null || name.length() < 1) { 405 name = qName; 406 } 407 408 Rule r = (Rule) RULES.match(match); 410 if (r != null) 411 r.end(name); 412 413 int slash = match.lastIndexOf('/'); 415 if (slash >= 0) { 416 match = match.substring(0, slash); 417 } else { 418 match = ""; 419 } 420 } 421 422 428 public final void endDocument() throws SAXException { 429 try { 430 os.write(cw.toByteArray()); 431 } catch (IOException ex) { 432 throw new SAXException (ex.toString(), ex); 433 } 434 } 435 436 442 final Object peek() { 443 return stack.size() == 0 ? null : stack.get(stack.size() - 1); 444 } 445 446 455 final Object peek(int n) { 456 return stack.size() < (n + 1) ? null : stack.get(n); 457 } 458 459 465 final Object pop() { 466 return stack.size() == 0 ? null : stack.remove(stack.size() - 1); 467 } 468 469 474 final void push(Object object) { 475 stack.add(object); 476 } 477 478 private static final class RuleSet { 479 private Map rules = new HashMap (); 480 481 private List lpatterns = new ArrayList (); 482 483 private List rpatterns = new ArrayList (); 484 485 public void add(String path, Object rule) { 486 String pattern = path; 487 if (path.startsWith("*/")) { 488 pattern = path.substring(1); 489 lpatterns.add(pattern); 490 } else if (path.endsWith("/*")) { 491 pattern = path.substring(0, path.length() - 1); 492 rpatterns.add(pattern); 493 } 494 rules.put(pattern, rule); 495 } 496 497 public Object match(String path) { 498 if (rules.containsKey(path)) { 499 return rules.get(path); 500 } 501 502 int n = path.lastIndexOf('/'); 503 for (Iterator it = lpatterns.iterator(); it.hasNext();) { 504 String pattern = (String ) it.next(); 505 if (path.substring(n).endsWith(pattern)) { 506 return rules.get(pattern); 507 } 508 } 509 510 for (Iterator it = rpatterns.iterator(); it.hasNext();) { 511 String pattern = (String ) it.next(); 512 if (path.startsWith(pattern)) { 513 return rules.get(pattern); 514 } 515 } 516 517 return null; 518 } 519 520 } 521 522 525 protected abstract class Rule { 526 527 public void begin(String name, Attributes attrs) { 528 } 529 530 public void end(String name) { 531 } 532 533 protected final Object getValue(String desc, String val) { 534 Object value = null; 535 if (val != null) { 536 if (desc.equals("Ljava/lang/String;")) { 537 value = decode(val); 538 } else if ("Ljava/lang/Integer;".equals(desc) 539 || "I".equals(desc) || "S".equals(desc) 540 || "B".equals(desc) || "C".equals(desc) 541 || desc.equals("Z")) 542 { 543 value = new Integer (val); 544 545 } else if ("Ljava/lang/Short;".equals(desc)) { 546 value = new Short (val); 547 548 } else if ("Ljava/lang/Byte;".equals(desc)) { 549 value = new Byte (val); 550 551 } else if ("Ljava/lang/Character;".equals(desc)) { 552 value = new Character (decode(val).charAt(0)); 553 554 } else if ("Ljava/lang/Boolean;".equals(desc)) { 555 value = Boolean.valueOf(val); 556 557 574 } else if ("Ljava/lang/Long;".equals(desc) || desc.equals("J")) 575 { 576 value = new Long (val); 577 } else if ("Ljava/lang/Float;".equals(desc) || desc.equals("F")) 578 { 579 value = new Float (val); 580 } else if ("Ljava/lang/Double;".equals(desc) 581 || desc.equals("D")) 582 { 583 value = new Double (val); 584 } else if (Type.getDescriptor(Type.class).equals(desc)) { 585 value = Type.getType(val); 586 587 604 } else { 605 throw new RuntimeException ("Invalid value:" + val 606 + " desc:" + desc + " ctx:" + this); 607 } 608 } 609 return value; 610 } 611 612 private final String decode(String val) { 613 StringBuffer sb = new StringBuffer (val.length()); 614 try { 615 int n = 0; 616 while (n < val.length()) { 617 char c = val.charAt(n); 618 if (c == '\\') { 619 n++; 620 c = val.charAt(n); 621 if (c == '\\') { 622 sb.append('\\'); 623 } else { 624 n++; sb.append((char) Integer.parseInt(val.substring(n, 626 n + 4), 16)); 627 n += 3; 628 } 629 } else { 630 sb.append(c); 631 } 632 n++; 633 } 634 635 } catch (RuntimeException ex) { 636 System.err.println(val + "\n" + ex.toString()); 637 ex.printStackTrace(); 638 throw ex; 639 } 640 return sb.toString(); 641 } 642 643 protected final Label getLabel(Object label) { 644 Label lbl = (Label) labels.get(label); 645 if (lbl == null) { 646 lbl = new Label(); 647 labels.put(label, lbl); 648 } 649 return lbl; 650 } 651 652 protected final MethodVisitor getCodeVisitor() { 654 return (MethodVisitor) peek(); 655 } 656 657 protected final int getAccess(String s) { 658 int access = 0; 659 if (s.indexOf("public") != -1) 660 access |= Opcodes.ACC_PUBLIC; 661 if (s.indexOf("private") != -1) 662 access |= Opcodes.ACC_PRIVATE; 663 if (s.indexOf("protected") != -1) 664 access |= Opcodes.ACC_PROTECTED; 665 if (s.indexOf("static") != -1) 666 access |= Opcodes.ACC_STATIC; 667 if (s.indexOf("final") != -1) 668 access |= Opcodes.ACC_FINAL; 669 if (s.indexOf("super") != -1) 670 access |= Opcodes.ACC_SUPER; 671 if (s.indexOf("synchronized") != -1) 672 access |= Opcodes.ACC_SYNCHRONIZED; 673 if (s.indexOf("volatile") != -1) 674 access |= Opcodes.ACC_VOLATILE; 675 if (s.indexOf("bridge") != -1) 676 access |= Opcodes.ACC_BRIDGE; 677 if (s.indexOf("varargs") != -1) 678 access |= Opcodes.ACC_VARARGS; 679 if (s.indexOf("transient") != -1) 680 access |= Opcodes.ACC_TRANSIENT; 681 if (s.indexOf("native") != -1) 682 access |= Opcodes.ACC_NATIVE; 683 if (s.indexOf("interface") != -1) 684 access |= Opcodes.ACC_INTERFACE; 685 if (s.indexOf("abstract") != -1) 686 access |= Opcodes.ACC_ABSTRACT; 687 if (s.indexOf("strict") != -1) 688 access |= Opcodes.ACC_STRICT; 689 if (s.indexOf("synthetic") != -1) 690 access |= Opcodes.ACC_SYNTHETIC; 691 if (s.indexOf("annotation") != -1) 692 access |= Opcodes.ACC_ANNOTATION; 693 if (s.indexOf("enum") != -1) 694 access |= Opcodes.ACC_ENUM; 695 if (s.indexOf("deprecated") != -1) 696 access |= Opcodes.ACC_DEPRECATED; 697 return access; 698 } 699 700 } 701 702 705 private final class ClassRule extends Rule { 706 707 public final void begin(String name, Attributes attrs) { 708 int major = Integer.parseInt(attrs.getValue("major")); 709 int minor = Integer.parseInt(attrs.getValue("minor")); 710 cw = new ClassWriter(computeMax); 711 Map vals = new HashMap (); 712 vals.put("version", new Integer (minor << 16 | major)); 713 vals.put("access", attrs.getValue("access")); 714 vals.put("name", attrs.getValue("name")); 715 vals.put("parent", attrs.getValue("parent")); 716 vals.put("source", attrs.getValue("source")); 717 vals.put("signature", attrs.getValue("signature")); 718 vals.put("interfaces", new ArrayList ()); 719 push(vals); 720 } 722 723 } 724 725 private final class SourceRule extends Rule { 726 727 public void begin(String name, Attributes attrs) { 728 String file = attrs.getValue("file"); 729 String debug = attrs.getValue("debug"); 730 cw.visitSource(file, debug); 731 } 732 733 } 734 735 738 private final class InterfaceRule extends Rule { 739 740 public final void begin(String name, Attributes attrs) { 741 ((List ) ((Map ) peek()).get("interfaces")).add(attrs.getValue("name")); 742 } 743 744 } 745 746 749 private final class InterfacesRule extends Rule { 750 751 public final void end(String element) { 752 Map vals = (Map ) pop(); 753 int version = ((Integer ) vals.get("version")).intValue(); 754 int access = getAccess((String ) vals.get("access")); 755 String name = (String ) vals.get("name"); 756 String signature = (String ) vals.get("signature"); 757 String parent = (String ) vals.get("parent"); 758 List infs = (List ) vals.get("interfaces"); 759 String [] interfaces = (String []) infs.toArray(new String [infs.size()]); 760 cw.visit(version, access, name, signature, parent, interfaces); 761 push(cw); 762 } 763 764 } 765 766 769 private final class OuterClassRule extends Rule { 770 771 public final void begin(String element, Attributes attrs) { 772 String owner = attrs.getValue("owner"); 773 String name = attrs.getValue("name"); 774 String desc = attrs.getValue("desc"); 775 cw.visitOuterClass(owner, name, desc); 776 } 777 778 } 779 780 783 private final class InnerClassRule extends Rule { 784 785 public final void begin(String element, Attributes attrs) { 786 int access = getAccess(attrs.getValue("access")); 787 String name = attrs.getValue("name"); 788 String outerName = attrs.getValue("outerName"); 789 String innerName = attrs.getValue("innerName"); 790 cw.visitInnerClass(name, outerName, innerName, access); 791 } 792 793 } 794 795 798 private final class FieldRule extends Rule { 799 800 public final void begin(String element, Attributes attrs) { 801 int access = getAccess(attrs.getValue("access")); 802 String name = attrs.getValue("name"); 803 String signature = attrs.getValue("signature"); 804 String desc = attrs.getValue("desc"); 805 Object value = getValue(desc, attrs.getValue("value")); 806 push(cw.visitField(access, name, desc, signature, value)); 807 } 808 809 public void end(String name) { 810 ((FieldVisitor) pop()).visitEnd(); 811 } 812 813 } 814 815 818 private final class MethodRule extends Rule { 819 820 public final void begin(String name, Attributes attrs) { 821 labels = new HashMap (); 822 Map vals = new HashMap (); 823 vals.put("access", attrs.getValue("access")); 824 vals.put("name", attrs.getValue("name")); 825 vals.put("desc", attrs.getValue("desc")); 826 vals.put("signature", attrs.getValue("signature")); 827 vals.put("exceptions", new ArrayList ()); 828 push(vals); 829 } 831 832 public final void end(String name) { 833 ((MethodVisitor) pop()).visitEnd(); 834 labels = null; 835 } 836 837 } 838 839 842 private final class ExceptionRule extends Rule { 843 844 public final void begin(String name, Attributes attrs) { 845 ((List ) ((Map ) peek()).get("exceptions")).add(attrs.getValue("name")); 846 } 847 848 } 849 850 853 private final class ExceptionsRule extends Rule { 854 855 public final void end(String element) { 856 Map vals = (Map ) pop(); 857 int access = getAccess((String ) vals.get("access")); 858 String name = (String ) vals.get("name"); 859 String desc = (String ) vals.get("desc"); 860 String signature = (String ) vals.get("signature"); 861 List excs = (List ) vals.get("exceptions"); 862 String [] exceptions = (String []) excs.toArray(new String [excs.size()]); 863 864 push(cw.visitMethod(access, name, desc, signature, exceptions)); 865 } 866 867 } 868 869 872 private class TableSwitchRule extends Rule { 873 874 public final void begin(String name, Attributes attrs) { 875 Map vals = new HashMap (); 876 vals.put("min", attrs.getValue("min")); 877 vals.put("max", attrs.getValue("max")); 878 vals.put("dflt", attrs.getValue("dflt")); 879 vals.put("labels", new ArrayList ()); 880 push(vals); 881 } 882 883 public final void end(String name) { 884 Map vals = (Map ) pop(); 885 int min = Integer.parseInt((String ) vals.get("min")); 886 int max = Integer.parseInt((String ) vals.get("max")); 887 Label dflt = getLabel(vals.get("dflt")); 888 List lbls = (List ) vals.get("labels"); 889 Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]); 890 getCodeVisitor().visitTableSwitchInsn(min, max, dflt, labels); 891 } 892 893 } 894 895 898 private final class TableSwitchLabelRule extends Rule { 899 900 public final void begin(String name, Attributes attrs) { 901 ((List ) ((Map ) peek()).get("labels")).add(getLabel(attrs.getValue("name"))); 902 } 903 904 } 905 906 909 private final class LookupSwitchRule extends Rule { 910 911 public final void begin(String name, Attributes attrs) { 912 Map vals = new HashMap (); 913 vals.put("dflt", attrs.getValue("dflt")); 914 vals.put("labels", new ArrayList ()); 915 vals.put("keys", new ArrayList ()); 916 push(vals); 917 } 918 919 public final void end(String name) { 920 Map vals = (Map ) pop(); 921 Label dflt = getLabel(vals.get("dflt")); 922 List keyList = (List ) vals.get("keys"); 923 List lbls = (List ) vals.get("labels"); 924 Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]); 925 int[] keys = new int[keyList.size()]; 926 for (int i = 0; i < keys.length; i++) { 927 keys[i] = Integer.parseInt((String ) keyList.get(i)); 928 } 929 getCodeVisitor().visitLookupSwitchInsn(dflt, keys, labels); 930 } 931 932 } 933 934 937 private final class LookupSwitchLabelRule extends Rule { 938 939 public final void begin(String name, Attributes attrs) { 940 Map vals = (Map ) peek(); 941 ((List ) vals.get("labels")).add(getLabel(attrs.getValue("name"))); 942 ((List ) vals.get("keys")).add(attrs.getValue("key")); 943 } 944 945 } 946 947 950 private final class LabelRule extends Rule { 951 952 public final void begin(String name, Attributes attrs) { 953 getCodeVisitor().visitLabel(getLabel(attrs.getValue("name"))); 954 } 955 956 } 957 958 961 private final class TryCatchRule extends Rule { 962 963 public final void begin(String name, Attributes attrs) { 964 Label start = getLabel(attrs.getValue("start")); 965 Label end = getLabel(attrs.getValue("end")); 966 Label handler = getLabel(attrs.getValue("handler")); 967 String type = attrs.getValue("type"); 968 getCodeVisitor().visitTryCatchBlock(start, end, handler, type); 969 } 970 971 } 972 973 976 private final class LineNumberRule extends Rule { 977 978 public final void begin(String name, Attributes attrs) { 979 int line = Integer.parseInt(attrs.getValue("line")); 980 Label start = getLabel(attrs.getValue("start")); 981 getCodeVisitor().visitLineNumber(line, start); 982 } 983 984 } 985 986 989 private final class LocalVarRule extends Rule { 990 991 public final void begin(String element, Attributes attrs) { 992 String name = attrs.getValue("name"); 993 String desc = attrs.getValue("desc"); 994 String signature = attrs.getValue("signature"); 995 Label start = getLabel(attrs.getValue("start")); 996 Label end = getLabel(attrs.getValue("end")); 997 int var = Integer.parseInt(attrs.getValue("var")); 998 getCodeVisitor().visitLocalVariable(name, 999 desc, 1000 signature, 1001 start, 1002 end, 1003 var); 1004 } 1005 1006 } 1007 1008 1011 private final class OpcodesRule extends Rule { 1012 1013 1017 public final void begin(String element, Attributes attrs) { 1018 Opcode o = ((Opcode) OPCODES.get(element)); 1019 if (o == null) 1020 return; 1021 1022 switch (o.type) { 1023 case OpcodeGroup.INSN: 1024 getCodeVisitor().visitInsn(o.opcode); 1025 break; 1026 1027 case OpcodeGroup.INSN_FIELD: 1028 getCodeVisitor().visitFieldInsn(o.opcode, 1029 attrs.getValue("owner"), 1030 attrs.getValue("name"), 1031 attrs.getValue("desc")); 1032 break; 1033 1034 case OpcodeGroup.INSN_INT: 1035 getCodeVisitor().visitIntInsn(o.opcode, 1036 Integer.parseInt(attrs.getValue("value"))); 1037 break; 1038 1039 case OpcodeGroup.INSN_JUMP: 1040 getCodeVisitor().visitJumpInsn(o.opcode, 1041 getLabel(attrs.getValue("label"))); 1042 break; 1043 1044 case OpcodeGroup.INSN_METHOD: 1045 getCodeVisitor().visitMethodInsn(o.opcode, 1046 attrs.getValue("owner"), 1047 attrs.getValue("name"), 1048 attrs.getValue("desc")); 1049 break; 1050 1051 case OpcodeGroup.INSN_TYPE: 1052 getCodeVisitor().visitTypeInsn(o.opcode, 1053 attrs.getValue("desc")); 1054 break; 1055 1056 case OpcodeGroup.INSN_VAR: 1057 getCodeVisitor().visitVarInsn(o.opcode, 1058 Integer.parseInt(attrs.getValue("var"))); 1059 break; 1060 1061 case OpcodeGroup.INSN_IINC: 1062 getCodeVisitor().visitIincInsn(Integer.parseInt(attrs.getValue("var")), 1063 Integer.parseInt(attrs.getValue("inc"))); 1064 break; 1065 1066 case OpcodeGroup.INSN_LDC: 1067 getCodeVisitor().visitLdcInsn(getValue(attrs.getValue("desc"), 1068 attrs.getValue("cst"))); 1069 break; 1070 1071 case OpcodeGroup.INSN_MULTIANEWARRAY: 1072 getCodeVisitor().visitMultiANewArrayInsn(attrs.getValue("desc"), 1073 Integer.parseInt(attrs.getValue("dims"))); 1074 break; 1075 1076 default: 1077 throw new RuntimeException ("Invalid element: " + element 1078 + " at " + match); 1079 1080 } 1081 } 1082 } 1083 1084 1087 private final class MaxRule extends Rule { 1088 1089 public final void begin(String element, Attributes attrs) { 1090 int maxStack = Integer.parseInt(attrs.getValue("maxStack")); 1091 int maxLocals = Integer.parseInt(attrs.getValue("maxLocals")); 1092 getCodeVisitor().visitMaxs(maxStack, maxLocals); 1093 } 1094 1095 } 1096 1097 private final class AnnotationRule extends Rule { 1098 1099 public void begin(String name, Attributes attrs) { 1100 String desc = attrs.getValue("desc"); 1101 boolean visible = Boolean.valueOf(attrs.getValue("visible")) 1102 .booleanValue(); 1103 1104 Object v = peek(); 1105 if (v instanceof ClassVisitor) { 1106 push(((ClassVisitor) v).visitAnnotation(desc, visible)); 1107 } else if (v instanceof FieldVisitor) { 1108 push(((FieldVisitor) v).visitAnnotation(desc, visible)); 1109 } else if (v instanceof MethodVisitor) { 1110 push(((MethodVisitor) v).visitAnnotation(desc, visible)); 1111 } 1112 } 1113 1114 public void end(String name) { 1115 ((AnnotationVisitor) pop()).visitEnd(); 1116 } 1117 1118 } 1119 1120 private final class AnnotationParameterRule extends Rule { 1121 1122 public void begin(String name, Attributes attrs) { 1123 int parameter = Integer.parseInt(attrs.getValue("parameter")); 1124 String desc = attrs.getValue("desc"); 1125 boolean visible = Boolean.valueOf(attrs.getValue("visible")) 1126 .booleanValue(); 1127 1128 push(((MethodVisitor) peek()).visitParameterAnnotation(parameter, 1129 desc, 1130 visible)); 1131 } 1132 1133 public void end(String name) { 1134 ((AnnotationVisitor) pop()).visitEnd(); 1135 } 1136 1137 } 1138 1139 private final class AnnotationValueRule extends Rule { 1140 1141 public void begin(String nm, Attributes attrs) { 1142 String name = attrs.getValue("name"); 1143 String desc = attrs.getValue("desc"); 1144 String value = attrs.getValue("value"); 1145 ((AnnotationVisitor) peek()).visit(name, getValue(desc, value)); 1146 } 1147 1148 } 1149 1150 private final class AnnotationValueEnumRule extends Rule { 1151 1152 public void begin(String nm, Attributes attrs) { 1153 String name = attrs.getValue("name"); 1154 String desc = attrs.getValue("desc"); 1155 String value = attrs.getValue("value"); 1156 ((AnnotationVisitor) peek()).visitEnum(name, desc, value); 1157 } 1158 1159 } 1160 1161 private final class AnnotationValueAnnotationRule extends Rule { 1162 1163 public void begin(String nm, Attributes attrs) { 1164 String name = attrs.getValue("name"); 1165 String desc = attrs.getValue("desc"); 1166 push(((AnnotationVisitor) peek()).visitAnnotation(name, desc)); 1167 } 1168 1169 public void end(String name) { 1170 ((AnnotationVisitor) pop()).visitEnd(); 1171 } 1172 1173 } 1174 1175 private final class AnnotationValueArrayRule extends Rule { 1176 1177 public void begin(String nm, Attributes attrs) { 1178 String name = attrs.getValue("name"); 1179 push(((AnnotationVisitor) peek()).visitArray(name)); 1180 } 1181 1182 public void end(String name) { 1183 ((AnnotationVisitor) pop()).visitEnd(); 1184 } 1185 1186 } 1187 1188 private final class AnnotationDefaultRule extends Rule { 1189 1190 public void begin(String nm, Attributes attrs) { 1191 push(((MethodVisitor) peek()).visitAnnotationDefault()); 1192 } 1193 1194 public void end(String name) { 1195 ((AnnotationVisitor) pop()).visitEnd(); 1196 } 1197 1198 } 1199 1200 1203 private final static class Opcode { 1204 public int opcode; 1205 1206 public int type; 1207 1208 public Opcode(int opcode, int type) { 1209 this.opcode = opcode; 1210 this.type = type; 1211 } 1212 1213 } 1214 1215} 1216 | Popular Tags |