private void visitConstruction(MethodVisitor mv, String name, String desc) { // 1.准备输出方法数据 Pattern p = Pattern.compile("\\((.*)\\)(.*)"); Matcher m = p.matcher(desc); m.find(); String[] asmParams = ASMEngineTools.splitAsmType( m.group(1)); // "IIIILjava/lang/Integer;F[[[ILjava/lang.Boolean;" int paramCount = asmParams.length; // mv.visitVarInsn(ALOAD, 0); for (int i = 0; i < paramCount; i++) { String asmType = asmParams[i]; mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1); } mv.visitMethodInsn(INVOKESPECIAL, this.superClassName, name, desc); mv.visitInsn(RETURN); mv.visitMaxs(paramCount + 1, paramCount + 1); }
// 实现接口附加 private void buildInterfaceMethod(MethodVisitor mv, String name, String desc, Class<?> faceType) { // 例子代码 // public int getNames(int abc, Object abcc) { // try { // Class<?>[] arrayOfClass = new Class[] { int.class, Object.class }; // Object[] arrayOfObject = new Object[] { abc, abcc }; // // // Method localMethod = List.class.getMethod("getNames", arrayOfClass); // ClassLoader localLoader = getClass().getClassLoader(); // // // Object target = new InnerChainMethodDelegate("xxxx", // localLoader).invoke(localMethod, this, arrayOfObject); // return ((Integer) target).intValue(); // } catch (Throwable e) { // throw new RuntimeException(e); // } // } // 1.准备输出方法数据 Pattern p = Pattern.compile("\\((.*)\\)(.*)"); Matcher m = p.matcher(desc); m.find(); String[] asmParams = ASMEngineTools.splitAsmType( m.group(1)); // "IIIILjava/lang/Integer;F[[[ILjava/lang.Boolean;" String asmReturns = m.group(2); int paramCount = asmParams.length; int maxStack = 4; // 方法最大堆栈大小 int maxLocals = paramCount + 5; // 本地变量表大小 // Label tryBegin = new Label(); Label tryEnd = new Label(); Label tryCatch = new Label(); mv.visitTryCatchBlock(tryBegin, tryEnd, tryCatch, "java/lang/Throwable"); { // try { mv.visitLabel(tryBegin); // Class<?>[] pTypes = new Class[] { int.class, Object.class, boolean.class, short.class }; this.codeBuilder_2(mv, asmParams); mv.visitVarInsn(ASTORE, paramCount + 2); // Object[] pObjects = new Object[] { abc, abcc, abcc }; this.codeBuilder_1(mv, asmParams); mv.visitVarInsn(ASTORE, paramCount + 3); // // List.class.getMethod("getNames", arrayOfClass); mv.visitLdcInsn(Type.getType(ASMEngineTools.toAsmType(faceType))); mv.visitLdcInsn(name); mv.visitVarInsn(ALOAD, paramCount + 2); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); mv.visitVarInsn(ASTORE, paramCount + 4); // // ClassLoader localLoader = getClass().getClassLoader(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;"); mv.visitVarInsn(ASTORE, paramCount + 5); // // Object target = new InnerChainMethodDelegate("xxxx", localLoader).invoke(localMethod, this, // arrayOfObject); mv.visitTypeInsn(NEW, ASMEngineTools.replaceClassName(InnerChainMethodDelegate.class)); mv.visitInsn(DUP); mv.visitLdcInsn(this.classConfig.getClassName()); mv.visitLdcInsn(faceType.getName()); mv.visitVarInsn(ALOAD, paramCount + 5); mv.visitMethodInsn( INVOKESPECIAL, ASMEngineTools.replaceClassName(InnerChainMethodDelegate.class), "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V"); mv.visitVarInsn(ALOAD, paramCount + 4); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, paramCount + 3); mv.visitMethodInsn( INVOKEVIRTUAL, ASMEngineTools.replaceClassName(InnerChainMethodDelegate.class), "invoke", "(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, paramCount + 6); // // return mv.visitVarInsn(ALOAD, paramCount + 6); mv.visitLabel(tryEnd); this.codeBuilder_3(mv, asmReturns); } { // } catch (Exception e) { mv.visitLabel(tryCatch); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"}); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 5); mv.visitTypeInsn(INSTANCEOF, "java/lang/RuntimeException"); Label ifBlock = new Label(); mv.visitJumpInsn(IFEQ, ifBlock); mv.visitVarInsn(ALOAD, 5); mv.visitTypeInsn(CHECKCAST, "java/lang/RuntimeException"); mv.visitInsn(ATHROW); mv.visitLabel(ifBlock); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/Throwable"}, 0, null); mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn( INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); mv.visitMaxs(maxStack, maxLocals); } // } }