javassist.bytecode.Bytecode Java Examples

The following examples show how to use javassist.bytecode.Bytecode. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: FieldTransformer.java    From cacheonix-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
private void addSetFieldHandlerMethod(ClassFile classfile)
		throws CannotCompileException {
	ConstPool cp = classfile.getConstPool();
	int this_class_index = cp.getThisClassInfo();
	MethodInfo minfo = new MethodInfo(cp, SETFIELDHANDLER_METHOD_NAME,
	                                  SETFIELDHANDLER_METHOD_DESCRIPTOR);
	/* local variables | this | callback | */
	Bytecode code = new Bytecode(cp, 3, 3);
	// aload_0 // load this
	code.addAload(0);
	// aload_1 // load callback
	code.addAload(1);
	// putfield // put field "$JAVASSIST_CALLBACK" defined already
	code.addOpcode(Opcode.PUTFIELD);
	int field_index = cp.addFieldrefInfo(this_class_index,
	                                     HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR);
	code.addIndex(field_index);
	// return
	code.addOpcode(Opcode.RETURN);
	minfo.setCodeAttribute(code.toCodeAttribute());
	minfo.setAccessFlags(AccessFlag.PUBLIC);
	classfile.addMethod(minfo);
}
 
Example #2
Source File: JavasisstUnitTest.java    From tutorials with MIT License 6 votes vote down vote up
@Test
public void givenLoadedClass_whenAddConstructorToClass_shouldCreateClassWithConstructor() throws NotFoundException, CannotCompileException, BadBytecode {
    // given
    ClassFile cf = ClassPool.getDefault().get("com.baeldung.javasisst.Point").getClassFile();
    Bytecode code = new Bytecode(cf.getConstPool());
    code.addAload(0);
    code.addInvokespecial("java/lang/Object", MethodInfo.nameInit, "()V");
    code.addReturn(null);

    // when
    MethodInfo minfo = new MethodInfo(cf.getConstPool(), MethodInfo.nameInit, "()V");
    minfo.setCodeAttribute(code.toCodeAttribute());
    cf.addMethod(minfo);

    // then
    CodeIterator ci = code.toCodeAttribute().iterator();
    List<String> operations = new LinkedList<>();
    while (ci.hasNext()) {
        int index = ci.next();
        int op = ci.byteAt(index);
        operations.add(Mnemonic.OPCODE[op]);
    }

    assertEquals(operations, Arrays.asList("aload_0", "invokespecial", "return"));

}
 
Example #3
Source File: FieldTransformer.java    From cacheonix-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
private static void addTypeDependDataReturn(Bytecode code, String typeName) {
	if ((typeName.charAt(0) == 'L')
	    && (typeName.charAt(typeName.length() - 1) == ';')
	    || (typeName.charAt(0) == '[')) {
		// reference type
		code.addOpcode(Opcode.ARETURN);
	} else if (typeName.equals("Z") || typeName.equals("B")
	           || typeName.equals("C") || typeName.equals("I")
	           || typeName.equals("S")) {
		// boolean, byte, char, int, short
		code.addOpcode(Opcode.IRETURN);
	} else if (typeName.equals("D")) {
		// double
		code.addOpcode(Opcode.DRETURN);
	} else if (typeName.equals("F")) {
		// float
		code.addOpcode(Opcode.FRETURN);
	} else if (typeName.equals("J")) {
		// long
		code.addOpcode(Opcode.LRETURN);
	} else {
		// bad type
		throw new RuntimeException("bad type: " + typeName);
	}
}
 
Example #4
Source File: FieldTransformer.java    From cacheonix-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
private static void addTypeDependDataStore(Bytecode code, String typeName,
                                           int i) {
	if ((typeName.charAt(0) == 'L')
	    && (typeName.charAt(typeName.length() - 1) == ';')
	    || (typeName.charAt(0) == '[')) {
		// reference type
		code.addAstore(i);
	} else if (typeName.equals("Z") || typeName.equals("B")
	           || typeName.equals("C") || typeName.equals("I")
	           || typeName.equals("S")) {
		// boolean, byte, char, int, short
		code.addIstore(i);
	} else if (typeName.equals("D")) {
		// double
		code.addDstore(i);
	} else if (typeName.equals("F")) {
		// float
		code.addFstore(i);
	} else if (typeName.equals("J")) {
		// long
		code.addLstore(i);
	} else {
		// bad type
		throw new RuntimeException("bad type: " + typeName);
	}
}
 
