1 30 31 package oracle.toplink.libraries.asm.xml; 32 33 import java.io.IOException ; 34 import java.io.OutputStream ; 35 import java.util.ArrayList ; 36 import java.util.HashMap ; 37 import java.util.List ; 38 import java.util.Map ; 39 40 import oracle.toplink.libraries.asm.ClassWriter; 41 import oracle.toplink.libraries.asm.CodeVisitor; 42 import oracle.toplink.libraries.asm.Constants; 43 import oracle.toplink.libraries.asm.Label; 44 45 import org.xml.sax.Attributes ; 46 import org.xml.sax.SAXException ; 47 import org.xml.sax.helpers.DefaultHandler ; 48 49 50 60 public class ASMContentHandler extends DefaultHandler implements Constants { 61 64 private List stack = new ArrayList (); 65 68 private String match = ""; 69 70 74 protected boolean computeMax; 75 78 protected OutputStream os; 79 80 83 protected ClassWriter cw; 84 87 protected CodeVisitor mw; 88 91 protected Map labels; 92 93 private static final String BASE = "class"; 94 private final Rule[] RULES = { 95 new ClassRule( BASE), 96 new InterfaceRule( BASE+"/interfaces/interface"), 97 new InterfacesRule( BASE+"/interfaces"), 98 new FieldRule( BASE+"/field"), 99 new MethodRule( BASE+"/method"), 100 new ExceptionRule( BASE+"/method/exceptions/exception"), 101 new ExceptionsRule( BASE+"/method/exceptions"), 102 new InnerClassRule( BASE+"/innerclass"), 103 104 new OpcodesRule( BASE+"/method/code/"), 106 new TableSwitchRule( BASE+"/method/code/TABLESWITCH"), 107 new TableSwitchLabelRule( BASE+"/method/code/TABLESWITCH/label"), 108 new LookupSwitchRule( BASE+"/method/code/LOOKUPSWITCH"), 109 new LookupSwitchLabelRule( BASE+"/method/code/LOOKUPSWITCH/label"), 110 111 new LabelRule( BASE+"/method/code/Label"), 112 new TryCatchRule( BASE+"/method/code/TryCatch"), 113 new LineNumberRule( BASE+"/method/code/LineNumber"), 114 new LocalVarRule( BASE+"/method/code/LocalVar"), 115 new MaxRule( BASE+"/method/code/Max") 116 }; 117 118 private static interface OpcodeGroup { 119 public static final int INSN = 0; 120 public static final int INSN_INT = 1; 121 public static final int INSN_VAR = 2; 122 public static final int INSN_TYPE = 3; 123 public static final int INSN_FIELD = 4; 124 public static final int INSN_METHOD = 5; 125 public static final int INSN_JUMP = 6; 126 public static final int INSN_LDC = 7; 127 public static final int INSN_IINC = 8; 128 public static final int INSN_MULTIANEWARRAY = 9; 129 } 130 131 134 static final Map OPCODES = new HashMap (); 135 static { 136 OPCODES.put( "NOP", new Opcode( NOP, OpcodeGroup.INSN)); 137 OPCODES.put( "ACONST_NULL", new Opcode( ACONST_NULL, OpcodeGroup.INSN)); 138 OPCODES.put( "ICONST_M1", new Opcode( ICONST_M1, OpcodeGroup.INSN)); 139 OPCODES.put( "ICONST_0", new Opcode( ICONST_0, OpcodeGroup.INSN)); 140 OPCODES.put( "ICONST_1", new Opcode( ICONST_1, OpcodeGroup.INSN)); 141 OPCODES.put( "ICONST_2", new Opcode( ICONST_2, OpcodeGroup.INSN)); 142 OPCODES.put( "ICONST_3", new Opcode( ICONST_3, OpcodeGroup.INSN)); 143 OPCODES.put( "ICONST_4", new Opcode( ICONST_4, OpcodeGroup.INSN)); 144 OPCODES.put( "ICONST_5", new Opcode( ICONST_5, OpcodeGroup.INSN)); 145 OPCODES.put( "LCONST_0", new Opcode( LCONST_0, OpcodeGroup.INSN)); 146 OPCODES.put( "LCONST_1", new Opcode( LCONST_1, OpcodeGroup.INSN)); 147 OPCODES.put( "FCONST_0", new Opcode( FCONST_0, OpcodeGroup.INSN)); 148 OPCODES.put( "FCONST_1", new Opcode( FCONST_1, OpcodeGroup.INSN)); 149 OPCODES.put( "FCONST_2", new Opcode( FCONST_2, OpcodeGroup.INSN)); 150 OPCODES.put( "DCONST_0", new Opcode( DCONST_0, OpcodeGroup.INSN)); 151 OPCODES.put( "DCONST_1", new Opcode( DCONST_1, OpcodeGroup.INSN)); 152 OPCODES.put( "BIPUSH", new Opcode( BIPUSH, OpcodeGroup.INSN_INT)); 153 OPCODES.put( "SIPUSH", new Opcode( SIPUSH, OpcodeGroup.INSN_INT)); 154 OPCODES.put( "LDC", new Opcode( LDC, OpcodeGroup.INSN_LDC)); 155 OPCODES.put( "ILOAD", new Opcode( ILOAD, OpcodeGroup.INSN_VAR)); 156 OPCODES.put( "LLOAD", new Opcode( LLOAD, OpcodeGroup.INSN_VAR)); 157 OPCODES.put( "FLOAD", new Opcode( FLOAD, OpcodeGroup.INSN_VAR)); 158 OPCODES.put( "DLOAD", new Opcode( DLOAD, OpcodeGroup.INSN_VAR)); 159 OPCODES.put( "ALOAD", new Opcode( ALOAD, OpcodeGroup.INSN_VAR)); 160 OPCODES.put( "IALOAD", new Opcode( IALOAD, OpcodeGroup.INSN)); 161 OPCODES.put( "LALOAD", new Opcode( LALOAD, OpcodeGroup.INSN)); 162 OPCODES.put( "FALOAD", new Opcode( FALOAD, OpcodeGroup.INSN)); 163 OPCODES.put( "DALOAD", new Opcode( DALOAD, OpcodeGroup.INSN)); 164 OPCODES.put( "AALOAD", new Opcode( AALOAD, OpcodeGroup.INSN)); 165 OPCODES.put( "BALOAD", new Opcode( BALOAD, OpcodeGroup.INSN)); 166 OPCODES.put( "CALOAD", new Opcode( CALOAD, OpcodeGroup.INSN)); 167 OPCODES.put( "SALOAD", new Opcode( SALOAD, OpcodeGroup.INSN)); 168 OPCODES.put( "ISTORE", new Opcode( ISTORE, OpcodeGroup.INSN_VAR)); 169 OPCODES.put( "LSTORE", new Opcode( LSTORE, OpcodeGroup.INSN_VAR)); 170 OPCODES.put( "FSTORE", new Opcode( FSTORE, OpcodeGroup.INSN_VAR)); 171 OPCODES.put( "DSTORE", new Opcode( DSTORE, OpcodeGroup.INSN_VAR)); 172 OPCODES.put( "ASTORE", new Opcode( ASTORE, OpcodeGroup.INSN_VAR)); 173 OPCODES.put( "IASTORE", new Opcode( IASTORE, OpcodeGroup.INSN)); 174 OPCODES.put( "LASTORE", new Opcode( LASTORE, OpcodeGroup.INSN)); 175 OPCODES.put( "FASTORE", new Opcode( FASTORE, OpcodeGroup.INSN)); 176 OPCODES.put( "DASTORE", new Opcode( DASTORE, OpcodeGroup.INSN)); 177 OPCODES.put( "AASTORE", new Opcode( AASTORE, OpcodeGroup.INSN)); 178 OPCODES.put( "BASTORE", new Opcode( BASTORE, OpcodeGroup.INSN)); 179 OPCODES.put( "CASTORE", new Opcode( CASTORE, OpcodeGroup.INSN)); 180 OPCODES.put( "SASTORE", new Opcode( SASTORE, OpcodeGroup.INSN)); 181 OPCODES.put( "POP", new Opcode( POP, OpcodeGroup.INSN)); 182 OPCODES.put( "POP2", new Opcode( POP2, OpcodeGroup.INSN)); 183 OPCODES.put( "DUP", new Opcode( DUP, OpcodeGroup.INSN)); 184 OPCODES.put( "DUP_X1", new Opcode( DUP_X1, OpcodeGroup.INSN)); 185 OPCODES.put( "DUP_X2", new Opcode( DUP_X2, OpcodeGroup.INSN)); 186 OPCODES.put( "DUP2", new Opcode( DUP2, OpcodeGroup.INSN)); 187 OPCODES.put( "DUP2_X1", new Opcode( DUP2_X1, OpcodeGroup.INSN)); 188 OPCODES.put( "DUP2_X2", new Opcode( DUP2_X2, OpcodeGroup.INSN)); 189 OPCODES.put( "SWAP", new Opcode( SWAP, OpcodeGroup.INSN)); 190 OPCODES.put( "IADD", new Opcode( IADD, OpcodeGroup.INSN)); 191 OPCODES.put( "LADD", new Opcode( LADD, OpcodeGroup.INSN)); 192 OPCODES.put( "FADD", new Opcode( FADD, OpcodeGroup.INSN)); 193 OPCODES.put( "DADD", new Opcode( DADD, OpcodeGroup.INSN)); 194 OPCODES.put( "ISUB", new Opcode( ISUB, OpcodeGroup.INSN)); 195 OPCODES.put( "LSUB", new Opcode( LSUB, OpcodeGroup.INSN)); 196 OPCODES.put( "FSUB", new Opcode( FSUB, OpcodeGroup.INSN)); 197 OPCODES.put( "DSUB", new Opcode( DSUB, OpcodeGroup.INSN)); 198 OPCODES.put( "IMUL", new Opcode( IMUL, OpcodeGroup.INSN)); 199 OPCODES.put( "LMUL", new Opcode( LMUL, OpcodeGroup.INSN)); 200 OPCODES.put( "FMUL", new Opcode( FMUL, OpcodeGroup.INSN)); 201 OPCODES.put( "DMUL", new Opcode( DMUL, OpcodeGroup.INSN)); 202 OPCODES.put( "IDIV", new Opcode( IDIV, OpcodeGroup.INSN)); 203 OPCODES.put( "LDIV", new Opcode( LDIV, OpcodeGroup.INSN)); 204 OPCODES.put( "FDIV", new Opcode( FDIV, OpcodeGroup.INSN)); 205 OPCODES.put( "DDIV", new Opcode( DDIV, OpcodeGroup.INSN)); 206 OPCODES.put( "IREM", new Opcode( IREM, OpcodeGroup.INSN)); 207 OPCODES.put( "LREM", new Opcode( LREM, OpcodeGroup.INSN)); 208 OPCODES.put( "FREM", new Opcode( FREM, OpcodeGroup.INSN)); 209 OPCODES.put( "DREM", new Opcode( DREM, OpcodeGroup.INSN)); 210 OPCODES.put( "INEG", new Opcode( INEG, OpcodeGroup.INSN)); 211 OPCODES.put( "LNEG", new Opcode( LNEG, OpcodeGroup.INSN)); 212 OPCODES.put( "FNEG", new Opcode( FNEG, OpcodeGroup.INSN)); 213 OPCODES.put( "DNEG", new Opcode( DNEG, OpcodeGroup.INSN)); 214 OPCODES.put( "ISHL", new Opcode( ISHL, OpcodeGroup.INSN)); 215 OPCODES.put( "LSHL", new Opcode( LSHL, OpcodeGroup.INSN)); 216 OPCODES.put( "ISHR", new Opcode( ISHR, OpcodeGroup.INSN)); 217 OPCODES.put( "LSHR", new Opcode( LSHR, OpcodeGroup.INSN)); 218 OPCODES.put( "IUSHR", new Opcode( IUSHR, OpcodeGroup.INSN)); 219 OPCODES.put( "LUSHR", new Opcode( LUSHR, OpcodeGroup.INSN)); 220 OPCODES.put( "IAND", new Opcode( IAND, OpcodeGroup.INSN)); 221 OPCODES.put( "LAND", new Opcode( LAND, OpcodeGroup.INSN)); 222 OPCODES.put( "IOR", new Opcode( IOR, OpcodeGroup.INSN)); 223 OPCODES.put( "LOR", new Opcode( LOR, OpcodeGroup.INSN)); 224 OPCODES.put( "IXOR", new Opcode( IXOR, OpcodeGroup.INSN)); 225 OPCODES.put( "LXOR", new Opcode( LXOR, OpcodeGroup.INSN)); 226 OPCODES.put( "IINC", new Opcode( IINC, OpcodeGroup.INSN_IINC)); 227 OPCODES.put( "I2L", new Opcode( I2L, OpcodeGroup.INSN)); 228 OPCODES.put( "I2F", new Opcode( I2F, OpcodeGroup.INSN)); 229 OPCODES.put( "I2D", new Opcode( I2D, OpcodeGroup.INSN)); 230 OPCODES.put( "L2I", new Opcode( L2I, OpcodeGroup.INSN)); 231 OPCODES.put( "L2F", new Opcode( L2F, OpcodeGroup.INSN)); 232 OPCODES.put( "L2D", new Opcode( L2D, OpcodeGroup.INSN)); 233 OPCODES.put( "F2I", new Opcode( F2I, OpcodeGroup.INSN)); 234 OPCODES.put( "F2L", new Opcode( F2L, OpcodeGroup.INSN)); 235 OPCODES.put( "F2D", new Opcode( F2D, OpcodeGroup.INSN)); 236 OPCODES.put( "D2I", new Opcode( D2I, OpcodeGroup.INSN)); 237 OPCODES.put( "D2L", new Opcode( D2L, OpcodeGroup.INSN)); 238 OPCODES.put( "D2F", new Opcode( D2F, OpcodeGroup.INSN)); 239 OPCODES.put( "I2B", new Opcode( I2B, OpcodeGroup.INSN)); 240 OPCODES.put( "I2C", new Opcode( I2C, OpcodeGroup.INSN)); 241 OPCODES.put( "I2S", new Opcode( I2S, OpcodeGroup.INSN)); 242 OPCODES.put( "LCMP", new Opcode( LCMP, OpcodeGroup.INSN)); 243 OPCODES.put( "FCMPL", new Opcode( FCMPL, OpcodeGroup.INSN)); 244 OPCODES.put( "FCMPG", new Opcode( FCMPG, OpcodeGroup.INSN)); 245 OPCODES.put( "DCMPL", new Opcode( DCMPL, OpcodeGroup.INSN)); 246 OPCODES.put( "DCMPG", new Opcode( DCMPG, OpcodeGroup.INSN)); 247 OPCODES.put( "IFEQ", new Opcode( IFEQ, OpcodeGroup.INSN_JUMP)); 248 OPCODES.put( "IFNE", new Opcode( IFNE, OpcodeGroup.INSN_JUMP)); 249 OPCODES.put( "IFLT", new Opcode( IFLT, OpcodeGroup.INSN_JUMP)); 250 OPCODES.put( "IFGE", new Opcode( IFGE, OpcodeGroup.INSN_JUMP)); 251 OPCODES.put( "IFGT", new Opcode( IFGT, OpcodeGroup.INSN_JUMP)); 252 OPCODES.put( "IFLE", new Opcode( IFLE, OpcodeGroup.INSN_JUMP)); 253 OPCODES.put( "IF_ICMPEQ", new Opcode( IF_ICMPEQ, OpcodeGroup.INSN_JUMP)); 254 OPCODES.put( "IF_ICMPNE", new Opcode( IF_ICMPNE, OpcodeGroup.INSN_JUMP)); 255 OPCODES.put( "IF_ICMPLT", new Opcode( IF_ICMPLT, OpcodeGroup.INSN_JUMP)); 256 OPCODES.put( "IF_ICMPGE", new Opcode( IF_ICMPGE, OpcodeGroup.INSN_JUMP)); 257 OPCODES.put( "IF_ICMPGT", new Opcode( IF_ICMPGT, OpcodeGroup.INSN_JUMP)); 258 OPCODES.put( "IF_ICMPLE", new Opcode( IF_ICMPLE, OpcodeGroup.INSN_JUMP)); 259 OPCODES.put( "IF_ACMPEQ", new Opcode( IF_ACMPEQ, OpcodeGroup.INSN_JUMP)); 260 OPCODES.put( "IF_ACMPNE", new Opcode( IF_ACMPNE, OpcodeGroup.INSN_JUMP)); 261 OPCODES.put( "GOTO", new Opcode( GOTO, OpcodeGroup.INSN_JUMP)); 262 OPCODES.put( "JSR", new Opcode( JSR, OpcodeGroup.INSN_JUMP)); 263 OPCODES.put( "RET", new Opcode( RET, OpcodeGroup.INSN_VAR)); 264 OPCODES.put( "IRETURN", new Opcode( IRETURN, OpcodeGroup.INSN)); 267 OPCODES.put( "LRETURN", new Opcode( LRETURN, OpcodeGroup.INSN)); 268 OPCODES.put( "FRETURN", new Opcode( FRETURN, OpcodeGroup.INSN)); 269 OPCODES.put( "DRETURN", new Opcode( DRETURN, OpcodeGroup.INSN)); 270 OPCODES.put( "ARETURN", new Opcode( ARETURN, OpcodeGroup.INSN)); 271 OPCODES.put( "RETURN", new Opcode( RETURN, OpcodeGroup.INSN)); 272 OPCODES.put( "GETSTATIC", new Opcode( GETSTATIC, OpcodeGroup.INSN_FIELD)); 273 OPCODES.put( "PUTSTATIC", new Opcode( PUTSTATIC, OpcodeGroup.INSN_FIELD)); 274 OPCODES.put( "GETFIELD", new Opcode( GETFIELD, OpcodeGroup.INSN_FIELD)); 275 OPCODES.put( "PUTFIELD", new Opcode( PUTFIELD, OpcodeGroup.INSN_FIELD)); 276 OPCODES.put( "INVOKEVIRTUAL", new Opcode( INVOKEVIRTUAL, OpcodeGroup.INSN_METHOD)); 277 OPCODES.put( "INVOKESPECIAL", new Opcode( INVOKESPECIAL, OpcodeGroup.INSN_METHOD)); 278 OPCODES.put( "INVOKESTATIC", new Opcode( INVOKESTATIC, OpcodeGroup.INSN_METHOD)); 279 OPCODES.put( "INVOKEINTERFACE", new Opcode( INVOKEINTERFACE, OpcodeGroup.INSN_METHOD)); 280 OPCODES.put( "NEW", new Opcode( NEW, OpcodeGroup.INSN_TYPE)); 281 OPCODES.put( "NEWARRAY", new Opcode( NEWARRAY, OpcodeGroup.INSN_INT)); 282 OPCODES.put( "ANEWARRAY", new Opcode( ANEWARRAY, OpcodeGroup.INSN_TYPE)); 283 OPCODES.put( "ARRAYLENGTH", new Opcode( ARRAYLENGTH, OpcodeGroup.INSN)); 284 OPCODES.put( "ATHROW", new Opcode( ATHROW, OpcodeGroup.INSN)); 285 OPCODES.put( "CHECKCAST", new Opcode( CHECKCAST, OpcodeGroup.INSN_TYPE)); 286 OPCODES.put( "INSTANCEOF", new Opcode( INSTANCEOF, OpcodeGroup.INSN_TYPE)); 287 OPCODES.put( "MONITORENTER", new Opcode( MONITORENTER, OpcodeGroup.INSN)); 288 OPCODES.put( "MONITOREXIT", new Opcode( MONITOREXIT, OpcodeGroup.INSN)); 289 OPCODES.put( "MULTIANEWARRAY", new Opcode( MULTIANEWARRAY, OpcodeGroup.INSN_MULTIANEWARRAY)); 290 OPCODES.put( "IFNULL", new Opcode( IFNULL, OpcodeGroup.INSN_JUMP)); 291 OPCODES.put( "IFNONNULL", new Opcode( IFNONNULL, OpcodeGroup.INSN_JUMP)); 292 } 293 294 303 public ASMContentHandler( OutputStream os, boolean computeMax) { 304 this.os = os; 305 this.computeMax = computeMax; 306 } 307 308 314 public byte[] toByteArray() { 315 return cw==null ? null : cw.toByteArray(); 316 } 317 318 331 public final void startElement( String ns, String localName, String qName, Attributes list) throws SAXException { 332 String name = localName; 335 if( name==null || name.length()<1) { 336 name = qName; 337 } 338 339 StringBuffer sb = new StringBuffer ( match); 341 if( match.length() > 0) { 342 sb.append( '/'); 343 } 344 sb.append( name); 345 match = sb.toString(); 346 347 for( int i = 0; i < RULES.length; i++) { 349 if( RULES[ i].match( match, name)) { 350 RULES[ i].begin( name, list); 351 } 352 } 353 } 354 355 368 public final void endElement( String ns, String localName, String qName) throws SAXException { 369 String name = localName; 372 if( name == null || name.length() < 1) { 373 name = qName; 374 } 375 376 for( int i = 0; i < RULES.length; i++) { 378 if( RULES[ i].match( match, name)) { 379 RULES[ i].end( name); 380 } 381 } 382 383 int slash = match.lastIndexOf( '/'); 385 if( slash >= 0) { 386 match = match.substring( 0, slash); 387 } else { 388 match = ""; 389 } 390 } 391 392 398 public final void endDocument() throws SAXException { 399 try { 400 os.write( cw.toByteArray()); 401 } catch( IOException ex) { 402 throw new SAXException ( ex.toString(), ex); 403 } 404 } 405 406 407 411 final Object peek() { 412 return stack.size()==0 ? null : stack.get( stack.size()-1); 413 } 414 415 416 424 final Object peek(int n) { 425 return stack.size()<( n+1) ? null : stack.get( n); 426 } 427 428 429 433 final Object pop() { 434 return stack.size()==0 ? null : stack.remove( stack.size()-1); 435 } 436 437 442 final void push(Object object) { 443 stack.add( object); 444 } 445 446 447 450 private abstract class Rule { 451 protected String path; 452 453 public Rule( String path) { 454 this.path = path; 455 } 456 457 public final String getPath() { 458 return path; 459 } 460 461 public void begin( String name, Attributes attrs) { 462 } 463 464 public void end( String name) { 465 } 466 467 public boolean match( String match, String element) { 468 return path.equals( match); 469 } 470 471 protected final Object getValue( String desc, String val) { 472 Object value = null; 473 if( val!=null) { 474 if( desc.equals( "Ljava/lang/String;")) { 475 value = decode( val); 476 } else if( desc.equals( "Ljava/lang/Integer;") || 477 desc.equals( "Z") || desc.equals( "B") || desc.equals( "C") || desc.equals( "I") || desc.equals( "S")) { 478 value = new Integer ( val); 479 } else if( desc.equals( "Ljava/lang/Long;") || desc.equals( "J")) { 480 value = new Long ( val); 481 } else if( desc.equals( "Ljava/lang/Float;") || desc.equals( "F")) { 482 value = new Float ( val); 483 } else if( desc.equals( "Ljava/lang/Double;") || desc.equals( "D")) { 484 value = new Double ( val); 485 } else { 486 throw new RuntimeException ( "Invalid value:"+val+" desc:"+desc+" ctx:"+this); 487 } 488 } 489 return value; 490 } 491 492 private final String decode( String val) { 493 StringBuffer sb = new StringBuffer ( val.length()); 494 try { 495 int n = 0; 496 while( n < val.length()) { 497 char c = val.charAt( n); 498 if( c == '\\') { 499 n++; 500 c = val.charAt( n); 501 if( c == '\\') { 502 sb.append( '\\'); 503 } else { 504 n++; sb.append( ( char) Integer.parseInt( val.substring( n, n + 4), 16)); 506 n += 3; 507 } 508 } else { 509 sb.append( c); 510 } 511 n++; 512 } 513 514 } catch( RuntimeException ex) { 515 System.err.println( val+"\n"+ex.toString()); 516 ex.printStackTrace(); 517 throw ex; 518 } 519 return sb.toString(); 520 } 521 522 protected final Label getLabel( Object label) { 523 Label lbl = ( Label) labels.get( label); 524 if( lbl==null) { 525 lbl = new Label(); 526 labels.put( label, lbl); 527 } 528 return lbl; 529 } 530 531 public String toString() { 532 return path; 533 } 534 535 protected final CodeVisitor getCodeVisitor() { 536 if( mw==null) { 537 Map vals = ( Map ) pop(); 538 int access = Integer.parseInt(( String ) vals.get( "access"), 16); 539 String name = ( String ) vals.get( "name"); 540 String desc = ( String ) vals.get( "desc"); 541 mw = cw.visitMethod( access, name, desc, null, null); 542 } 543 return mw; 544 } 545 546 protected final int getAccess( String s) { 547 int access = 0; 548 if( s.indexOf( "public")!=-1) access |= Constants.ACC_PUBLIC; 549 if( s.indexOf( "private")!=-1) access |= Constants.ACC_PRIVATE; 550 if( s.indexOf( "protected")!=-1) access |= Constants.ACC_PROTECTED; 551 if( s.indexOf( "static")!=-1) access |= Constants.ACC_STATIC; 552 if( s.indexOf( "final")!=-1) access |= Constants.ACC_FINAL; 553 if( s.indexOf( "super")!=-1) access |= Constants.ACC_SUPER; 554 if( s.indexOf( "synchronized")!=-1) access |= Constants.ACC_SYNCHRONIZED; 555 if( s.indexOf( "volatile")!=-1) access |= Constants.ACC_VOLATILE; 556 if( s.indexOf( "bridge")!=-1) access |= Constants.ACC_BRIDGE; 557 if( s.indexOf( "varargs")!=-1) access |= Constants.ACC_VARARGS; 558 if( s.indexOf( "transient")!=-1) access |= Constants.ACC_TRANSIENT; 559 if( s.indexOf( "native")!=-1) access |= Constants.ACC_NATIVE; 560 if( s.indexOf( "interface")!=-1) access |= Constants.ACC_INTERFACE; 561 if( s.indexOf( "abstract")!=-1) access |= Constants.ACC_ABSTRACT; 562 if( s.indexOf( "strict")!=-1) access |= Constants.ACC_STRICT; 563 if( s.indexOf( "synthetic")!=-1) access |= Constants.ACC_SYNTHETIC; 564 if( s.indexOf( "annotation")!=-1) access |= Constants.ACC_ANNOTATION; 565 if( s.indexOf( "enum")!=-1) access |= Constants.ACC_ENUM; 566 if( s.indexOf( "deprecated")!=-1) access |= Constants.ACC_DEPRECATED; 567 return access; 568 } 569 570 } 571 572 575 private final class ClassRule extends Rule { 576 577 public ClassRule( String path) { 578 super( path); 579 } 580 581 public final void begin( String name, Attributes attrs) { 582 int major = Integer.parseInt( attrs.getValue( "major")); 583 int minor = Integer.parseInt( attrs.getValue( "minor")); 584 cw = new ClassWriter( computeMax); 585 Map vals = new HashMap (); 586 vals.put( "version", new Integer (minor << 16 | major)); 587 vals.put( "access", attrs.getValue( "access")); 588 vals.put( "name", attrs.getValue( "name")); 589 vals.put( "parent", attrs.getValue( "parent")); 590 vals.put( "source", attrs.getValue( "source")); 591 vals.put( "interfaces", new ArrayList ()); 592 push( vals); 593 } 595 596 } 597 598 599 602 private final class InterfaceRule extends Rule { 603 604 public InterfaceRule( String path) { 605 super( path); 606 } 607 608 public final void begin( String name, Attributes attrs) { 609 (( List ) (( Map ) peek()).get( "interfaces")).add( attrs.getValue( "name")); 610 } 611 612 } 613 614 615 618 private final class InterfacesRule extends Rule { 619 620 public InterfacesRule( String path) { 621 super( path); 622 } 623 624 public final void end( String element) { 625 Map vals = ( Map ) pop(); 626 int version = (( Integer )vals.get( "version")).intValue(); 627 int access = getAccess(( String ) vals.get( "access")); 628 String name = ( String ) vals.get( "name"); 629 String parent = ( String ) vals.get( "parent"); 630 String source = ( String ) vals.get( "source"); 631 String [] interfaces = ( String [])(( List ) vals.get( "interfaces")).toArray( new String [ 0]); 632 cw.visit( version, access, name, parent, interfaces, source); 633 } 634 635 } 636 637 638 641 private final class FieldRule extends Rule { 642 643 public FieldRule( String path) { 644 super( path); 645 } 646 647 public final void begin( String element, Attributes attrs) { 648 int access = getAccess( attrs.getValue( "access")); 649 String name = attrs.getValue( "name"); 650 String desc = attrs.getValue( "desc"); 651 Object value = getValue( desc, attrs.getValue( "value")); 652 cw.visitField( access, name, desc, value, null); 653 } 654 655 } 656 657 658 661 private final class MethodRule extends Rule { 662 663 public MethodRule( String path) { 664 super( path); 665 } 666 667 public final void begin( String name, Attributes attrs) { 668 labels = new HashMap (); 669 Map vals = new HashMap (); 670 vals.put( "access", attrs.getValue( "access")); 671 vals.put( "name", attrs.getValue( "name")); 672 vals.put( "desc", attrs.getValue( "desc")); 673 vals.put( "exceptions", new ArrayList ()); 674 push( vals); 675 } 677 678 public final void end( String name) { 679 mw = null; 680 labels = null; 681 } 682 683 } 684 685 686 689 private final class InnerClassRule extends Rule { 690 691 public InnerClassRule( String path) { 692 super( path); 693 } 694 695 public final void begin( String element, Attributes attrs) { 696 int access = getAccess( attrs.getValue( "access")); 697 String name = attrs.getValue( "name"); 698 String outerName = attrs.getValue( "outerName"); 699 String innerName = attrs.getValue( "innerName"); 700 cw.visitInnerClass( name, outerName, innerName, access); 701 } 702 703 public final void end( String name) { 704 mw = null; 705 labels = null; 706 } 707 708 } 709 710 711 714 private final class ExceptionRule extends Rule { 715 716 public ExceptionRule( String path) { 717 super( path); 718 } 719 720 public final void begin( String name, Attributes attrs) { 721 (( List ) (( Map ) peek()).get( "exceptions")).add( attrs.getValue( "name")); 722 } 723 724 } 725 726 727 730 private final class ExceptionsRule extends Rule { 731 732 public ExceptionsRule( String path) { 733 super( path); 734 } 735 736 public final void end( String element) { 737 Map vals = ( Map ) pop(); 738 int access = getAccess(( String ) vals.get( "access")); 739 String name = ( String ) vals.get( "name"); 740 String desc = ( String ) vals.get( "desc"); 741 String [] exceptions = ( String [])(( List ) vals.get( "exceptions")).toArray( new String [ 0]); 742 743 mw = cw.visitMethod( access, name, desc, exceptions, null); 744 } 745 746 } 747 748 749 752 private class TableSwitchRule extends Rule { 753 754 public TableSwitchRule( String path) { 755 super( path); 756 } 757 758 public final void begin( String name, Attributes attrs) { 759 Map vals = new HashMap (); 760 vals.put( "min", attrs.getValue( "min")); 761 vals.put( "max", attrs.getValue( "max")); 762 vals.put( "dflt", attrs.getValue( "dflt")); 763 vals.put( "labels", new ArrayList ()); 764 push( vals); 765 } 766 767 public final void end( String name) { 768 Map vals = ( Map ) pop(); 769 int min = Integer.parseInt(( String ) vals.get( "min")); 770 int max = Integer.parseInt(( String ) vals.get( "max")); 771 Label dflt = getLabel( vals.get( "dflt")); 772 Label[] lbls = ( Label[])(( List ) vals.get( "labels")).toArray( new Label[ 0]); 773 getCodeVisitor().visitTableSwitchInsn( min, max, dflt, lbls); 774 } 775 776 } 777 778 779 782 private final class TableSwitchLabelRule extends Rule { 783 784 public TableSwitchLabelRule( String path) { 785 super( path); 786 } 787 788 public final void begin( String name, Attributes attrs) { 789 (( List ) (( Map ) peek()).get( "labels")).add( getLabel( attrs.getValue( "name"))); 790 } 791 792 } 793 794 795 798 private final class LookupSwitchRule extends Rule { 799 800 public LookupSwitchRule( String path) { 801 super( path); 802 } 803 804 public final void begin( String name, Attributes attrs) { 805 Map vals = new HashMap (); 806 vals.put( "dflt", attrs.getValue( "dflt")); 807 vals.put( "labels", new ArrayList ()); 808 vals.put( "keys", new ArrayList ()); 809 push( vals); 810 } 811 812 public final void end( String name) { 813 Map vals = ( Map ) pop(); 814 Label dflt = getLabel( vals.get( "dflt")); 815 List keyList = ( List ) vals.get( "keys"); 816 Label[] lbls = ( Label[])(( List ) vals.get( "labels")).toArray( new Label[ 0]); 817 int[] keys = new int[ keyList.size()]; 818 for( int i = 0; i < keys.length; i++) { 819 keys[ i] = Integer.parseInt(( String ) keyList.get( i)); 820 } 821 getCodeVisitor().visitLookupSwitchInsn( dflt, keys, lbls); 822 } 823 824 } 825 826 827 830 private final class LookupSwitchLabelRule extends Rule { 831 832 public LookupSwitchLabelRule( String path) { 833 super( path); 834 } 835 836 public final void begin( String name, Attributes attrs) { 837 Map vals = ( Map ) peek(); 838 (( List ) vals.get( "labels")).add( getLabel( attrs.getValue( "name"))); 839 (( List ) vals.get( "keys")).add( attrs.getValue( "key")); 840 } 841 842 } 843 844 845 848 private final class LabelRule extends Rule { 849 850 public LabelRule( String path) { 851 super( path); 852 } 853 854 public final void begin( String name, Attributes attrs) { 855 getCodeVisitor().visitLabel( getLabel( attrs.getValue( "name"))); 856 } 857 858 } 859 860 861 864 private final class TryCatchRule extends Rule { 865 866 public TryCatchRule( String path) { 867 super( path); 868 } 869 870 public final void begin( String name, Attributes attrs) { 871 Label start = getLabel( attrs.getValue( "start")); 872 Label end = getLabel( attrs.getValue( "end")); 873 Label handler = getLabel( attrs.getValue( "handler")); 874 String type = attrs.getValue( "type"); 875 getCodeVisitor().visitTryCatchBlock( start, end, handler, type); 876 } 877 878 } 879 880 881 884 private final class LineNumberRule extends Rule { 885 886 public LineNumberRule( String path) { 887 super( path); 888 } 889 890 public final void begin( String name, Attributes attrs) { 891 int line = Integer.parseInt( attrs.getValue( "line")); 892 Label start = getLabel( attrs.getValue( "start")); 893 getCodeVisitor().visitLineNumber( line, start); 894 } 895 896 } 897 898 899 902 private final class LocalVarRule extends Rule { 903 904 public LocalVarRule( String path) { 905 super( path); 906 } 907 908 public final void begin( String element, Attributes attrs) { 909 String name = attrs.getValue( "name"); 910 String desc = attrs.getValue( "desc"); 911 Label start = getLabel( attrs.getValue( "start")); 912 Label end = getLabel( attrs.getValue( "end")); 913 int var = Integer.parseInt( attrs.getValue( "var")); 914 getCodeVisitor().visitLocalVariable( name, desc, start, end, var); 915 } 916 917 } 918 919 920 923 private final class OpcodesRule extends Rule { 924 925 public OpcodesRule( String path) { 926 super( path); 927 } 928 929 public boolean match( String match, String element) { 930 return match.startsWith( path) && OPCODES.containsKey( element); 931 } 932 933 public final void begin( String element, Attributes attrs) { 934 Opcode o = (( Opcode) OPCODES.get( element)); 935 if( o==null) return; 936 937 switch( o.type) { 938 case OpcodeGroup.INSN: 939 getCodeVisitor().visitInsn( o.opcode); 940 break; 941 942 case OpcodeGroup.INSN_FIELD: 943 getCodeVisitor().visitFieldInsn( o.opcode, attrs.getValue( "owner"), attrs.getValue( "name"), attrs.getValue( "desc")); 944 break; 945 946 case OpcodeGroup.INSN_INT: 947 getCodeVisitor().visitIntInsn( o.opcode, Integer.parseInt( attrs.getValue( "value"))); 948 break; 949 950 case OpcodeGroup.INSN_JUMP: 951 getCodeVisitor().visitJumpInsn( o.opcode, getLabel( attrs.getValue( "label"))); 952 break; 953 954 case OpcodeGroup.INSN_METHOD: 955 getCodeVisitor().visitMethodInsn( o.opcode, attrs.getValue( "owner"), attrs.getValue( "name"), attrs.getValue( "desc")); 956 break; 957 958 case OpcodeGroup.INSN_TYPE: 959 getCodeVisitor().visitTypeInsn( o.opcode, attrs.getValue( "desc")); 960 break; 961 962 case OpcodeGroup.INSN_VAR: 963 getCodeVisitor().visitVarInsn( o.opcode, Integer.parseInt( attrs.getValue( "var"))); 964 break; 965 966 case OpcodeGroup.INSN_IINC: 967 getCodeVisitor().visitIincInsn( Integer.parseInt( attrs.getValue( "var")), Integer.parseInt( attrs.getValue( "inc"))); 968 break; 969 970 case OpcodeGroup.INSN_LDC: 971 getCodeVisitor().visitLdcInsn( getValue( attrs.getValue( "desc"), attrs.getValue( "cst"))); 972 break; 973 974 case OpcodeGroup.INSN_MULTIANEWARRAY: 975 getCodeVisitor().visitMultiANewArrayInsn( attrs.getValue( "desc"), Integer.parseInt( attrs.getValue( "dims"))); 976 break; 977 978 default: 979 throw new RuntimeException ( "Invalid element: "+element+" at "+match); 980 981 } 982 } 983 } 984 985 986 989 private final class MaxRule extends Rule { 990 991 public MaxRule( String path) { 992 super( path); 993 } 994 995 public final void begin( String element, Attributes attrs) { 996 int maxStack = Integer.parseInt( attrs.getValue( "maxStack")); 997 int maxLocals = Integer.parseInt( attrs.getValue( "maxLocals")); 998 getCodeVisitor().visitMaxs( maxStack, maxLocals); 999 } 1000 1001 } 1002 1003 1004 1007 private final static class Opcode { 1008 public int opcode; 1009 public int type; 1010 1011 public Opcode( int opcode, int type) { 1012 this.opcode = opcode; 1013 this.type = type; 1014 } 1015 1016 } 1017 1018} 1019 1020 | Popular Tags |