1 package jp.sourceforge.stigmata.birthmarks;
7 import java.util.ArrayList;
10 import org.objectweb.asm.Label;
11 import org.objectweb.asm.MethodAdapter;
12 import org.objectweb.asm.MethodVisitor;
13 import org.objectweb.asm.Opcodes;
14 import org.objectweb.asm.Type;
18 * @author Haruaki TAMADA
21 public class OpcodeExtractMethodVisitor extends MethodAdapter{
22 private List<Opcode> opcodes;
23 private OpcodeManager manager = OpcodeManager.getInstance();
24 private List<OpcodeExtractListener> listeners = new ArrayList<OpcodeExtractListener>();
26 public OpcodeExtractMethodVisitor(MethodVisitor visitor){
27 this(visitor, new ArrayList<Opcode>());
30 public OpcodeExtractMethodVisitor(MethodVisitor visitor, List<Opcode> opcodes){
32 this.opcodes = opcodes;
35 public void addOpcodeExtractListener(OpcodeExtractListener listener){
36 listeners.add(listener);
39 public void removeOpcodeExtractListener(OpcodeExtractListener listener){
40 listeners.add(listener);
44 public void visitFieldInsn(int opcode, String owner, String name, String desc){
45 Opcode o = new Opcode(manager.getOpcode(opcode));
46 int size = Type.getType(desc).getSize();
48 case Opcodes.PUTFIELD:
51 case Opcodes.PUTSTATIC:
54 case Opcodes.GETFIELD:
57 case Opcodes.GETSTATIC:
63 super.visitFieldInsn(opcode, owner, name, desc);
67 public void visitIincInsn(int var, int increment){
68 opcodes.add(manager.getOpcode(Opcodes.IINC));
69 super.visitIincInsn(var, increment);
73 public void visitInsn(int opcode){
74 opcodes.add(manager.getOpcode(opcode));
75 super.visitInsn(opcode);
79 public void visitLabel(Label label){
80 opcodes.add(new LabelOpcode(label));
84 public void visitIntInsn(int opcode, int operand){
85 opcodes.add(manager.getOpcode(opcode));
86 super.visitIntInsn(opcode, operand);
90 public void visitJumpInsn(int opcode, Label label){
91 Opcode o = new Opcode(manager.getOpcode(opcode));
94 super.visitJumpInsn(opcode, label);
98 public void visitLdcInsn(Object value){
99 opcodes.add(manager.getOpcode(Opcodes.LDC));
100 super.visitLdcInsn(value);
104 public void visitTableSwitchInsn(int min, int max, Label defaultLabel, Label[] labels){
105 Opcode tableSwitch = new Opcode(manager.getOpcode(Opcodes.TABLESWITCH));
106 tableSwitch.setLabels(labels);
107 tableSwitch.addLabel(defaultLabel);
109 opcodes.add(tableSwitch);
110 super.visitTableSwitchInsn(min, max, defaultLabel, labels);
114 public void visitLookupSwitchInsn(Label defaultHandle, int[] keys, Label[] labels){
115 Opcode lookupSwitch = new Opcode(manager.getOpcode(Opcodes.LOOKUPSWITCH));
116 lookupSwitch.setLabels(labels);
117 lookupSwitch.addLabel(defaultHandle);
119 opcodes.add(lookupSwitch);
120 super.visitLookupSwitchInsn(defaultHandle, keys, labels);
124 public void visitMethodInsn(int opcode, String owner, String name, String desc){
125 Opcode methodOpcode = new Opcode(manager.getOpcode(opcode));
126 Type[] types = Type.getArgumentTypes(desc);
127 int argumentSize = 0;
128 for(Type type: types) argumentSize = type.getSize();
129 int size = Type.getReturnType(desc).getSize();
131 case Opcodes.INVOKESTATIC:
132 size = size - argumentSize;
134 case Opcodes.INVOKEINTERFACE:
135 case Opcodes.INVOKESPECIAL:
136 case Opcodes.INVOKEVIRTUAL:
137 size = size - argumentSize - 1;
140 methodOpcode.setAct(size);
142 opcodes.add(methodOpcode);
143 super.visitMethodInsn(opcode, owner, name, desc);
147 public void visitMultiANewArrayInsn(String desc, int dims){
148 opcodes.add(manager.getOpcode(Opcodes.MULTIANEWARRAY));
149 super.visitMultiANewArrayInsn(desc, dims);
153 public void visitTypeInsn(int opcode, String desc){
154 opcodes.add(manager.getOpcode(opcode));
155 super.visitTypeInsn(opcode, desc);
159 public void visitVarInsn(int opcode, int var){
160 opcodes.add(manager.getOpcode(opcode));
161 super.visitVarInsn(opcode, var);
165 public void visitEnd(){
166 for(OpcodeExtractListener listener: listeners){
167 listener.extractOpcodesFinished(opcodes);