Example #5
Source File: FieldTransformer.java    From cacheonix-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
private static void addTypeDependDataLoad(Bytecode code, String typeName,
                                          int i) {
	if ((typeName.charAt(0) == 'L')
	    && (typeName.charAt(typeName.length() - 1) == ';')
	    || (typeName.charAt(0) == '[')) {
		// reference type
		code.addAload(i);
	} else if (typeName.equals("Z") || typeName.equals("B")
	           || typeName.equals("C") || typeName.equals("I")
	           || typeName.equals("S")) {
		// boolean, byte, char, int, short
		code.addIload(i);
	} else if (typeName.equals("D")) {
		// double
		code.addDload(i);
	} else if (typeName.equals("F")) {
		// float
		code.addFload(i);
	} else if (typeName.equals("J")) {
		// long
		code.addLload(i);
	} else {
		// bad type
		throw new RuntimeException("bad type: " + typeName);
	}
}
 
Example #6
Source File: FieldTransformer.java    From cacheonix-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
private void addGetFieldHandlerMethod(ClassFile classfile)
		throws CannotCompileException {
	ConstPool cp = classfile.getConstPool();
	int this_class_index = cp.getThisClassInfo();
	MethodInfo minfo = new MethodInfo(cp, GETFIELDHANDLER_METHOD_NAME,
	                                  GETFIELDHANDLER_METHOD_DESCRIPTOR);
	/* local variable | this | */
	Bytecode code = new Bytecode(cp, 2, 1);
	// aload_0 // load this
	code.addAload(0);
	// getfield // get field "$JAVASSIST_CALLBACK" defined already
	code.addOpcode(Opcode.GETFIELD);
	int field_index = cp.addFieldrefInfo(this_class_index,
	                                     HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR);
	code.addIndex(field_index);
	// areturn // return the value of the field
	code.addOpcode(Opcode.ARETURN);
	minfo.setCodeAttribute(code.toCodeAttribute());
	minfo.setAccessFlags(AccessFlag.PUBLIC);
	classfile.addMethod(minfo);
}
 
Example #7
Source File: BulkAccessorFactory.java    From cacheonix-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Declares a constructor that takes no parameter.
 *
 * @param classfile
 * @throws CannotCompileException
 */
private void addDefaultConstructor(ClassFile classfile) throws CannotCompileException {
	ConstPool cp = classfile.getConstPool();
	String cons_desc = "()V";
	MethodInfo mi = new MethodInfo( cp, MethodInfo.nameInit, cons_desc );

	Bytecode code = new Bytecode( cp, 0, 1 );
	// aload_0
	code.addAload( 0 );
	// invokespecial
	code.addInvokespecial( BulkAccessor.class.getName(), MethodInfo.nameInit, cons_desc );
	// return
	code.addOpcode( Opcode.RETURN );

	mi.setCodeAttribute( code.toCodeAttribute() );
	mi.setAccessFlags( AccessFlag.PUBLIC );
	classfile.addMethod( mi );
}
 
Example #8
Source File: BulkAccessorFactory.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Declares a constructor that takes no parameter.
 *
 * @param classfile The class descriptor
 *
 * @throws CannotCompileException Indicates trouble with the underlying Javassist calls
 */
private void addDefaultConstructor(ClassFile classfile) throws CannotCompileException {
	final ConstPool constPool = classfile.getConstPool();
	final String constructorSignature = "()V";
	final MethodInfo constructorMethodInfo = new MethodInfo( constPool, MethodInfo.nameInit, constructorSignature );

	final Bytecode code = new Bytecode( constPool, 0, 1 );
	// aload_0
	code.addAload( 0 );
	// invokespecial
	code.addInvokespecial( BulkAccessor.class.getName(), MethodInfo.nameInit, constructorSignature );
	// return
	code.addOpcode( Opcode.RETURN );

	constructorMethodInfo.setCodeAttribute( code.toCodeAttribute() );
	constructorMethodInfo.setAccessFlags( AccessFlag.PUBLIC );
	classfile.addMethod( constructorMethodInfo );
}
 
