package nginx.clojure.wave;
import nginx.clojure.asm.Label;
import nginx.clojure.asm.MethodVisitor;
import nginx.clojure.asm.commons.AdviceAdapter;
public class SuspendMethodVerifyAdvice extends AdviceAdapter {
protected MethodDatabase db;
protected String owner;
protected String method;
private final Label start = new Label();
private final Label handler = new Label();
public SuspendMethodVerifyAdvice(MethodDatabase db,String owner, MethodVisitor mv, int access,
String name, String desc) {
super(ASM4, mv, access, name, desc);
this.db = db;
this.owner = owner;
this.method = name + desc;
}
public void visitCode() {
super.visitCode();
mv.visitLabel(start);
};
@Override
protected void onMethodEnter() {
mv.visitLdcInsn(owner);
mv.visitLdcInsn(method);
mv.visitMethodInsn(INVOKESTATIC, "nginx/clojure/wave/SuspendMethodVerifier", "enter", "(Ljava/lang/String;Ljava/lang/String;)V");
// if (method.equals("invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;")) {
// mv.visitVarInsn(ALOAD, 2);
// mv.visitMethodInsn(INVOKESTATIC, "nginx/clojure/wave/SuspendMethodVerifier", "downProxyInvoke", "(Ljava/lang/reflect/Method;)V");
// }
}
private final void doExitCode() {
// if (method.equals("invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;")) {
// mv.visitVarInsn(ALOAD, 2);
// mv.visitMethodInsn(INVOKESTATIC, "nginx/clojure/wave/SuspendMethodVerifier", "upProxyInvoke", "(Ljava/lang/reflect/Method;)V");
// }
mv.visitLdcInsn(owner);
mv.visitLdcInsn(method);
mv.visitMethodInsn(INVOKESTATIC, "nginx/clojure/wave/SuspendMethodVerifier", "leave", "(Ljava/lang/String;Ljava/lang/String;)V");
}
@Override
protected void onMethodExit(int opcode) {
if (opcode != ATHROW) {
doExitCode();
}
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
mv.visitTryCatchBlock(start, handler, handler, null);
mv.visitLabel(this.handler);
doExitCode();
mv.visitInsn(ATHROW);
mv.visitMaxs(Math.max(maxStack, 4), maxLocals);
}
}