Search in sources :

Example 1 with MethodVisitor

use of org.simpleflatmapper.ow2asm.MethodVisitor in project SimpleFlatMapper by arnaudroger.

the class CsvMapperCellHandlerBuilder method appendPeekDelayedCellSetterValue.

private static <T> void appendPeekDelayedCellSetterValue(final DelayedCellSetterFactory<T, ?>[] delayedCellSetters, final ClassWriter cw, final String classType, final int maxMethodSize) {
    ShardingHelper.shard(delayedCellSetters.length, maxMethodSize, new AbstractMethodDispatchShardCallBack<T>(cw, classType, maxMethodSize) {

        @Override
        protected void appendLeafSwitch(MethodVisitor mv, int start, int end) {
            Label defaultLabel = new Label();
            Label[] labels = newLabels(end - start);
            mv.visitTableSwitchInsn(start, end - 1, defaultLabel, labels);
            for (int i = start; i < end; i++) {
                mv.visitLabel(labels[i - start]);
                mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                if (delayedCellSetters[i] != null) {
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    mv.visitFieldInsn(Opcodes.GETFIELD, classType, "delayedCellSetter" + i, "L" + DELAYED_CELL_SETTER_TYPE + ";");
                    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, DELAYED_CELL_SETTER_TYPE, "peekValue", "()Ljava/lang/Object;", true);
                    mv.visitInsn(Opcodes.ARETURN);
                } else if (i < (delayedCellSetters.length - 1)) {
                    mv.visitInsn(Opcodes.ACONST_NULL);
                    mv.visitInsn(Opcodes.ARETURN);
                }
            }
            mv.visitLabel(defaultLabel);
            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        }

        @Override
        protected int maxArgIndex() {
            return 1;
        }

        @Override
        protected void loadArguments(MethodVisitor mv) {
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitVarInsn(Opcodes.ILOAD, 1);
        }

        @Override
        protected int argIndex() {
            return 1;
        }

        @Override
        protected String name() {
            return "_peekDelayedCellSetterValue";
        }

        @Override
        protected String signature() {
            return "(I)Ljava/lang/Object;";
        }
    });
    MethodVisitor mv;
    mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "peekDelayedCellSetterValue", "(L" + AsmUtils.toAsmType(CsvColumnKey.class) + ";)Ljava/lang/Object;", null, null);
    mv.visitCode();
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, AsmUtils.toAsmType(CsvColumnKey.class), "getIndex", "()I", false);
    mv.visitVarInsn(Opcodes.ISTORE, 2);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, classType, "_peekDelayedCellSetterValue", "(I)Ljava/lang/Object;", false);
    mv.visitInsn(Opcodes.ARETURN);
    mv.visitMaxs(1, 2);
    mv.visitEnd();
}
Also used : Label(org.simpleflatmapper.ow2asm.Label) CsvColumnKey(org.simpleflatmapper.csv.CsvColumnKey) MethodVisitor(org.simpleflatmapper.ow2asm.MethodVisitor)

Example 2 with MethodVisitor

use of org.simpleflatmapper.ow2asm.MethodVisitor in project SimpleFlatMapper by arnaudroger.

the class CsvMapperCellHandlerBuilder method createTargetSetterFactory.