Example #9
Source File: BulkAccessorFactory.java    From cacheonix-core with GNU Lesser General Public License v2.1 5 votes vote down vote up
private void addUnwrapper(
		ClassFile classfile,
        Bytecode code,
        Class type) {
	int index = FactoryHelper.typeIndex( type );
	String wrapperType = FactoryHelper.wrapperTypes[index];
	// checkcast
	code.addCheckcast( wrapperType );
	// invokevirtual
	code.addInvokevirtual( wrapperType, FactoryHelper.unwarpMethods[index], FactoryHelper.unwrapDesc[index] );
}
 
Example #10
Source File: BulkAccessorFactory.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private void addUnwrapper(Bytecode code, Class type) {
	final int index = FactoryHelper.typeIndex( type );
	final String wrapperType = FactoryHelper.wrapperTypes[index];
	// checkcast
	code.addCheckcast( wrapperType );
	// invokevirtual
	code.addInvokevirtual( wrapperType, FactoryHelper.unwarpMethods[index], FactoryHelper.unwrapDesc[index] );
}
 
Example #11
Source File: JavassistPerfTest.java    From annotation-tools with MIT License 5 votes vote down vote up
byte[] counterAdaptClass(final InputStream is, final String name)
        throws Exception
{
    CtClass cc = pool.makeClass(is);
    if (!cc.isInterface()) {
        cc.addField(new CtField(CtClass.intType, "_counter", cc));
    }
    CtMethod[] ms = cc.getDeclaredMethods();
    for (int j = 0; j < ms.length; ++j) {
        CtMethod m = ms[j];
        int modifiers = m.getModifiers();
        if (!Modifier.isStatic(modifiers)
                && !Modifier.isAbstract(modifiers)
                && !Modifier.isNative(modifiers))
        {
            if (!m.isEmpty()) {
                MethodInfo info = m.getMethodInfo();
                Bytecode bc = new Bytecode(info.getConstPool(), 1, 0);
                bc.addAload(0);
                bc.addAload(0);
                bc.addGetfield(cc, "_counter", "I");
                bc.add(Opcode.ICONST_1);
                bc.add(Opcode.IADD);
                bc.addPutfield(cc, "_counter", "I");
                CodeIterator iter = info.getCodeAttribute().iterator();
                iter.begin();
                iter.insert(bc.get());
            }
        }
    }
    return cc.toBytecode();
}
 
Example #12
Source File: JavassistPerfTest.java    From annotation-tools with MIT License 5 votes vote down vote up
byte[] counterAdaptClass(final InputStream is, final String name)
        throws Exception
{
    CtClass cc = pool.makeClass(is);
    if (!cc.isInterface()) {
        cc.addField(new CtField(CtClass.intType, "_counter", cc));
    }
    CtMethod[] ms = cc.getDeclaredMethods();
    for (int j = 0; j < ms.length; ++j) {
        CtMethod m = ms[j];
        int modifiers = m.getModifiers();
        if (!Modifier.isStatic(modifiers)
                && !Modifier.isAbstract(modifiers)
                && !Modifier.isNative(modifiers))
        {
            if (!m.isEmpty()) {
                MethodInfo info = m.getMethodInfo();
                Bytecode bc = new Bytecode(info.getConstPool(), 1, 0);
                bc.addAload(0);
                bc.addAload(0);
                bc.addGetfield(cc, "_counter", "I");
                bc.add(Opcode.ICONST_1);
                bc.add(Opcode.IADD);
                bc.addPutfield(cc, "_counter", "I");
                CodeIterator iter = info.getCodeAttribute().iterator();
                iter.begin();
                iter.insert(bc.get());
            }
        }
    }
    return cc.toBytecode();
}
 
