AsmMethodBoost

This commit is contained in:
redkale
2023-12-20 20:22:39 +08:00
parent ebaf4ebe16
commit 3fba0a3eeb
3 changed files with 181 additions and 223 deletions

View File

@@ -6,12 +6,28 @@ package org.redkale.asm;
import java.io.InputStream; import java.io.InputStream;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.redkale.annotation.Nullable; import org.redkale.annotation.Nullable;
import static org.redkale.asm.Opcodes.ACC_PRIVATE;
import static org.redkale.asm.Opcodes.ACC_PROTECTED;
import static org.redkale.asm.Opcodes.ACC_PUBLIC;
import static org.redkale.asm.Opcodes.ALOAD;
import static org.redkale.asm.Opcodes.ARETURN;
import static org.redkale.asm.Opcodes.DLOAD;
import static org.redkale.asm.Opcodes.DRETURN;
import static org.redkale.asm.Opcodes.FLOAD;
import static org.redkale.asm.Opcodes.FRETURN;
import static org.redkale.asm.Opcodes.ILOAD;
import static org.redkale.asm.Opcodes.IRETURN;
import static org.redkale.asm.Opcodes.LLOAD;
import static org.redkale.asm.Opcodes.LRETURN;
import static org.redkale.asm.Opcodes.RETURN;
import org.redkale.util.Utility; import org.redkale.util.Utility;
/** /**
@@ -21,7 +37,15 @@ import org.redkale.util.Utility;
* *
* @since 2.8.0 * @since 2.8.0
*/ */
public interface AsmMethodBoost<T> { public abstract class AsmMethodBoost<T> {
protected final AtomicInteger fieldIndex = new AtomicInteger();
protected final Class serviceType;
protected AsmMethodBoost(Class serviceType) {
this.serviceType = serviceType;
}
public static AsmMethodBoost create(Collection<AsmMethodBoost> list) { public static AsmMethodBoost create(Collection<AsmMethodBoost> list) {
return new AsmMethodBoosts(list); return new AsmMethodBoosts(list);
@@ -31,6 +55,124 @@ public interface AsmMethodBoost<T> {
return new AsmMethodBoosts(items); return new AsmMethodBoosts(items);
} }
protected AsmMethodBean getMethodBean(Method method) {
Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(serviceType);
return AsmMethodBean.get(methodBeans, method);
}
protected MethodVisitor createMethodVisitor(ClassWriter cw, Method method, String newMethodName, AsmMethodBean methodBean) {
return new MethodDebugVisitor(cw.visitMethod(getAcc(method, newMethodName),
getNowMethodName(method, newMethodName), Type.getMethodDescriptor(method),
getMethodSignature(method, methodBean), getMethodExceptions(method, methodBean)));
}
protected int getAcc(Method method, String newMethodName) {
if (newMethodName != null) {
return ACC_PRIVATE;
}
return Modifier.isProtected(method.getModifiers()) ? ACC_PROTECTED : ACC_PUBLIC;
}
protected String getNowMethodName(Method method, String newMethodName) {
return newMethodName == null ? method.getName() : newMethodName;
}
protected String getMethodSignature(Method method, AsmMethodBean methodBean) {
return methodBean != null ? methodBean.getSignature() : null;
}
protected String[] getMethodExceptions(Method method, AsmMethodBean methodBean) {
if (methodBean == null) {
String[] exceptions = null;
Class<?>[] expTypes = method.getExceptionTypes();
if (expTypes.length > 0) {
exceptions = new String[expTypes.length];
for (int i = 0; i < expTypes.length; i++) {
exceptions[i] = expTypes[i].getName().replace('.', '/');
}
}
return exceptions;
} else {
return methodBean.getExceptions();
}
}
protected void visitRawAnnotation(Method method, String newMethodName, MethodVisitor mv, Class selfAnnType, List filterAnns) {
if (newMethodName == null) {
//给方法加上原有的Annotation
final Annotation[] anns = method.getAnnotations();
for (Annotation ann : anns) {
if (ann.annotationType() != selfAnnType
&& (filterAnns == null || !filterAnns.contains(ann.annotationType()))) {
Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
}
}
//给参数加上原有的Annotation
final Annotation[][] annss = method.getParameterAnnotations();
for (int k = 0; k < annss.length; k++) {
for (Annotation ann : annss[k]) {
Asms.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann);
}
}
}
}
protected List<Integer> visitVarInsnParamTypes(MethodVisitor mv, Method method) {
//传参数
Class[] paramTypes = method.getParameterTypes();
List<Integer> insns = new ArrayList<>();
int insn = 0;
for (Class pt : paramTypes) {
insn++;
if (pt.isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
} else if (pt == float.class) {
mv.visitVarInsn(FLOAD, insn++);
} else if (pt == double.class) {
mv.visitVarInsn(DLOAD, insn++);
} else {
mv.visitVarInsn(ILOAD, insn);
}
} else {
mv.visitVarInsn(ALOAD, insn);
}
insns.add(insn);
}
return insns;
}
protected void visitInsnReturn(MethodVisitor mv, Method method, Label l0, List<Integer> insns, AsmMethodBean methodBean) {
if (method.getGenericReturnType() == void.class) {
mv.visitInsn(RETURN);
} else {
Class returnclz = method.getReturnType();
if (returnclz.isPrimitive()) {
if (returnclz == long.class) {
mv.visitInsn(LRETURN);
} else if (returnclz == float.class) {
mv.visitInsn(FRETURN);
} else if (returnclz == double.class) {
mv.visitInsn(DRETURN);
} else {
mv.visitInsn(IRETURN);
}
} else {
mv.visitInsn(ARETURN);
}
}
Class[] paramTypes = method.getParameterTypes();
if (methodBean != null && paramTypes.length > 0) {
Label l2 = new Label();
mv.visitLabel(l2);
//mv.visitLocalVariable("this", thisClassDesc, null, l0, l2, 0);
List<String> fieldNames = methodBean.getFieldNames();
for (int i = 0; i < paramTypes.length; i++) {
mv.visitLocalVariable(fieldNames.get(i), Type.getDescriptor(paramTypes[i]), null, l0, l2, insns.get(i));
}
}
}
/** /**
* *
* 返回一个类所有方法的字节信息, key为: method.getName+':'+Type.getMethodDescriptor(method) * 返回一个类所有方法的字节信息, key为: method.getName+':'+Type.getMethodDescriptor(method)
@@ -53,7 +195,7 @@ public interface AsmMethodBoost<T> {
* *
* @return 需要屏蔽的注解 * @return 需要屏蔽的注解
*/ */
public List<Class<? extends Annotation>> filterMethodAnnotations(Method method); public abstract List<Class<? extends Annotation>> filterMethodAnnotations(Method method);
/** /**
* 对方法进行动态加强处理 * 对方法进行动态加强处理
@@ -67,7 +209,7 @@ public interface AsmMethodBoost<T> {
* *
* @return 下一个新的方法名不做任何处理应返回参数newMethodName * @return 下一个新的方法名不做任何处理应返回参数newMethodName
*/ */
public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, public abstract String doMethod(ClassWriter cw, String newDynName, String fieldPrefix,
List<Class<? extends Annotation>> filterAnns, Method method, @Nullable String newMethodName); List<Class<? extends Annotation>> filterAnns, Method method, @Nullable String newMethodName);
/** 处理所有动态方法后调用 /** 处理所有动态方法后调用
@@ -76,14 +218,14 @@ public interface AsmMethodBoost<T> {
* @param newDynName 动态新类名 * @param newDynName 动态新类名
* @param fieldPrefix 动态字段的前缀 * @param fieldPrefix 动态字段的前缀
*/ */
public void doAfterMethods(ClassWriter cw, String newDynName, String fieldPrefix); public abstract void doAfterMethods(ClassWriter cw, String newDynName, String fieldPrefix);
/** /**
* 实例对象进行操作,通常用于给动态的字段赋值 * 实例对象进行操作,通常用于给动态的字段赋值
* *
* @param service 实例对象 * @param service 实例对象
*/ */
public void doInstance(T service); public abstract void doInstance(T service);
/** /**
* 生产动态字节码的方法扩展器, 可以进行方法加强动作 * 生产动态字节码的方法扩展器, 可以进行方法加强动作
@@ -92,15 +234,17 @@ public interface AsmMethodBoost<T> {
* *
* @since 2.8.0 * @since 2.8.0
*/ */
static class AsmMethodBoosts<T> implements AsmMethodBoost<T> { static class AsmMethodBoosts<T> extends AsmMethodBoost<T> {
private final AsmMethodBoost[] items; private final AsmMethodBoost[] items;
public AsmMethodBoosts(Collection<AsmMethodBoost> list) { public AsmMethodBoosts(Collection<AsmMethodBoost> list) {
super(null);
this.items = list.toArray(new AsmMethodBoost[list.size()]); this.items = list.toArray(new AsmMethodBoost[list.size()]);
} }
public AsmMethodBoosts(AsmMethodBoost... items) { public AsmMethodBoosts(AsmMethodBoost... items) {
super(null);
this.items = items; this.items = items;
} }

View File

@@ -6,10 +6,7 @@ package org.redkale.cache.spi;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.redkale.asm.AnnotationVisitor; import org.redkale.asm.AnnotationVisitor;
import org.redkale.asm.AsmMethodBean; import org.redkale.asm.AsmMethodBean;
import org.redkale.asm.AsmMethodBoost; import org.redkale.asm.AsmMethodBoost;
@@ -17,7 +14,7 @@ import org.redkale.asm.Asms;
import org.redkale.asm.ClassWriter; import org.redkale.asm.ClassWriter;
import org.redkale.asm.FieldVisitor; import org.redkale.asm.FieldVisitor;
import org.redkale.asm.Label; import org.redkale.asm.Label;
import org.redkale.asm.MethodDebugVisitor; import org.redkale.asm.MethodVisitor;
import static org.redkale.asm.Opcodes.*; import static org.redkale.asm.Opcodes.*;
import org.redkale.asm.Type; import org.redkale.asm.Type;
import org.redkale.cache.Cached; import org.redkale.cache.Cached;
@@ -27,16 +24,12 @@ import org.redkale.util.RedkaleException;
* *
* @author zhangjx * @author zhangjx
*/ */
public class CacheAsmMethodBoost implements AsmMethodBoost { public class CacheAsmMethodBoost extends AsmMethodBoost {
private static final List<Class<? extends Annotation>> FILTER_ANN = List.of(Cached.class, DynForCache.class); private static final List<Class<? extends Annotation>> FILTER_ANN = List.of(Cached.class, DynForCache.class);
private final AtomicInteger fieldIndex = new AtomicInteger();
protected final Class serviceType;
public CacheAsmMethodBoost(Class serviceType) { public CacheAsmMethodBoost(Class serviceType) {
this.serviceType = serviceType; super(serviceType);
} }
@Override @Override
@@ -50,123 +43,38 @@ public class CacheAsmMethodBoost implements AsmMethodBoost {
if (cached == null) { if (cached == null) {
return newMethodName; return newMethodName;
} }
if (method.getAnnotation(DynForCache.class) != null) {
return newMethodName;
}
if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) { if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
throw new RedkaleException("@" + Cached.class.getSimpleName() + " can not on final or static method, but on " + method); throw new RedkaleException("@" + Cached.class.getSimpleName() + " can not on final or static method, but on " + method);
} }
if (!Modifier.isProtected(method.getModifiers()) && !Modifier.isPublic(method.getModifiers())) { if (!Modifier.isProtected(method.getModifiers()) && !Modifier.isPublic(method.getModifiers())) {
throw new RedkaleException("@" + Cached.class.getSimpleName() + " must on protected or public method, but on " + method); throw new RedkaleException("@" + Cached.class.getSimpleName() + " must on protected or public method, but on " + method);
} }
int acc;
String nowMethodName;
if (newMethodName == null) {
nowMethodName = method.getName();
acc = Modifier.isProtected(method.getModifiers()) ? ACC_PROTECTED : ACC_PUBLIC;
} else {
acc = ACC_PRIVATE;
nowMethodName = newMethodName;
}
final String rsMethodName = method.getName() + "_afterCache"; final String rsMethodName = method.getName() + "_afterCache";
final String dynFieldName = fieldPrefix + "_" + method.getName() + "CacheAction" + fieldIndex.incrementAndGet(); final String dynFieldName = fieldPrefix + "_" + method.getName() + "CacheAction" + fieldIndex.incrementAndGet();
{ { //定义一个新方法调用 this.rsMethodName
Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(serviceType); final AsmMethodBean methodBean = getMethodBean(method);
AsmMethodBean methodBean = AsmMethodBean.get(methodBeans, method);
final String cacheDynDesc = Type.getDescriptor(DynForCache.class); final String cacheDynDesc = Type.getDescriptor(DynForCache.class);
MethodDebugVisitor mv; final MethodVisitor mv = createMethodVisitor(cw, method, newMethodName, methodBean);
AnnotationVisitor av;
String signature = null;
String[] exceptions = null;
if (methodBean == null) {
Class<?>[] expTypes = method.getExceptionTypes();
if (expTypes.length > 0) {
exceptions = new String[expTypes.length];
for (int i = 0; i < expTypes.length; i++) {
exceptions[i] = expTypes[i].getName().replace('.', '/');
}
}
} else {
signature = methodBean.getSignature();
exceptions = methodBean.getExceptions();
}
//需要定义一个新方法调用 this.rsMethodName
mv = new MethodDebugVisitor(cw.visitMethod(acc, nowMethodName, Type.getMethodDescriptor(method), signature, exceptions));
//mv.setDebug(true); //mv.setDebug(true);
Label l0 = new Label(); Label l0 = new Label();
mv.visitLabel(l0); mv.visitLabel(l0);
av = mv.visitAnnotation(cacheDynDesc, true); AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true);
av.visit("dynField", dynFieldName); av.visit("dynField", dynFieldName);
Asms.visitAnnotation(av, cached); Asms.visitAnnotation(av, cached);
if (newMethodName == null) { visitRawAnnotation(method, newMethodName, mv, Cached.class, filterAnns);
//给方法加上原有的Annotation
final Annotation[] anns = method.getAnnotations();
for (Annotation ann : anns) {
if (ann.annotationType() != Cached.class
&& (filterAnns == null || !filterAnns.contains(ann.annotationType()))) {
Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
}
}
//给参数加上原有的Annotation
final Annotation[][] annss = method.getParameterAnnotations();
for (int k = 0; k < annss.length; k++) {
for (Annotation ann : annss[k]) {
Asms.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann);
}
}
}
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
//传参数 //传参数
Class[] paramTypes = method.getParameterTypes(); List<Integer> insns = visitVarInsnParamTypes(mv, method);
List<Integer> insns = new ArrayList<>();
int insn = 0;
for (Class pt : paramTypes) {
insn++;
if (pt.isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
} else if (pt == float.class) {
mv.visitVarInsn(FLOAD, insn++);
} else if (pt == double.class) {
mv.visitVarInsn(DLOAD, insn++);
} else {
mv.visitVarInsn(ILOAD, insn);
}
} else {
mv.visitVarInsn(ALOAD, insn);
}
insns.add(insn);
}
mv.visitMethodInsn(INVOKESPECIAL, newDynName, rsMethodName, Type.getMethodDescriptor(method), false); mv.visitMethodInsn(INVOKESPECIAL, newDynName, rsMethodName, Type.getMethodDescriptor(method), false);
if (method.getGenericReturnType() == void.class) { visitInsnReturn(mv, method, l0, insns, methodBean);
mv.visitInsn(RETURN);
} else {
Class returnclz = method.getReturnType();
if (returnclz.isPrimitive()) {
if (returnclz == long.class) {
mv.visitInsn(LRETURN);
} else if (returnclz == float.class) {
mv.visitInsn(FRETURN);
} else if (returnclz == double.class) {
mv.visitInsn(DRETURN);
} else {
mv.visitInsn(IRETURN);
}
} else {
mv.visitInsn(ARETURN);
}
}
if (methodBean != null && paramTypes.length > 0) {
Label l2 = new Label();
mv.visitLabel(l2);
//mv.visitLocalVariable("this", thisClassDesc, null, l0, l2, 0);
List<String> fieldNames = methodBean.getFieldNames();
for (int i = 0; i < paramTypes.length; i++) {
mv.visitLocalVariable(fieldNames.get(i), Type.getDescriptor(paramTypes[i]), null, l0, l2, insns.get(i));
}
}
mv.visitMaxs(20, 20); mv.visitMaxs(20, 20);
mv.visitEnd(); mv.visitEnd();
} }
{ { //定义字段
FieldVisitor fv = cw.visitField(ACC_PRIVATE, dynFieldName, Type.getDescriptor(CacheAction.class), null, null); FieldVisitor fv = cw.visitField(ACC_PRIVATE, dynFieldName, Type.getDescriptor(CacheAction.class), null, null);
fv.visitEnd(); fv.visitEnd();
} }

