better support LineBinding

This commit is contained in:
hengyunabc 2020-04-26 03:08:43 +08:00
parent 10575cf172
commit bbe10cb8d5
3 changed files with 43 additions and 13 deletions

View File

@ -313,27 +313,33 @@ public abstract class Binding {
} }
} }
@Documented @Documented
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(ElementType.PARAMETER) @java.lang.annotation.Target(ElementType.PARAMETER)
@BindingParserHandler(parser = LineBindingParser.class) @BindingParserHandler(parser = LineBindingParser.class)
public static @interface Line { public static @interface Line {
boolean optional() default false; boolean optional() default false;
/**
* 是否精确是在某个 LineNumberNode 如果为true的话会向上找到最接近的 LineNumberNode
*
* @return
*/
boolean exact() default false;
} }
public static class LineBindingParser implements BindingParser { public static class LineBindingParser implements BindingParser {
@Override @Override
public Binding parse(Annotation annotation) { public Binding parse(Annotation annotation) {
return new LineBinding(); Line line = (Line) annotation;
return new LineBinding(line.exact());
} }
} }
@Documented @Documented
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(ElementType.PARAMETER) @java.lang.annotation.Target(ElementType.PARAMETER)

View File

@ -8,17 +8,38 @@ import com.alibaba.arthas.deps.org.objectweb.asm.tree.LineNumberNode;
import com.taobao.arthas.bytekit.asm.location.Location; import com.taobao.arthas.bytekit.asm.location.Location;
import com.taobao.arthas.bytekit.utils.AsmOpUtils; import com.taobao.arthas.bytekit.utils.AsmOpUtils;
/**
*
* @author hengyunabc
*
*/
public class LineBinding extends Binding { public class LineBinding extends Binding {
private boolean exact;
public LineBinding(boolean exact) {
this.exact = exact;
}
@Override @Override
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) { public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
Location location = bindingContext.getLocation(); Location location = bindingContext.getLocation();
AbstractInsnNode insnNode = location.getInsnNode(); AbstractInsnNode insnNode = location.getInsnNode();
if (insnNode instanceof LineNumberNode) { if (exact) {
AsmOpUtils.push(instructions, ((LineNumberNode) insnNode).line); if (insnNode instanceof LineNumberNode) {
AsmOpUtils.push(instructions, ((LineNumberNode) insnNode).line);
} else {
throw new IllegalArgumentException("LineBinding location is not LineNumberNode, insnNode: " + insnNode);
}
} else { } else {
throw new IllegalArgumentException("LineBinding location is not LineNumberNode, insnNode: " + insnNode); while (insnNode != null) {
if (insnNode instanceof LineNumberNode) {
AsmOpUtils.push(instructions, ((LineNumberNode) insnNode).line);
break;
}
insnNode = insnNode.getPrevious();
}
} }
} }

View File

@ -28,6 +28,7 @@ public class AtInvokeTest {
public int testCall(int ii) { public int testCall(int ii) {
toBeCall(ii, 123L, ""); toBeCall(ii, 123L, "");
System.err.println("abc"); System.err.println("abc");
aaa("abc"); aaa("abc");
return 123; return 123;
} }
@ -60,10 +61,12 @@ public class AtInvokeTest {
public static void onInvoke( public static void onInvoke(
@Binding.This Object object, @Binding.This Object object,
@Binding.Class Object clazz @Binding.Class Object clazz
, ,
@Binding.Line int line,
@Binding.InvokeArgs Object[] args @Binding.InvokeArgs Object[] args
) { ) {
System.err.println("onInvoke: this" + object); System.err.println("onInvoke: line: " + line);
System.err.println("onInvoke: this: " + object);
} }
@AtInvoke(name = "toBeCall", inline = false, whenComplete = true) @AtInvoke(name = "toBeCall", inline = false, whenComplete = true)