Example #13
Source File: BulkAccessorFactory.java    From cacheonix-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
private void addGetter(ClassFile classfile, final Method[] getters) throws CannotCompileException {
	ConstPool cp = classfile.getConstPool();
	int target_type_index = cp.addClassInfo( this.targetBean.getName() );
	String desc = GET_SETTER_DESC;
	MethodInfo mi = new MethodInfo( cp, GENERATED_GETTER_NAME, desc );

	Bytecode code = new Bytecode( cp, 6, 4 );
	/* | this | bean | args | raw bean | */
	if ( getters.length >= 0 ) {
		// aload_1 // load bean
		code.addAload( 1 );
		// checkcast // cast bean
		code.addCheckcast( this.targetBean.getName() );
		// astore_3 // store bean
		code.addAstore( 3 );
		for ( int i = 0; i < getters.length; ++i ) {
			if ( getters[i] != null ) {
				Method getter = getters[i];
				// aload_2 // args
				code.addAload( 2 );
				// iconst_i // continue to aastore
				code.addIconst( i ); // growing stack is 1
				Class returnType = getter.getReturnType();
				int typeIndex = -1;
				if ( returnType.isPrimitive() ) {
					typeIndex = FactoryHelper.typeIndex( returnType );
					// new
					code.addNew( FactoryHelper.wrapperTypes[typeIndex] );
					// dup
					code.addOpcode( Opcode.DUP );
				}

				// aload_3 // load the raw bean
				code.addAload( 3 );
				String getter_desc = RuntimeSupport.makeDescriptor( getter );
				String getterName = getter.getName();
				if ( this.targetBean.isInterface() ) {
					// invokeinterface
					code.addInvokeinterface( target_type_index, getterName, getter_desc, 1 );
				}
				else {
					// invokevirtual
					code.addInvokevirtual( target_type_index, getterName, getter_desc );
				}

				if ( typeIndex >= 0 ) {       // is a primitive type
					// invokespecial
					code.addInvokespecial(
							FactoryHelper.wrapperTypes[typeIndex],
					        MethodInfo.nameInit,
					        FactoryHelper.wrapperDesc[typeIndex]
					);
				}

				// aastore // args
				code.add( Opcode.AASTORE );
				code.growStack( -3 );
			}
		}
	}
	// return
	code.addOpcode( Opcode.RETURN );

	mi.setCodeAttribute( code.toCodeAttribute() );
	mi.setAccessFlags( AccessFlag.PUBLIC );
	classfile.addMethod( mi );
}
 
Example #14
Source File: Javassists.java    From ProjectAres with GNU Affero General Public License v3.0 4 votes vote down vote up
public static CtMethod delegateMethod(CtClass implClass, CtMethod method, CtMethod delegateGetter) throws NotFoundException, CannotCompileException {
    checkArgument(!Modifier.isStatic(method.getModifiers()),
                  "Cannot delegate static method " + method.getLongName());
    checkArgument(!Modifier.isStatic(delegateGetter.getModifiers()),
                  "Delegate getter method " + delegateGetter.getLongName() + " must not be static");
    checkArgument(isSubtype(delegateGetter.getDeclaringClass(), implClass),
                  "Implementation class " + implClass + " does not contain delegate getter method " + delegateGetter.getLongName());
    checkArgument(delegateGetter.getParameterTypes().length == 0,
                  "Delegate getter method " + delegateGetter.getLongName() + " must not take any parameters");
    checkArgument(!delegateGetter.getReturnType().isPrimitive(),
                  "Delegate getter method " + delegateGetter.getLongName() + " must return an object");

    try {
        final CtMethod conflict = implClass.getDeclaredMethod(method.getName(), method.getParameterTypes());
        throw new IllegalArgumentException("Class " + implClass.getName() +
                                           " already contains a method " + conflict.getLongName() +
                                           " that conflicts with the delegated method " + method.getLongName());
    } catch(NotFoundException ignored) {}

    final String name = method.getName();
    final CtClass[] paramTypes = method.getParameterTypes();
    final CtClass returnType = method.getReturnType();
    final MethodInfo info = method.getMethodInfo2(); // Must be read-only
    final String descriptor = info.getDescriptor();
    final CtClass decl = method.getDeclaringClass();

    final Bytecode bc = new Bytecode(implClass.getClassFile().getConstPool());
    int maxStack = 1;
    bc.addAload(0); // push this
    bc.addInvokeinterface(delegateGetter.getDeclaringClass(), delegateGetter.getName(), delegateGetter.getReturnType(), null, 1); // get delegate
    bc.addCheckcast(decl); // make the verifier happy
    maxStack += bc.addLoadParameters(paramTypes, 1); // push all params
    if(decl.isInterface()) { // call the method on delegate
        bc.addInvokeinterface(decl, name, descriptor, 1 + paramTypes.length);
    } else {
        bc.addInvokevirtual(decl, name, descriptor);
    }
    bc.addReturn(returnType); // forward the return value

    bc.setMaxLocals(false, paramTypes, 0);
    bc.setMaxStack(Math.max(2, maxStack)); // return value might be up to 2 stack ops

    final CtMethod delegator = CtNewMethod.copy(method, implClass, null);
    setAccessModifiers(delegator, method.getModifiers());
    setModifier(delegator, Modifier.ABSTRACT, false);
    setModifier(delegator, Modifier.NATIVE, false);
    delegator.getMethodInfo().setCodeAttribute(bc.toCodeAttribute());
    implClass.addMethod(delegator);
    return delegator;
}
 