public static byte[] createTargetSetterFactory(String factoryName, String className, Type target) throws Exception {
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    MethodVisitor mv;
    String factoryType = AsmUtils.toAsmType(factoryName);
    String classType = AsmUtils.toAsmType(className);
    String targetType = AsmUtils.toAsmType(target);
    cw.visit(Opcodes.V1_6, Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, factoryType, "L" + CELL_HANDLER_FACTORY_TYPE + "<L" + targetType + ";>;", CELL_HANDLER_FACTORY_TYPE, null);
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(" + AsmUtils.toTargetTypeDeclaration(Instantiator.class) + AsmUtils.toTargetTypeDeclaration(CsvColumnKey[].class) + AsmUtils.toTargetTypeDeclaration(ParsingContextFactory.class) + AsmUtils.toTargetTypeDeclaration(FieldMapperErrorHandler.class) + ")V", "(" + "L" + AsmUtils.toAsmType(Instantiator.class) + "<L" + AsmUtils.toAsmType(CsvMapperCellHandler.class) + "<L" + targetType + ";>;L" + targetType + ";>;" + AsmUtils.toTargetTypeDeclaration(CsvColumnKey[].class) + AsmUtils.toTargetTypeDeclaration(ParsingContextFactory.class) + "L" + AsmUtils.toAsmType(FieldMapperErrorHandler.class) + "<L" + AsmUtils.toAsmType(CsvColumnKey.class) + ";>;" + ")V", null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitVarInsn(Opcodes.ALOAD, 2);
        mv.visitVarInsn(Opcodes.ALOAD, 3);
        mv.visitVarInsn(Opcodes.ALOAD, 4);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, CELL_HANDLER_FACTORY_TYPE, "<init>", "(" + AsmUtils.toTargetTypeDeclaration(Instantiator.class) + AsmUtils.toTargetTypeDeclaration(CsvColumnKey[].class) + AsmUtils.toTargetTypeDeclaration(ParsingContextFactory.class) + AsmUtils.toTargetTypeDeclaration(FieldMapperErrorHandler.class) + ")V", false);
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(5, 5);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "newInstance", "(" + AsmUtils.toTargetTypeDeclaration(DelayedCellSetter[].class) + AsmUtils.toTargetTypeDeclaration(CellSetter[].class) + ")" + AsmUtils.toTargetTypeDeclaration(CsvMapperCellHandler.class), "(" + "[L" + DELAYED_CELL_SETTER_TYPE + "<L" + targetType + ";*>;" + "[L" + CELL_SETTER_TYPE + "<L" + targetType + ";>;" + ")" + "L" + AsmUtils.toAsmType(CsvMapperCellHandler.class) + "<L" + targetType + ";>;", null);
        mv.visitCode();
        mv.visitTypeInsn(Opcodes.NEW, classType);
        mv.visitInsn(Opcodes.DUP);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, factoryType, "instantiator", AsmUtils.toTargetTypeDeclaration(Instantiator.class));
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitVarInsn(Opcodes.ALOAD, 2);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, factoryType, "keys", AsmUtils.toTargetTypeDeclaration(CsvColumnKey[].class));
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, factoryType, "parsingContextFactory", AsmUtils.toTargetTypeDeclaration(ParsingContextFactory.class));
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, AsmUtils.toAsmType(ParsingContextFactory.class), "newContext", "()" + AsmUtils.toTargetTypeDeclaration(ParsingContext.class), false);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, factoryType, "fieldErrorHandler", AsmUtils.toTargetTypeDeclaration(FieldMapperErrorHandler.class));
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, classType, "<init>", "(" + AsmUtils.toTargetTypeDeclaration(Instantiator.class) + AsmUtils.toTargetTypeDeclaration(DelayedCellSetter[].class) + AsmUtils.toTargetTypeDeclaration(CellSetter[].class) + AsmUtils.toTargetTypeDeclaration(CsvColumnKey[].class) + AsmUtils.toTargetTypeDeclaration(ParsingContext.class) + AsmUtils.toTargetTypeDeclaration(FieldMapperErrorHandler.class) + ")V", false);
        mv.visitInsn(Opcodes.ARETURN);
        mv.visitMaxs(8, 3);
        mv.visitEnd();
    }
    cw.visitEnd();
    return cw.toByteArray();
}
Also used : CellSetter(org.simpleflatmapper.csv.mapper.CellSetter) DelayedCellSetter(org.simpleflatmapper.csv.mapper.DelayedCellSetter) ParsingContext(org.simpleflatmapper.csv.ParsingContext) DelayedCellSetter(org.simpleflatmapper.csv.mapper.DelayedCellSetter) CsvColumnKey(org.simpleflatmapper.csv.CsvColumnKey) ParsingContextFactory(org.simpleflatmapper.csv.ParsingContextFactory) Instantiator(org.simpleflatmapper.reflect.Instantiator) CsvMapperCellHandler(org.simpleflatmapper.csv.mapper.CsvMapperCellHandler) FieldMapperErrorHandler(org.simpleflatmapper.map.FieldMapperErrorHandler) ClassWriter(org.simpleflatmapper.ow2asm.ClassWriter) MethodVisitor(org.simpleflatmapper.ow2asm.MethodVisitor)

Example 3 with MethodVisitor

use of org.simpleflatmapper.ow2asm.MethodVisitor in project SimpleFlatMapper by arnaudroger.

the class AsmInstantiatorDefinitionFactory method extractDefinitions.

