in bytekit-core/src/main/java/com/alibaba/bytekit/asm/interceptor/InterceptorProcessor.java [192:228]
private void errorHandler(MethodProcessor methodProcessor, InsnList insnList) {
// MethodInsnNode printStackTrace = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V", false);
// insnList.add(printStackTrace);
// 第一个参数要求是 throwable ,或者一个exception ?
// 有很多 binding 并不能使用的,因为location不生效
BindingContext bindingContext = new BindingContext(null, methodProcessor, null);
Type methodType = Type.getMethodType(this.exceptionHandlerConfig.getMethodDesc());
Type[] argumentTypes = methodType.getArgumentTypes();
List<Binding> bindings = this.exceptionHandlerConfig.getBindings();
if(bindings.size() + 1 != argumentTypes.length) {
throw new IllegalArgumentException("errorHandler bindings size do not match error method args size.");
}
if(!argumentTypes[0].equals(Type.getType(Throwable.class))) {
throw new IllegalArgumentException("errorHandler method first arg type must be Throwable.");
}
// 组装好要调用的 static 函数的参数
for(Binding binding: bindings) {
if(binding.fromStack()) {
throw new IllegalArgumentException("errorHandler binding can not load value from stack!");
}
binding.pushOntoStack(insnList, bindingContext);
// 检查 回调函数的参数类型,看是否要box一下 ,检查是否原始类型就可以了。
if(AsmOpUtils.needBox(binding.getType(bindingContext))) {
AsmOpUtils.box(insnList, binding.getType(bindingContext));
}
}
insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, exceptionHandlerConfig.getOwner(), exceptionHandlerConfig.getMethodName(),
exceptionHandlerConfig.getMethodDesc(), false));
int size = methodType.getReturnType().getSize();
if (size == 1) {
AsmOpUtils.pop(insnList);
} else if (size == 2) {
AsmOpUtils.pop2(insnList);
}
}