Example #15
Source File: FieldTransformer.java    From cacheonix-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
private void addReadMethod(ClassFile classfile, FieldInfo finfo)
		throws CannotCompileException {
	ConstPool cp = classfile.getConstPool();
	int this_class_index = cp.getThisClassInfo();
	String desc = "()" + finfo.getDescriptor();
	MethodInfo minfo = new MethodInfo(cp, EACH_READ_METHOD_PREFIX
	                                      + finfo.getName(), desc);
	/* local variables | target obj | each oldvalue | */
	Bytecode code = new Bytecode(cp, 5, 3);
	// aload_0
	code.addAload(0);
	// getfield // get each field
	code.addOpcode(Opcode.GETFIELD);
	int base_field_index = cp.addFieldrefInfo(this_class_index, finfo
			.getName(), finfo.getDescriptor());
	code.addIndex(base_field_index);
	// aload_0
	code.addAload(0);
	// invokeinterface // invoke Enabled.getInterceptFieldCallback()
	int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME);
	code.addInvokeinterface(enabled_class_index,
	                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
	                        1);
	// ifnonnull
	code.addOpcode(Opcode.IFNONNULL);
	code.addIndex(4);
	// *return // each type
	addTypeDependDataReturn(code, finfo.getDescriptor());
	// *store_1 // each type
	addTypeDependDataStore(code, finfo.getDescriptor(), 1);
	// aload_0
	code.addAload(0);
	// invokeinterface // invoke Enabled.getInterceptFieldCallback()
	code.addInvokeinterface(enabled_class_index,
	                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
	                        1);
	// aload_0
	code.addAload(0);
	// ldc // name of the field
	code.addLdc(finfo.getName());
	// *load_1 // each type
	addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
	// invokeinterface // invoke Callback.read*() // each type
	addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),
	                            true);
	// *return // each type
	addTypeDependDataReturn(code, finfo.getDescriptor());

	minfo.setCodeAttribute(code.toCodeAttribute());
	minfo.setAccessFlags(AccessFlag.PUBLIC);
	classfile.addMethod(minfo);
}
 