public static List<InstantiatorDefinition> extractDefinitions(final Type target) throws IOException {
    final List<InstantiatorDefinition> constructors = new ArrayList<InstantiatorDefinition>();
    final Class<?> targetClass = TypeHelper.toClass(target);
    ClassLoader cl = targetClass.getClassLoader();
    if (cl == null) {
        cl = ClassLoader.getSystemClassLoader();
    }
    final String fileName = targetClass.getName().replace('.', '/') + ".class";
    final InputStream is = cl.getResourceAsStream(fileName);
    try {
        if (is == null) {
            throw new IOException("Cannot find file " + fileName + " in " + cl);
        }
        ClassReader classReader = new ClassReader(is);
        classReader.accept(new ClassVisitor(Opcodes.ASM5) {

            List<String> genericTypeNames;

            @Override
            public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
                if (signature != null) {
                    genericTypeNames = AsmUtils.extractGenericTypeNames(signature);
                } else {
                    genericTypeNames = Collections.emptyList();
                }
                super.visit(version, access, name, signature, superName, interfaces);
            }

            @Override
            public MethodVisitor visitMethod(int access, final String methodName, String desc, String signature, String[] exceptions) {
                final boolean isConstructor = "<init>".equals(methodName);
                if ((Opcodes.ACC_PUBLIC & access) == Opcodes.ACC_PUBLIC && (isConstructor || ((Opcodes.ACC_STATIC & access) == Opcodes.ACC_STATIC && !desc.endsWith("V")))) {
                    final List<String> descTypes = AsmUtils.extractTypeNamesFromSignature(desc);
                    final List<String> genericTypes;
                    final List<String> names = new ArrayList<String>();
                    if (signature != null) {
                        genericTypes = AsmUtils.extractTypeNamesFromSignature(signature);
                    } else {
                        genericTypes = descTypes;
                    }
                    if (!isConstructor) {
                        if (descTypes.size() > 0) {
                            try {
                                final Type genericType = AsmUtils.toGenericType(descTypes.get(descTypes.size() - 1), genericTypeNames, target);
                                if (!targetClass.isAssignableFrom(TypeHelper.toClass(genericType))) {
                                    return null;
                                }
                            } catch (ClassNotFoundException e) {
                                return null;
                            }
                        } else
                            return null;
                    }
                    return new MethodVisitor(Opcodes.ASM5) {

                        Label firstLabel;

                        Label lastLabel;

                        @Override
                        public void visitLabel(Label label) {
                            if (firstLabel == null) {
                                firstLabel = label;
                            }
                            lastLabel = label;
                        }

                        @Override
                        public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
                            if (start.equals(firstLabel) && end.equals(lastLabel) && !"this".equals(name)) {
                                names.add(name);
                            }
                        }

                        @Override
                        public void visitEnd() {
                            try {
                                final List<Parameter> parameters = new ArrayList<Parameter>();
                                int l = descTypes.size() - (isConstructor ? 0 : 1);
                                for (int i = 0; i < l; i++) {
                                    String name = "arg" + i;
                                    if (i < names.size()) {
                                        name = names.get(i);
                                    }
                                    parameters.add(createParameter(i, name, descTypes.get(i), genericTypes.get(i)));
                                }
                                final Member executable;
                                if (isConstructor) {
                                    executable = targetClass.getDeclaredConstructor(toTypeArray(parameters));
                                } else {
                                    executable = targetClass.getDeclaredMethod(methodName, toTypeArray(parameters));
                                }
                                constructors.add(new ExecutableInstantiatorDefinition(executable, parameters.toArray(new Parameter[0])));
                            } catch (Exception e) {
                                ErrorHelper.rethrow(e);
                            }
                        }

                        private Class<?>[] toTypeArray(List<Parameter> parameters) {
                            Class<?>[] types = new Class<?>[parameters.size()];
                            for (int i = 0; i < types.length; i++) {
                                types[i] = parameters.get(i).getType();
                            }
                            return types;
                        }

                        private Parameter createParameter(int index, String name, String desc, String signature) {
                            try {
                                Type basicType = AsmUtils.toGenericType(desc, genericTypeNames, target);
                                Type genericType = basicType;
                                if (signature != null) {
                                    Type type = AsmUtils.toGenericType(signature, genericTypeNames, target);
                                    if (type != null) {
                                        genericType = type;
                                    }
                                }
                                return new Parameter(index, name, TypeHelper.toClass(basicType), genericType);
                            } catch (ClassNotFoundException e) {
                                throw new Error("Unexpected error " + e, e);
                            }
                        }
                    };
                } else {
                    return null;
                }
            }
        }, 0);
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (Exception e) {
            }
        }
    }
    return constructors;
}
Also used : ExecutableInstantiatorDefinition(org.simpleflatmapper.reflect.instantiator.ExecutableInstantiatorDefinition) ArrayList(java.util.ArrayList) Label(org.simpleflatmapper.ow2asm.Label) ClassVisitor(org.simpleflatmapper.ow2asm.ClassVisitor) MethodVisitor(org.simpleflatmapper.ow2asm.MethodVisitor) ExecutableInstantiatorDefinition(org.simpleflatmapper.reflect.instantiator.ExecutableInstantiatorDefinition) InstantiatorDefinition(org.simpleflatmapper.reflect.InstantiatorDefinition) ArrayList(java.util.ArrayList) List(java.util.List) Member(java.lang.reflect.Member) InputStream(java.io.InputStream) IOException(java.io.IOException) IOException(java.io.IOException) Type(java.lang.reflect.Type) ClassReader(org.simpleflatmapper.ow2asm.ClassReader) Parameter(org.simpleflatmapper.reflect.Parameter)