View File

@@ -6,17 +6,14 @@ package org.redkale.lock.spi;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.redkale.asm.AnnotationVisitor; import org.redkale.asm.AnnotationVisitor;
import org.redkale.asm.AsmMethodBean; import org.redkale.asm.AsmMethodBean;
import org.redkale.asm.AsmMethodBoost; import org.redkale.asm.AsmMethodBoost;
import org.redkale.asm.Asms; import org.redkale.asm.Asms;
import org.redkale.asm.ClassWriter; import org.redkale.asm.ClassWriter;
import org.redkale.asm.Label; import org.redkale.asm.Label;
import org.redkale.asm.MethodDebugVisitor; import org.redkale.asm.MethodVisitor;
import static org.redkale.asm.Opcodes.*; import static org.redkale.asm.Opcodes.*;
import org.redkale.asm.Type; import org.redkale.asm.Type;
import org.redkale.lock.Locked; import org.redkale.lock.Locked;
@@ -26,16 +23,12 @@ import org.redkale.util.RedkaleException;
* *
* @author zhangjx * @author zhangjx
*/ */
public class LockAsmMethodBoost implements AsmMethodBoost { public class LockAsmMethodBoost extends AsmMethodBoost {
private static final List<Class<? extends Annotation>> FILTER_ANN = List.of(Locked.class, DynForLock.class); private static final List<Class<? extends Annotation>> FILTER_ANN = List.of(Locked.class, DynForLock.class);
private final AtomicInteger fieldIndex = new AtomicInteger();
protected final Class serviceType;
public LockAsmMethodBoost(Class serviceType) { public LockAsmMethodBoost(Class serviceType) {
this.serviceType = serviceType; super(serviceType);
} }
@Override @Override
@@ -45,8 +38,11 @@ public class LockAsmMethodBoost implements AsmMethodBoost {
@Override @Override
public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, List filterAnns, Method method, final String newMethodName) { public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, List filterAnns, Method method, final String newMethodName) {
Locked cached = method.getAnnotation(Locked.class); Locked locked = method.getAnnotation(Locked.class);
if (cached == null) { if (locked == null) {
return newMethodName;
}
if (method.getAnnotation(DynForLock.class) != null) {
return newMethodName; return newMethodName;
} }
if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) { if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
@@ -55,114 +51,24 @@ public class LockAsmMethodBoost implements AsmMethodBoost {
if (!Modifier.isProtected(method.getModifiers()) && !Modifier.isPublic(method.getModifiers())) { if (!Modifier.isProtected(method.getModifiers()) && !Modifier.isPublic(method.getModifiers())) {
throw new RedkaleException("@" + Locked.class.getSimpleName() + " must on protected or public method, but on " + method); throw new RedkaleException("@" + Locked.class.getSimpleName() + " must on protected or public method, but on " + method);
} }
int acc;
String nowMethodName;
if (newMethodName == null) {
nowMethodName = method.getName();
acc = Modifier.isProtected(method.getModifiers()) ? ACC_PROTECTED : ACC_PUBLIC;
} else {
acc = ACC_PRIVATE;
nowMethodName = newMethodName;
}
final String rsMethodName = method.getName() + "_afterLock"; final String rsMethodName = method.getName() + "_afterLock";
final String dynFieldName = fieldPrefix + "_" + method.getName() + "LockAction" + fieldIndex.incrementAndGet(); final String dynFieldName = fieldPrefix + "_" + method.getName() + "LockAction" + fieldIndex.incrementAndGet();
{ { //定义一个新方法调用 this.rsMethodName
Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(serviceType); final AsmMethodBean methodBean = getMethodBean(method);
AsmMethodBean methodBean = AsmMethodBean.get(methodBeans, method);
final String lockDynDesc = Type.getDescriptor(DynForLock.class); final String lockDynDesc = Type.getDescriptor(DynForLock.class);
MethodDebugVisitor mv; final MethodVisitor mv = createMethodVisitor(cw, method, newMethodName, methodBean);
AnnotationVisitor av;
String signature = null;
String[] exceptions = null;
if (methodBean == null) {
Class<?>[] expTypes = method.getExceptionTypes();
if (expTypes.length > 0) {
exceptions = new String[expTypes.length];
for (int i = 0; i < expTypes.length; i++) {
exceptions[i] = expTypes[i].getName().replace('.', '/');
}
}
} else {
signature = methodBean.getSignature();
exceptions = methodBean.getExceptions();
}
//需要定义一个新方法调用 this.rsMethodName
mv = new MethodDebugVisitor(cw.visitMethod(acc, nowMethodName, Type.getMethodDescriptor(method), signature, exceptions));
//mv.setDebug(true); //mv.setDebug(true);
Label l0 = new Label(); Label l0 = new Label();
mv.visitLabel(l0); mv.visitLabel(l0);
av = mv.visitAnnotation(lockDynDesc, true); AnnotationVisitor av = mv.visitAnnotation(lockDynDesc, true);
av.visit("dynField", dynFieldName); av.visit("dynField", dynFieldName);
Asms.visitAnnotation(av, cached); Asms.visitAnnotation(av, locked);
if (newMethodName == null) { visitRawAnnotation(method, newMethodName, mv, Locked.class, filterAnns);
//给方法加上原有的Annotation
final Annotation[] anns = method.getAnnotations();
for (Annotation ann : anns) {
if (ann.annotationType() != Locked.class
&& (filterAnns == null || !filterAnns.contains(ann.annotationType()))) {
Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
}
}
//给参数加上原有的Annotation
final Annotation[][] annss = method.getParameterAnnotations();
for (int k = 0; k < annss.length; k++) {
for (Annotation ann : annss[k]) {
Asms.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann);
}
}
}
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
//传参数 List<Integer> insns = visitVarInsnParamTypes(mv, method);
Class[] paramTypes = method.getParameterTypes();
List<Integer> insns = new ArrayList<>();
int insn = 0;
for (Class pt : paramTypes) {
insn++;
if (pt.isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
} else if (pt == float.class) {
mv.visitVarInsn(FLOAD, insn++);
} else if (pt == double.class) {
mv.visitVarInsn(DLOAD, insn++);
} else {
mv.visitVarInsn(ILOAD, insn);
}
} else {
mv.visitVarInsn(ALOAD, insn);
}
insns.add(insn);
}
mv.visitMethodInsn(INVOKESPECIAL, newDynName, rsMethodName, Type.getMethodDescriptor(method), false); mv.visitMethodInsn(INVOKESPECIAL, newDynName, rsMethodName, Type.getMethodDescriptor(method), false);
if (method.getGenericReturnType() == void.class) { visitInsnReturn(mv, method, l0, insns, methodBean);
mv.visitInsn(RETURN);
} else {
Class returnclz = method.getReturnType();
if (returnclz.isPrimitive()) {
if (returnclz == long.class) {
mv.visitInsn(LRETURN);
} else if (returnclz == float.class) {
mv.visitInsn(FRETURN);
} else if (returnclz == double.class) {
mv.visitInsn(DRETURN);
} else {
mv.visitInsn(IRETURN);
}
} else {
mv.visitInsn(ARETURN);
}
}
if (methodBean != null && paramTypes.length > 0) {
Label l2 = new Label();
mv.visitLabel(l2);
//mv.visitLocalVariable("this", thisClassDesc, null, l0, l2, 0);
List<String> fieldNames = methodBean.getFieldNames();
for (int i = 0; i < paramTypes.length; i++) {
mv.visitLocalVariable(fieldNames.get(i), Type.getDescriptor(paramTypes[i]), null, l0, l2, insns.get(i));
}
}
mv.visitMaxs(20, 20); mv.visitMaxs(20, 20);
mv.visitEnd(); mv.visitEnd();
} }