Example #16
Source File: FieldTransformer.java    From cacheonix-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
private void addWriteMethod(ClassFile classfile, FieldInfo finfo)
		throws CannotCompileException {
	ConstPool cp = classfile.getConstPool();
	int this_class_index = cp.getThisClassInfo();
	String desc = "(" + finfo.getDescriptor() + ")V";
	MethodInfo minfo = new MethodInfo(cp, EACH_WRITE_METHOD_PREFIX
	                                      + finfo.getName(), desc);
	/* local variables | target obj | each oldvalue | */
	Bytecode code = new Bytecode(cp, 6, 3);
	// aload_0
	code.addAload(0);
	// invokeinterface // enabled.getInterceptFieldCallback()
	int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME);
	code.addInvokeinterface(enabled_class_index,
	                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
	                        1);
	// ifnonnull (label1)
	code.addOpcode(Opcode.IFNONNULL);
	code.addIndex(9);
	// aload_0
	code.addAload(0);
	// *load_1
	addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
	// putfield
	code.addOpcode(Opcode.PUTFIELD);
	int base_field_index = cp.addFieldrefInfo(this_class_index, finfo
			.getName(), finfo.getDescriptor());
	code.addIndex(base_field_index);
	code.growStack(-Descriptor.dataSize(finfo.getDescriptor()));
	// return ;
	code.addOpcode(Opcode.RETURN);
	// aload_0
	code.addAload(0);
	// dup
	code.addOpcode(Opcode.DUP);
	// invokeinterface // enabled.getInterceptFieldCallback()
	code.addInvokeinterface(enabled_class_index,
	                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
	                        1);
	// aload_0
	code.addAload(0);
	// ldc // field name
	code.addLdc(finfo.getName());
	// aload_0
	code.addAload(0);
	// getfield // old value of the field
	code.addOpcode(Opcode.GETFIELD);
	code.addIndex(base_field_index);
	code.growStack(Descriptor.dataSize(finfo.getDescriptor()) - 1);
	// *load_1
	addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
	// invokeinterface // callback.write*(..)
	addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),
	                            false);
	// putfield // new value of the field
	code.addOpcode(Opcode.PUTFIELD);
	code.addIndex(base_field_index);
	code.growStack(-Descriptor.dataSize(finfo.getDescriptor()));
	// return
	code.addOpcode(Opcode.RETURN);

	minfo.setCodeAttribute(code.toCodeAttribute());
	minfo.setAccessFlags(AccessFlag.PUBLIC);
	classfile.addMethod(minfo);
}
 
Example #17
Source File: BulkAccessorFactory.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
private void addGetter(ClassFile classfile, final Method[] getters) throws CannotCompileException {
	final ConstPool constPool = classfile.getConstPool();
	final int targetBeanConstPoolIndex = constPool.addClassInfo( this.targetBean.getName() );
	final String desc = GET_SETTER_DESC;
	final MethodInfo getterMethodInfo = new MethodInfo( constPool, GENERATED_GETTER_NAME, desc );

	final Bytecode code = new Bytecode( constPool, 6, 4 );
	/* | this | bean | args | raw bean | */
	if ( getters.length >= 0 ) {
		// aload_1 // load bean
		code.addAload( 1 );
		// checkcast // cast bean
		code.addCheckcast( this.targetBean.getName() );
		// astore_3 // store bean
		code.addAstore( 3 );
		for ( int i = 0; i < getters.length; ++i ) {
			if ( getters[i] != null ) {
				final Method getter = getters[i];
				// aload_2 // args
				code.addAload( 2 );
				// iconst_i // continue to aastore
				// growing stack is 1
				code.addIconst( i );
				final Class returnType = getter.getReturnType();
				int typeIndex = -1;
				if ( returnType.isPrimitive() ) {
					typeIndex = FactoryHelper.typeIndex( returnType );
					// new
					code.addNew( FactoryHelper.wrapperTypes[typeIndex] );
					// dup
					code.addOpcode( Opcode.DUP );
				}

				// aload_3 // load the raw bean
				code.addAload( 3 );
				final String getterSignature = RuntimeSupport.makeDescriptor( getter );
				final String getterName = getter.getName();
				if ( this.targetBean.isInterface() ) {
					// invokeinterface
					code.addInvokeinterface( targetBeanConstPoolIndex, getterName, getterSignature, 1 );
				}
				else {
					// invokevirtual
					code.addInvokevirtual( targetBeanConstPoolIndex, getterName, getterSignature );
				}

				if ( typeIndex >= 0 ) {
					// is a primitive type
					// invokespecial
					code.addInvokespecial(
							FactoryHelper.wrapperTypes[typeIndex],
							MethodInfo.nameInit,
							FactoryHelper.wrapperDesc[typeIndex]
					);
				}

				// aastore // args
				code.add( Opcode.AASTORE );
				code.growStack( -3 );
			}
		}
	}
	// return
	code.addOpcode( Opcode.RETURN );

	getterMethodInfo.setCodeAttribute( code.toCodeAttribute() );
	getterMethodInfo.setAccessFlags( AccessFlag.PUBLIC );
	classfile.addMethod( getterMethodInfo );
}