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();
}
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();
}
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;
}
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();
}
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();
}
Aggregations