package scouter.agent.asm;
import scouter.agent.ClassDesc;
import scouter.agent.Configure;
import scouter.agent.Logger;
import scouter.agent.trace.TraceCollection;
import scouter.org.objectweb.asm.ClassVisitor;
import scouter.org.objectweb.asm.MethodVisitor;
import scouter.org.objectweb.asm.Opcodes;
import scouter.org.objectweb.asm.Type;
import scouter.org.objectweb.asm.commons.LocalVariablesSorter;
/**
* @author Gun Lee (gunlee01@gmail.com) on 2016. 9. 20.
*/
public class MapImplASM implements IASM, Opcodes {
public ClassVisitor transform(ClassVisitor cv, String className, ClassDesc classDesc) {
if (Configure.getInstance()._hook_map_impl_enabled == false) {
return cv;
}
if(classDesc.isMapImpl) {
return new MapImplCV(cv, className);
}
return cv;
}
}
class MapImplCV extends ClassVisitor implements Opcodes {
private static String TARGET_METHOD = "put";
private String className;
public MapImplCV(ClassVisitor cv, String className) {
super(ASM4, cv);
this.className = className;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
if (mv == null) {
return mv;
}
if (TARGET_METHOD.equals(name)) {
Logger.println("A201", "HOOK MAP IMPL - " + className);
return new MapImplMV(access, desc, mv, className);
}
return mv;
}
}
class MapImplMV extends LocalVariablesSorter implements Opcodes {
private static final String TRACECOLLECTION = TraceCollection.class.getName().replace('.', '/');
private final static String END_PUT = "endPut";
private static final String END_PUT_SIGNATURE = "(Ljava/util/Map;)V";
private String className;
public MapImplMV(int access, String desc, MethodVisitor mv, String className) {
super(ASM4, access, desc, mv);
this.className = className;
}
@Override
public void visitInsn(int opcode) {
if ((opcode >= IRETURN && opcode <= RETURN)) {
int pos = newLocal(Type.INT_TYPE);
mv.visitVarInsn(Opcodes.ALOAD, 0);
//mv.visitMethodInsn(INVOKEVIRTUAL, className, "size", "()I", false);
//mv.visitVarInsn(Opcodes.ISTORE, pos);
//mv.visitVarInsn(Opcodes.ILOAD, pos);
mv.visitMethodInsn(INVOKESTATIC, TRACECOLLECTION, END_PUT, END_PUT_SIGNATURE, false);
}
mv.visitInsn(opcode);
}
}