private void writeGroovyMethods(ClassVisitor visitor, Class<?> managedTypeClass) { // Object propertyMissing(String name) MethodVisitor methodVisitor = declareMethod( visitor, "propertyMissing", GET_PROPERTY_MISSING_METHOD_DESCRIPTOR, CONCRETE_SIGNATURE); // throw new MissingPropertyException(name, <managed-type>.class) methodVisitor.visitTypeInsn(NEW, MISSING_PROPERTY_EXCEPTION_TYPE); methodVisitor.visitInsn(DUP); putFirstMethodArgumentOnStack(methodVisitor); putClassOnStack(methodVisitor, managedTypeClass); methodVisitor.visitMethodInsn( INVOKESPECIAL, MISSING_PROPERTY_EXCEPTION_TYPE, "<init>", MISSING_PROPERTY_CONSTRUCTOR_DESCRIPTOR, false); finishVisitingMethod(methodVisitor, ATHROW); // Object propertyMissing(String name, Object value) methodVisitor = declareMethod( visitor, "propertyMissing", SET_PROPERTY_MISSING_METHOD_DESCRIPTOR, CONCRETE_SIGNATURE); // throw new MissingPropertyException(name, <managed-type>.class) methodVisitor.visitTypeInsn(NEW, MISSING_PROPERTY_EXCEPTION_TYPE); methodVisitor.visitInsn(DUP); putFirstMethodArgumentOnStack(methodVisitor); putClassOnStack(methodVisitor, managedTypeClass); methodVisitor.visitMethodInsn( INVOKESPECIAL, MISSING_PROPERTY_EXCEPTION_TYPE, "<init>", MISSING_PROPERTY_CONSTRUCTOR_DESCRIPTOR, false); finishVisitingMethod(methodVisitor, ATHROW); // Object methodMissing(String name, Object args) methodVisitor = declareMethod( visitor, "methodMissing", METHOD_MISSING_METHOD_DESCRIPTOR, CONCRETE_SIGNATURE); // throw new MissingMethodException(name, <managed-type>.class, args) methodVisitor.visitTypeInsn(NEW, MISSING_METHOD_EXCEPTION_TYPE); methodVisitor.visitInsn(DUP); putMethodArgumentOnStack(methodVisitor, 1); putClassOnStack(methodVisitor, managedTypeClass); putMethodArgumentOnStack(methodVisitor, 2); methodVisitor.visitTypeInsn(CHECKCAST, OBJECT_ARRAY_TYPE); methodVisitor.visitMethodInsn( INVOKESPECIAL, MISSING_METHOD_EXCEPTION_TYPE, "<init>", MISSING_METHOD_EXCEPTION_CONSTRUCTOR_DESCRIPTOR, false); finishVisitingMethod(methodVisitor, ATHROW); }
private void castFirstStackElement(MethodVisitor methodVisitor, Class<?> returnType) { if (returnType.isPrimitive()) { unboxType(methodVisitor, returnType); } else { methodVisitor.visitTypeInsn(CHECKCAST, Type.getInternalName(returnType)); } }
protected void injectGetByIndex( ClassWriter classWriter, String targetClassName, List<Field> fields) { MethodVisitor methodVisitor = classWriter.visitMethod( ACC_PUBLIC, "get", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, new String[] {getInternalName(ILLEGAL_ACCESS_EXCEPTION.getCanonicalName())}); Boxer boxer = new Boxer(methodVisitor); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ILOAD, 2); int maxStack = 6; Label[] labels = new Label[fields.size()]; Label errorLabel = new Label(); for (int i = 0; i < fields.size(); i++) { labels[i] = new Label(); } methodVisitor.visitTableSwitchInsn(0, labels.length - 1, errorLabel, labels); if (!fields.isEmpty()) { maxStack--; for (int i = 0; i < fields.size(); i++) { Field field = fields.get(i); Class<?> type = field.getType(); String fieldDescriptor = Type.getDescriptor(type); methodVisitor.visitLabel(labels[i]); if (i == 0) methodVisitor.visitFrame(F_APPEND, 1, new Object[] {targetClassName}, 0, null); else methodVisitor.visitFrame(F_SAME, 0, null, 0, null); if (isPublic(field)) { methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitTypeInsn(CHECKCAST, targetClassName); methodVisitor.visitFieldInsn(GETFIELD, targetClassName, field.getName(), fieldDescriptor); boxer.box(Type.getType(type)); } else { injectReflectiveGetter(methodVisitor); } methodVisitor.visitInsn(ARETURN); } methodVisitor.visitLabel(errorLabel); methodVisitor.visitFrame(F_SAME, 0, null, 0, null); } injectException(methodVisitor, IllegalAccessException.class); methodVisitor.visitMaxs(maxStack, 3); methodVisitor.visitEnd(); }
private void throwExceptionBecauseCalledOnItself(MethodVisitor methodVisitor) { String exceptionInternalName = Type.getInternalName(UnsupportedOperationException.class); methodVisitor.visitTypeInsn(NEW, exceptionInternalName); methodVisitor.visitInsn(DUP); putConstantOnStack(methodVisitor, "Calling setters of a managed type on itself is not allowed"); String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, STRING_TYPE); methodVisitor.visitMethodInsn( INVOKESPECIAL, exceptionInternalName, CONSTRUCTOR_NAME, constructorDescriptor, false); methodVisitor.visitInsn(ATHROW); }
protected void injectException( MethodVisitor methodVisitor, Class<? extends Throwable> throwable) { methodVisitor.visitTypeInsn(NEW, getInternalName(throwable.getCanonicalName())); methodVisitor.visitInsn(DUP); methodVisitor.visitTypeInsn(NEW, "java/lang/StringBuilder"); methodVisitor.visitInsn(DUP); methodVisitor.visitLdcInsn("Invalid index: "); methodVisitor.visitMethodInsn( INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V"); methodVisitor.visitVarInsn(ILOAD, 2); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); methodVisitor.visitMethodInsn( INVOKESPECIAL, getInternalName(throwable.getCanonicalName()), "<init>", "(Ljava/lang/String;)V"); methodVisitor.visitInsn(ATHROW); }
// the overload of type Object for Groovy coercions: public void setFoo(Object foo) private void createTypeConvertingSetter( ClassVisitor visitor, Type generatedType, ModelProperty<?> property) { if (!property.isWritable() || !(property.getSchema() instanceof ScalarValueSchema)) { return; } Class<?> propertyClass = property.getType().getConcreteClass(); Type propertyType = Type.getType(propertyClass); Class<?> boxedClass = propertyClass.isPrimitive() ? BOXED_TYPES.get(propertyClass) : propertyClass; Type boxedType = Type.getType(boxedClass); Method setter = property.getSetter().getMethod(); MethodVisitor methodVisitor = declareMethod( visitor, setter.getName(), SET_OBJECT_PROPERTY_DESCRIPTOR, SET_OBJECT_PROPERTY_DESCRIPTOR); putThisOnStack(methodVisitor); putTypeConverterFieldValueOnStack(methodVisitor, generatedType); // Object converted = $typeConverter.convert(foo, Float.class, false); methodVisitor.visitVarInsn(ALOAD, 1); // put var #1 ('foo') on the stack methodVisitor.visitLdcInsn(boxedType); // push the constant Class onto the stack methodVisitor.visitInsn( propertyClass.isPrimitive() ? ICONST_1 : ICONST_0); // push int 1 or 0 (interpreted as true or false) onto the stack methodVisitor.visitMethodInsn( INVOKEINTERFACE, TYPE_CONVERTER_TYPE.getInternalName(), "convert", COERCE_TO_SCALAR_DESCRIPTOR, true); methodVisitor.visitTypeInsn(CHECKCAST, boxedType.getInternalName()); if (propertyClass.isPrimitive()) { unboxType(methodVisitor, propertyClass); } // invoke the typed setter, popping 'this' and 'converted' from the stack methodVisitor.visitMethodInsn( INVOKEVIRTUAL, generatedType.getInternalName(), setter.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, propertyType), false); finishVisitingMethod(methodVisitor); }
private void writeEqualsMethod(ClassVisitor cw, Type generatedType) { MethodVisitor methodVisitor = cw.visitMethod(Opcodes.ACC_PUBLIC, "equals", EQUALS_METHOD_DESCRIPTOR, null, null); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitVarInsn(ALOAD, 1); Label notSameLabel = new Label(); methodVisitor.visitJumpInsn(IF_ACMPNE, notSameLabel); methodVisitor.visitInsn(ICONST_1); methodVisitor.visitInsn(IRETURN); methodVisitor.visitLabel(notSameLabel); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitTypeInsn(INSTANCEOF, MANAGED_INSTANCE_TYPE); Label notManagedInstanceLabel = new Label(); methodVisitor.visitJumpInsn(IFNE, notManagedInstanceLabel); methodVisitor.visitInsn(ICONST_0); methodVisitor.visitInsn(IRETURN); methodVisitor.visitLabel(notManagedInstanceLabel); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, generatedType.getInternalName(), "getBackingNode", GET_BACKING_NODE_METHOD_DESCRIPTOR, false); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitTypeInsn(CHECKCAST, MANAGED_INSTANCE_TYPE); methodVisitor.visitMethodInsn( INVOKEINTERFACE, MANAGED_INSTANCE_TYPE, "getBackingNode", GET_BACKING_NODE_METHOD_DESCRIPTOR, true); methodVisitor.visitMethodInsn( INVOKEINTERFACE, MUTABLE_MODEL_NODE_TYPE, "equals", EQUALS_METHOD_DESCRIPTOR, true); finishVisitingMethod(methodVisitor, Opcodes.IRETURN); }
private void unboxType(MethodVisitor methodVisitor, Class<?> primitiveClass) { // Float f = (Float) tmp // f==null?0:f.floatValue() Class<?> boxedType = BOXED_TYPES.get(primitiveClass); Type primitiveType = Type.getType(primitiveClass); methodVisitor.visitTypeInsn(CHECKCAST, Type.getInternalName(boxedType)); methodVisitor.visitInsn(DUP); Label exit = new Label(); Label elseValue = new Label(); methodVisitor.visitJumpInsn(IFNONNULL, elseValue); methodVisitor.visitInsn(POP); pushDefaultValue(methodVisitor, primitiveClass); methodVisitor.visitJumpInsn(GOTO, exit); methodVisitor.visitLabel(elseValue); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, Type.getInternalName(boxedType), primitiveClass.getSimpleName() + "Value", Type.getMethodDescriptor(primitiveType), false); methodVisitor.visitLabel(exit); }
public static byte[] createTargetSetterFactory(String factoryName, String className, Type target) throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); MethodVisitor mv; String factoryType = AsmUtils.toType(factoryName); String classType = AsmUtils.toType(className); String targetType = AsmUtils.toType(target); cw.visit( V1_6, ACC_FINAL + ACC_PUBLIC + ACC_SUPER, factoryType, "L" + CELL_HANDLER_FACTORY_TYPE + "<L" + targetType + ";>;", CELL_HANDLER_FACTORY_TYPE, null); { mv = cw.visitMethod( ACC_PUBLIC, "<init>", "(" + AsmUtils.toDeclaredLType(Instantiator.class) + AsmUtils.toDeclaredLType(CsvColumnKey[].class) + AsmUtils.toDeclaredLType(ParsingContextFactory.class) + AsmUtils.toDeclaredLType(FieldMapperErrorHandler.class) + ")V", "(" + "L" + AsmUtils.toType(Instantiator.class) + "<L" + AsmUtils.toType(CsvMapperCellHandler.class) + "<L" + targetType + ";>;L" + targetType + ";>;" + AsmUtils.toDeclaredLType(CsvColumnKey[].class) + AsmUtils.toDeclaredLType(ParsingContextFactory.class) + "L" + AsmUtils.toType(FieldMapperErrorHandler.class) + "<L" + AsmUtils.toType(CsvColumnKey.class) + ";>;" + ")V", null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn( INVOKESPECIAL, CELL_HANDLER_FACTORY_TYPE, "<init>", "(" + AsmUtils.toDeclaredLType(Instantiator.class) + AsmUtils.toDeclaredLType(CsvColumnKey[].class) + AsmUtils.toDeclaredLType(ParsingContextFactory.class) + AsmUtils.toDeclaredLType(FieldMapperErrorHandler.class) + ")V", false); mv.visitInsn(RETURN); mv.visitMaxs(5, 5); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PUBLIC, "newInstance", "(" + AsmUtils.toDeclaredLType(DelayedCellSetter[].class) + AsmUtils.toDeclaredLType(CellSetter[].class) + ")" + AsmUtils.toDeclaredLType(CsvMapperCellHandler.class), "(" + "[L" + DELAYED_CELL_SETTER_TYPE + "<L" + targetType + ";*>;" + "[L" + CELL_SETTER_TYPE + "<L" + targetType + ";>;" + ")" + "L" + AsmUtils.toType(CsvMapperCellHandler.class) + "<L" + targetType + ";>;", null); mv.visitCode(); mv.visitTypeInsn(NEW, classType); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, factoryType, "instantiator", AsmUtils.toDeclaredLType(Instantiator.class)); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, factoryType, "keys", AsmUtils.toDeclaredLType(CsvColumnKey[].class)); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, factoryType, "parsingContextFactory", AsmUtils.toDeclaredLType(ParsingContextFactory.class)); mv.visitMethodInsn( INVOKEVIRTUAL, AsmUtils.toType(ParsingContextFactory.class), "newContext", "()" + AsmUtils.toDeclaredLType(ParsingContext.class), false); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, factoryType, "fieldErrorHandler", AsmUtils.toDeclaredLType(FieldMapperErrorHandler.class)); mv.visitMethodInsn( INVOKESPECIAL, classType, "<init>", "(" + AsmUtils.toDeclaredLType(Instantiator.class) + AsmUtils.toDeclaredLType(DelayedCellSetter[].class) + AsmUtils.toDeclaredLType(CellSetter[].class) + AsmUtils.toDeclaredLType(CsvColumnKey[].class) + AsmUtils.toDeclaredLType(ParsingContext.class) + AsmUtils.toDeclaredLType(FieldMapperErrorHandler.class) + ")V", false); mv.visitInsn(ARETURN); mv.visitMaxs(8, 3); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
private void writeConfigureMethod( ClassVisitor visitor, Type generatedType, ModelProperty<?> property) { if (!property.isWritable() && property.getSchema() instanceof CompositeSchema) { // Adds a void $propName(Closure<?> cl) method that delegates to model state MethodVisitor methodVisitor = declareMethod( visitor, property.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, CLOSURE_TYPE), null); putStateFieldValueOnStack(methodVisitor, generatedType); putConstantOnStack(methodVisitor, property.getName()); putFirstMethodArgumentOnStack(methodVisitor); methodVisitor.visitMethodInsn( INVOKEINTERFACE, MODEL_ELEMENT_STATE_TYPE_INTERNAL_NAME, "apply", STATE_APPLY_METHOD_DESCRIPTOR, true); finishVisitingMethod(methodVisitor); return; } if (!property.isWritable() && property.getSchema() instanceof UnmanagedImplStructSchema) { UnmanagedImplStructSchema<?> structSchema = (UnmanagedImplStructSchema<?>) property.getSchema(); if (!structSchema.isAnnotated()) { return; } // Adds a void $propName(Closure<?> cl) method that executes the closure MethodVisitor methodVisitor = declareMethod( visitor, property.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, CLOSURE_TYPE), null); putThisOnStack(methodVisitor); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, generatedType.getInternalName(), property.getGetters().get(0).getName(), Type.getMethodDescriptor(Type.getType(property.getType().getConcreteClass())), false); putFirstMethodArgumentOnStack(methodVisitor); methodVisitor.visitMethodInsn( INVOKESTATIC, Type.getInternalName(ClosureBackedAction.class), "execute", Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE, CLOSURE_TYPE), false); finishVisitingMethod(methodVisitor); return; } // Adds a void $propName(Closure<?> cl) method that throws MME, to avoid attempts to convert // closure to something else MethodVisitor methodVisitor = declareMethod( visitor, property.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, CLOSURE_TYPE), null); putThisOnStack(methodVisitor); putConstantOnStack(methodVisitor, property.getName()); methodVisitor.visitInsn(Opcodes.ICONST_1); methodVisitor.visitTypeInsn(Opcodes.ANEWARRAY, OBJECT_TYPE.getInternalName()); methodVisitor.visitInsn(Opcodes.DUP); methodVisitor.visitInsn(Opcodes.ICONST_0); putFirstMethodArgumentOnStack(methodVisitor); methodVisitor.visitInsn(Opcodes.AASTORE); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, generatedType.getInternalName(), "methodMissing", METHOD_MISSING_METHOD_DESCRIPTOR, false); finishVisitingMethod(methodVisitor); }
protected void injectConstructor(ClassWriter classWriter) { String resultName = getAccessorNameInternal(this.getTarget(), this.getAccessorType()); MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); ; methodVisitor.visitTypeInsn(NEW, "java/util/ArrayList"); methodVisitor.visitInsn(DUP); methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false); methodVisitor.visitVarInsn(ASTORE, 1); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, resultName, "getTargetClass", "()Ljava/lang/Class;", false); methodVisitor.visitVarInsn(ASTORE, 2); Label whileLoop = new Label(); // enter the "while (currentClass != Object.class)" loop methodVisitor.visitLabel(whileLoop); methodVisitor.visitFrame( Opcodes.F_FULL, 3, new Object[] {resultName, "java/util/List", "java/lang/Class"}, 0, new Object[] {}); methodVisitor.visitVarInsn(ALOAD, 2); methodVisitor.visitLdcInsn(Type.getType("Ljava/lang/Object;")); Label classNotObjectComparer = new Label(); // compares the current class to Object.class aka currentClass != Object.class methodVisitor.visitJumpInsn(IF_ACMPEQ, classNotObjectComparer); methodVisitor.visitVarInsn(ALOAD, 2); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Class", "getDeclaredFields", "()[Ljava/lang/reflect/Field;", false); methodVisitor.visitVarInsn(ASTORE, 3); methodVisitor.visitVarInsn(ALOAD, 3); methodVisitor.visitInsn(ARRAYLENGTH); methodVisitor.visitVarInsn(ISTORE, 4); methodVisitor.visitInsn(ICONST_0); methodVisitor.visitVarInsn(ISTORE, 5); Label cachingForLoop = new Label(); // this loop handles the storing of the fields (to the list) methodVisitor.visitLabel(cachingForLoop); methodVisitor.visitFrame( Opcodes.F_APPEND, 3, new Object[] {"[Ljava/lang/reflect/Field;", Opcodes.INTEGER, Opcodes.INTEGER}, 0, null); methodVisitor.visitVarInsn(ILOAD, 5); methodVisitor.visitVarInsn(ILOAD, 4); Label cachingForLoopIncrementLabel = new Label(); // handles the looping of the fields methodVisitor.visitJumpInsn(IF_ICMPGE, cachingForLoopIncrementLabel); methodVisitor.visitVarInsn(ALOAD, 3); methodVisitor.visitVarInsn(ILOAD, 5); methodVisitor.visitInsn(AALOAD); methodVisitor.visitVarInsn(ASTORE, 6); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitVarInsn(ALOAD, 6); methodVisitor.visitMethodInsn( INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true); methodVisitor.visitInsn(POP); methodVisitor.visitIincInsn(5, 1); methodVisitor.visitJumpInsn(GOTO, cachingForLoop); methodVisitor.visitLabel(cachingForLoopIncrementLabel); methodVisitor.visitFrame(Opcodes.F_CHOP, 3, null, 0, null); methodVisitor.visitVarInsn(ALOAD, 2); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Class", "getSuperclass", "()Ljava/lang/Class;", false); methodVisitor.visitVarInsn(ASTORE, 2); methodVisitor.visitJumpInsn(GOTO, whileLoop); methodVisitor.visitLabel(classNotObjectComparer); methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true); methodVisitor.visitTypeInsn(ANEWARRAY, "java/lang/reflect/Field"); methodVisitor.visitFieldInsn(PUTFIELD, resultName, "fieldTable", "[Ljava/lang/reflect/Field;"); methodVisitor.visitInsn(ICONST_0); methodVisitor.visitVarInsn(ISTORE, 3); Label storingForLoop = new Label(); // this for loop goes about storing the fields in the array defined in the // class methodVisitor.visitLabel(storingForLoop); methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null); methodVisitor.visitVarInsn(ILOAD, 3); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitFieldInsn(GETFIELD, resultName, "fieldTable", "[Ljava/lang/reflect/Field;"); methodVisitor.visitInsn(ARRAYLENGTH); Label storage = new Label(); // gets the field at position x and stores it in the cache (fieldTable) methodVisitor.visitJumpInsn(IF_ICMPGE, storage); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitFieldInsn(GETFIELD, resultName, "fieldTable", "[Ljava/lang/reflect/Field;"); methodVisitor.visitVarInsn(ILOAD, 3); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitVarInsn(ILOAD, 3); methodVisitor.visitMethodInsn( INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true); methodVisitor.visitTypeInsn(CHECKCAST, "java/lang/reflect/Field"); methodVisitor.visitInsn(AASTORE); methodVisitor.visitIincInsn(3, 1); methodVisitor.visitJumpInsn(GOTO, storingForLoop); methodVisitor.visitLabel(storage); methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); methodVisitor.visitInsn(RETURN); methodVisitor.visitMaxs(4, 7); methodVisitor.visitEnd(); }