Example 4 with MethodVisitor

use of org.simpleflatmapper.ow2asm.MethodVisitor in project SimpleFlatMapper by arnaudroger.

the class BiInstantiatorBuilder method appendNewInstance.

private static <S1, S2> void appendNewInstance(Class<?> s1, Class<?> s2, ExecutableInstantiatorDefinition instantiatorDefinition, List<InjectionPoint> injectionPoints, ClassWriter cw, String targetType, String s1Type, String s2Type, String classType, Parameter[] parameters) throws NoSuchMethodException {
    MethodVisitor mv;
    mv = cw.visitMethod(ACC_PUBLIC, "newInstance", "(" + AsmUtils.toTargetTypeDeclaration(s1Type) + AsmUtils.toTargetTypeDeclaration(s2Type) + ")" + AsmUtils.toTargetTypeDeclaration(targetType), null, new String[] { "java/lang/Exception" });
    mv.visitCode();
    mv.visitTypeInsn(NEW, targetType);
    mv.visitInsn(DUP);
    StringBuilder sb = new StringBuilder();
    for (Parameter p : parameters) {
        InjectionPoint function = findFunctionCalls(p, injectionPoints);
        sb.append(AsmUtils.toTargetTypeDeclaration(p.getType()));
        if (function == null) {
            newInstanceNullFunction(mv, p);
        } else {
            invokeBiFunction(function, classType, s1, s2, mv, null, false);
        }
    }
    Member exec = instantiatorDefinition.getExecutable();
    if (exec instanceof Constructor) {
        mv.visitMethodInsn(INVOKESPECIAL, targetType, "<init>", "(" + sb.toString() + ")V", false);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, AsmUtils.toAsmType(((Method) exec).getDeclaringClass()), exec.getName(), AsmUtils.toSignature((Method) exec), false);
    }
    mv.visitInsn(ARETURN);
    mv.visitMaxs(3, 2);
    mv.visitEnd();
}
Also used : Constructor(java.lang.reflect.Constructor) Parameter(org.simpleflatmapper.reflect.Parameter) Method(java.lang.reflect.Method) Member(java.lang.reflect.Member) MethodVisitor(org.simpleflatmapper.ow2asm.MethodVisitor)

Example 5 with MethodVisitor

use of org.simpleflatmapper.ow2asm.MethodVisitor in project SimpleFlatMapper by arnaudroger.

the class BiInstantiatorBuilder method appendBridgeMethod.

private static void appendBridgeMethod(ClassWriter cw, String targetType, String s1Type, String s2Type, String classType) {
    MethodVisitor mv;
    mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "newInstance", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", null, new String[] { "java/lang/Exception" });
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, s1Type);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitTypeInsn(CHECKCAST, s2Type);
    mv.visitMethodInsn(INVOKEVIRTUAL, classType, "newInstance", "(" + AsmUtils.toTargetTypeDeclaration(s1Type) + AsmUtils.toTargetTypeDeclaration(s2Type) + ")" + AsmUtils.toTargetTypeDeclaration(targetType), false);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(2, 2);
    mv.visitEnd();
}
Also used : MethodVisitor(org.simpleflatmapper.ow2asm.MethodVisitor)

Aggregations

MethodVisitor (org.simpleflatmapper.ow2asm.MethodVisitor)37 ClassWriter (org.simpleflatmapper.ow2asm.ClassWriter)12 Parameter (org.simpleflatmapper.reflect.Parameter)5 Method (java.lang.reflect.Method)4 Label (org.simpleflatmapper.ow2asm.Label)4 Member (java.lang.reflect.Member)3 Type (java.lang.reflect.Type)3 Instantiator (org.simpleflatmapper.reflect.Instantiator)3 Constructor (java.lang.reflect.Constructor)2 CsvColumnKey (org.simpleflatmapper.csv.CsvColumnKey)2 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Test (org.junit.Test)1 ParsingContext (org.simpleflatmapper.csv.ParsingContext)1 ParsingContextFactory (org.simpleflatmapper.csv.ParsingContextFactory)1 CellSetter (org.simpleflatmapper.csv.mapper.CellSetter)1 CsvMapperCellHandler (org.simpleflatmapper.csv.mapper.CsvMapperCellHandler)1 DelayedCellSetter (org.simpleflatmapper.csv.mapper.DelayedCellSetter)1