Example usage for org.objectweb.asm Opcodes GETSTATIC

List of usage examples for org.objectweb.asm Opcodes GETSTATIC

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes GETSTATIC.

Prototype

int GETSTATIC

To view the source code for org.objectweb.asm Opcodes GETSTATIC.

Click Source Link

Usage

From source file:pl.asie.foamfix.coremod.patches.ReturnIfBooleanTruePatch.java

License:Open Source License

public ReturnIfBooleanTruePatch(String optionName, String... methods) {
    this.optionName = optionName;
    this.methods = ImmutableSet.copyOf(methods);

    list = new InsnList();
    Label l = new Label();
    LabelNode ln = new LabelNode(l);
    list.add(new FieldInsnNode(Opcodes.GETSTATIC, "pl/asie/foamfix/shared/FoamFixShared", "config",
            "Lpl/asie/foamfix/shared/FoamFixConfig;"));
    list.add(new FieldInsnNode(Opcodes.GETFIELD, "pl/asie/foamfix/shared/FoamFixConfig", optionName, "Z"));
    list.add(new JumpInsnNode(Opcodes.IFEQ, ln));
    list.add(new InsnNode(Opcodes.RETURN));
    list.add(ln);//  w  w  w  .  j av  a  2s.c  om
    list.add(new FrameNode(Opcodes.F_SAME, 0, null, 0, null));
}

From source file:pl.clareo.coroutines.core.ClassTransformer.java

License:Apache License

private static InsnList loggingInstructions(String ownerName, String loggerField, Level level,
        Object... messages) {// ww w.  j a  va  2 s . c  o m
    InsnList insn = new InsnList();
    insn.add(new FieldInsnNode(Opcodes.GETSTATIC, ownerName, loggerField, "Ljava/util/logging/Logger;"));
    insn.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/util/logging/Level", level.getName(),
            "Ljava/util/logging/Level;"));
    // stack: * *
    insn.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/logging/Logger", "isLoggable",
            "(Ljava/util/logging/Level;)Z"));
    // stack: *
    LabelNode exitBranch = new LabelNode();
    insn.add(new JumpInsnNode(Opcodes.IFEQ, exitBranch));
    // stack:
    insn.add(new FieldInsnNode(Opcodes.GETSTATIC, ownerName, loggerField, "Ljava/util/logging/Logger;"));
    insn.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/util/logging/Level", level.getName(),
            "Ljava/util/logging/Level;"));
    // stack: * *
    insn.add(new TypeInsnNode(Opcodes.NEW, "java/lang/StringBuilder"));
    insn.add(new InsnNode(Opcodes.DUP));
    // stack: * * * *
    String message0 = messages[0].toString();
    insn.add(new LdcInsnNode(message0));
    // stack: * * * * *
    insn.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>",
            "(Ljava/lang/String;)V"));
    // stack: * * *
    for (int m = 1; m < messages.length; m++) {
        Object message = messages[m];
        if (message instanceof Number) {
            insn.add(new VarInsnNode(Opcodes.ALOAD, ((Number) message).intValue()));
        } else {
            insn.add(new LdcInsnNode(message.toString()));
        }
        // stack: * * * *
        insn.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"));
        // stack: * * *
    }
    insn.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
            "()Ljava/lang/String;"));
    insn.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/logging/Logger", "log",
            "(Ljava/util/logging/Level;Ljava/lang/String;)V"));
    // stack:
    insn.add(exitBranch);
    return insn;
}

From source file:portablejim.veinminer.asm.ItemInWorldManagerTransformer.java

License:Open Source License

private int insertCallAfterTryHarvestBlockFunction(MethodNode curMethod, String obfuscatedClassName,
        int startIndex) throws IndexOutOfBoundsException {
    LocalVariablesSorter varSorter = new LocalVariablesSorter(curMethod.access, curMethod.desc, curMethod);

    String worldType = typemap.get(getCorrectName("theWorld"));
    String playerType = typemap.get(getCorrectName("thisPlayerMP"));

    while (!isMethodWithName(curMethod.instructions.get(startIndex), "tryHarvestBlock")) {
        ++startIndex;/*from  w ww .j a v  a  2s  .co m*/
    }

    do {
        --startIndex;
    } while (curMethod.instructions.get(startIndex).getType() == AbstractInsnNode.VAR_INSN);

    int blockVarIndex = varSorter.newLocal(Type.getType(BlockID.class));
    curMethod.instructions.insert(curMethod.instructions.get(startIndex),
            buildBlockIdFunctionCall(obfuscatedClassName, worldType, blockVarIndex));
    ++startIndex;

    while (!isMethodWithName(curMethod.instructions.get(startIndex), "tryHarvestBlock")) {
        ++startIndex;
    }

    // Add variable to store result
    int newVarIndex = varSorter.newLocal(Type.BOOLEAN_TYPE);
    VarInsnNode newVar = new VarInsnNode(Opcodes.ISTORE, newVarIndex);
    curMethod.instructions.insert(curMethod.instructions.get(startIndex), newVar);
    ++startIndex;

    // Add in function call to call function
    InsnList veinMinerFunctionCall = new InsnList();
    veinMinerFunctionCall
            .add(new FieldInsnNode(Opcodes.GETSTATIC, targetClassName, "instance", targetClassType));
    veinMinerFunctionCall.add(new VarInsnNode(Opcodes.ALOAD, 0));
    veinMinerFunctionCall.add(new FieldInsnNode(Opcodes.GETFIELD, obfuscatedClassName.replace(".", "/"),
            getCorrectName("theWorld"), typemap.get(getCorrectName("theWorld"))));
    veinMinerFunctionCall.add(new VarInsnNode(Opcodes.ALOAD, 0));
    veinMinerFunctionCall.add(new FieldInsnNode(Opcodes.GETFIELD, obfuscatedClassName.replace(".", "/"),
            getCorrectName("thisPlayerMP"), typemap.get(getCorrectName("thisPlayerMP"))));
    veinMinerFunctionCall.add(new VarInsnNode(Opcodes.ILOAD, 1));
    veinMinerFunctionCall.add(new VarInsnNode(Opcodes.ILOAD, 2));
    veinMinerFunctionCall.add(new VarInsnNode(Opcodes.ILOAD, 3));
    veinMinerFunctionCall.add(new VarInsnNode(Opcodes.ILOAD, newVarIndex));
    veinMinerFunctionCall.add(new VarInsnNode(Opcodes.ALOAD, blockVarIndex));

    String blockIdClassType = String.format("L%s;", blockIdClassName);
    veinMinerFunctionCall.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, targetClassName, targetMethodName,
            String.format(targetMethodType, worldType, playerType, blockIdClassType)));
    curMethod.instructions.insert(curMethod.instructions.get(startIndex), veinMinerFunctionCall);
    ++startIndex;

    // Get rid of un-needed POP.
    while (curMethod.instructions.get(startIndex).getOpcode() != Opcodes.POP) {
        ++startIndex;
    }
    curMethod.instructions.remove(curMethod.instructions.get(startIndex));

    return startIndex;
}

From source file:pt.minha.kernel.instrument.SyncToMonitorClassVisitor.java

License:Open Source License

public void makeStub(int access, String name, String desc, String signature, String[] exceptions) {
    Method m = new Method(name, desc);

    MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
    mv.visitCode();// w  w w  .j a  v a  2s  . c o  m

    Label begin = new Label();
    Label pre_invoke = new Label();
    Label pos_leave = new Label();
    Label in_catch = new Label();
    Label pre_rethrow = new Label();
    Label end = new Label();

    mv.visitTryCatchBlock(pre_invoke, pos_leave, in_catch, null);
    mv.visitTryCatchBlock(in_catch, pre_rethrow, in_catch, null);

    mv.visitLabel(begin);

    int offset;
    if ((access & Opcodes.ACC_STATIC) == 0) {
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        offset = 1;
    } else {
        mv.visitFieldInsn(Opcodes.GETSTATIC, clz, "_fake_class",
                "L" + ClassConfig.fake_prefix + "java/lang/Object;");
        offset = 0;
    }

    int length = 0;
    for (Type t : m.getArgumentTypes())
        length += t.getSize();

    mv.visitInsn(Opcodes.DUP);
    mv.visitVarInsn(Opcodes.ASTORE, offset + length);
    mv.visitInsn(Opcodes.MONITORENTER);

    mv.visitLabel(pre_invoke);

    if ((access & Opcodes.ACC_STATIC) == 0)
        mv.visitVarInsn(Opcodes.ALOAD, 0);

    int i = offset;
    for (Type t : m.getArgumentTypes()) {
        // t.getOpcode() should work for long and double too... :-( 
        if (t.getClassName().equals("long"))
            mv.visitVarInsn(Opcodes.LLOAD, i);
        else if (t.getClassName().equals("double"))
            mv.visitVarInsn(Opcodes.DLOAD, i);
        else
            mv.visitVarInsn(t.getOpcode(Opcodes.ILOAD), i);
        i += t.getSize();
    }

    boolean itf = (access & Opcodes.ACC_INTERFACE) != 0;
    if ((access & Opcodes.ACC_STATIC) == 0)
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, clz, "_" + name, desc, itf);
    else
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, clz, "_" + name, desc, itf);

    mv.visitVarInsn(Opcodes.ALOAD, offset + length);
    mv.visitInsn(Opcodes.MONITOREXIT);

    mv.visitLabel(pos_leave);

    if (m.getReturnType().equals(Type.VOID_TYPE))
        mv.visitInsn(Opcodes.RETURN);
    else
        mv.visitInsn(m.getReturnType().getOpcode(Opcodes.IRETURN));

    mv.visitLabel(in_catch);

    mv.visitVarInsn(Opcodes.ALOAD, offset + length);
    mv.visitInsn(Opcodes.MONITOREXIT);

    mv.visitLabel(pre_rethrow);
    mv.visitInsn(Opcodes.ATHROW);

    mv.visitLabel(end);

    i = 0;
    if ((access & Opcodes.ACC_STATIC) == 0)
        mv.visitLocalVariable("this", "L" + clz + ";", null, begin, end, i++);
    for (Type t : m.getArgumentTypes())
        mv.visitLocalVariable("arg" + i, t.getDescriptor(), null, begin, end, i++);

    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:pxb.android.dex2jar.asm.PDescMethodVisitor.java

License:Apache License

public void visitFieldInsn(int opcode, String owner, String name, String desc) {
    super.visitFieldInsn(opcode, owner, name, desc);
    switch (opcode) {
    case Opcodes.GETFIELD:
        e((Type) stack.pop(), Type.getType(owner));
        stack.push(Type.getType(desc));
        break;/*from  ww  w  .  j ava2s.c  o  m*/
    case Opcodes.PUTFIELD:
        e((Type) stack.pop(), Type.getType(desc));
        e((Type) stack.pop(), Type.getType(owner));
        break;
    case Opcodes.GETSTATIC:
        stack.push(Type.getType(desc));
        break;
    case Opcodes.PUTSTATIC:
        e((Type) stack.pop(), Type.getType(desc));
        break;
    }
}

From source file:pxb.android.dex2jar.asm.PMethodVisitor.java

License:Apache License

public void visitFieldInsn(int opcode, String owner, String name, String desc) {
    super.visitFieldInsn(opcode, owner, name, desc);
    switch (opcode) {
    case Opcodes.GETFIELD:
        e((Type) stack.pop(), Type.getObjectType(owner));
        stack.push(Type.getType(desc));
        break;/*from w w w. j  av a  2 s .  co m*/
    case Opcodes.PUTFIELD:
        e((Type) stack.pop(), Type.getType(desc));
        e((Type) stack.pop(), Type.getObjectType(owner));
        break;
    case Opcodes.GETSTATIC:
        stack.push(Type.getType(desc));
        break;
    case Opcodes.PUTSTATIC:
        e((Type) stack.pop(), Type.getType(desc));
        break;
    }
}

From source file:serianalyzer.JVMImpl.java

License:Open Source License

/**
 * @param opcode/*  ww w  . j av a2s  .c om*/
 * @param owner
 * @param name
 * @param desc
 * @param s
 */
static void handleFieldInsn(int opcode, String owner, String name, String desc, JVMStackState s) {
    switch (opcode) {
    case Opcodes.GETFIELD:
        Object tgt = s.pop();
        if (log.isTraceEnabled()) {
            log.trace("From " + tgt); //$NON-NLS-1$
        }
    case Opcodes.GETSTATIC:
        // this can be more specific
        if (log.isTraceEnabled()) {
            log.trace("Load field " + name + " (" + desc + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }
        s.push(new FieldReference(DotName.createSimple(owner.replace('/', '.')), name, Type.getType(desc),
                true));
        break;
    case Opcodes.PUTFIELD:
        s.pop();
        s.pop();
        break;
    case Opcodes.PUTSTATIC:
        s.pop();
        break;
    default:
        log.warn("Unsupported opcode " + opcode); //$NON-NLS-1$
    }
}

From source file:serianalyzer.SerianalyzerMethodVisitor.java

License:Open Source License

/**
 * {@inheritDoc}//from w ww  .j  a v  a2s.  co  m
 *
 * @see org.objectweb.asm.MethodVisitor#visitFieldInsn(int, java.lang.String, java.lang.String, java.lang.String)
 */
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
    JVMStackState s = this.stack;
    if (opcode == Opcodes.PUTSTATIC) {
        Object v = s.pop();

        if (!(v instanceof BaseType) || ((BaseType) v).isTainted()) {

            // generated static cached, let's assume they are safe
            if (name.indexOf('$') < 0 && this.ref.getMethod().indexOf('$') < 0) {
                this.parent.getAnalyzer().putstatic(this.ref);
            }
        }
    } else {
        JVMImpl.handleFieldInsn(opcode, owner, name, desc, s);
    }

    if ((opcode == Opcodes.GETSTATIC || opcode == Opcodes.GETFIELD) && name.indexOf('$') < 0) {
        this.parent.getAnalyzer().instantiable(this.ref, Type.getType(desc));
    }

    super.visitFieldInsn(opcode, owner, name, desc);
}

From source file:sg.atom.core.actor.internal.codegenerator.ActorProxyCreator.java

License:Apache License

/**
 * Writes a proxy method for messages.//from   www  .  j  av a 2  s . c  o  m
 *
 * @param classNameInternal the internal class name
 * @param classNameDescriptor the class name descriptor
 * @param cw the ClassWriter
 * @param index the message index
 * @param type the ActorState type to use
 * @param concurrencyModel the concurrency model of the message
 * @param messageDescriptor the message's descriptor
 * @param method the method to override
 * @param simpleDescriptor a simple descriptor of the message
 * @param genericSignature the signature of the message
 */
private static void writeProxyMethod(String classNameInternal, String classNameDescriptor, ClassWriter cw,
        int index, Type actorState, ConcurrencyModel concurrencyModel, MessageImplDescriptor messageDescriptor,
        Method method, String simpleDescriptor, String genericSignature) throws NoSuchMethodException {
    MethodVisitor mv;
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), simpleDescriptor, genericSignature, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitIntInsn(Opcodes.BIPUSH, method.getParameterTypes().length);
        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
        for (int j = 0; j < method.getParameterTypes().length; j++) {
            mv.visitInsn(Opcodes.DUP);
            mv.visitIntInsn(Opcodes.BIPUSH, j);
            Class<?> paraType = method.getParameterTypes()[j];
            if (paraType.isPrimitive()) {
                String wrapperClass = GenerationUtils.getWrapperInternalName(paraType);
                Type primType = Type.getType(paraType);
                mv.visitVarInsn(primType.getOpcode(Opcodes.ILOAD), j + 1);
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, wrapperClass, "valueOf",
                        "(" + primType.getDescriptor() + ")" + "L" + wrapperClass + ";");
            } else if (isArgumentFreezingRequired(method, j, paraType)) {
                mv.visitVarInsn(Opcodes.ALOAD, j + 1);
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(SerializableFreezer.class),
                        "freeze",
                        Type.getMethodDescriptor(SerializableFreezer.class.getMethod("freeze", Object.class)));
            } else if (paraType.isInterface()) {
                mv.visitVarInsn(Opcodes.ALOAD, j + 1);
                mv.visitInsn(Opcodes.DUP);
                mv.visitTypeInsn(Opcodes.INSTANCEOF, "org/actorsguildframework/Actor");
                Label lEndif = new Label();
                mv.visitJumpInsn(Opcodes.IFNE, lEndif);
                mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ActorRuntimeException.class));
                mv.visitInsn(Opcodes.DUP);
                mv.visitLdcInsn(String.format(
                        "Argument %d is an non-Serializable interface, but you did not give an Actor. If a message's argument type is an interface that does not extend Serializable, only Actors are acceptable as argument.",
                        j));
                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ActorRuntimeException.class),
                        "<init>", "(Ljava/lang/String;)V");
                mv.visitInsn(Opcodes.ATHROW);
                mv.visitLabel(lEndif);
            } else {
                mv.visitVarInsn(Opcodes.ALOAD, j + 1);
            }

            mv.visitInsn(Opcodes.AASTORE);
        }
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitVarInsn(Opcodes.ASTORE, method.getParameterTypes().length + 1); // method.getParameterTypes().length+1 ==> 'args' local variable
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, classNameInternal, "actorState__ACTORPROXY",
                actorState.getDescriptor());
        mv.visitFieldInsn(Opcodes.GETSTATIC, classNameInternal,
                String.format(MESSAGE_CALLER_NAME_FORMAT, index),
                "Lorg/actorsguildframework/internal/MessageCaller;");
        mv.visitFieldInsn(Opcodes.GETSTATIC, "org/actorsguildframework/annotations/ThreadUsage",
                messageDescriptor.getThreadUsage().name(),
                "Lorg/actorsguildframework/annotations/ThreadUsage;");
        mv.visitVarInsn(Opcodes.ALOAD, method.getParameterTypes().length + 1);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, actorState.getInternalName(), "queueMessage",
                "(Lorg/actorsguildframework/internal/MessageCaller;Lorg/actorsguildframework/annotations/ThreadUsage;[Ljava/lang/Object;)Lorg/actorsguildframework/internal/AsyncResultImpl;");
        mv.visitInsn(Opcodes.ARETURN);
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitLocalVariable("this", classNameDescriptor, null, l0, l4, 0);
        for (int j = 0; j < method.getParameterTypes().length; j++) {
            mv.visitLocalVariable("arg" + j, Type.getDescriptor(method.getParameterTypes()[j]),
                    GenericTypeHelper.getSignatureIfGeneric(method.getGenericParameterTypes()[j]), l0, l4,
                    j + 1);
        }
        mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l1, l4,
                method.getParameterTypes().length + 1);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}

From source file:sg.atom.core.actor.internal.codegenerator.BeanCreator.java

License:Apache License

/**
 * Writes the bean constructor to the given ClassWriter.
 *
 * @param beanClass the original bean class to extend
 * @param bcd the descriptor of the bean
 * @param classNameInternal the internal name of the new class
 * @param cw the ClassWriter to write to
 * @param snippetWriter if not null, this will be invoked to add a snippet
 * after the invocation of the super constructor
 *//* w w  w  .ja  va  2 s .co m*/
public static void writeConstructor(Class<?> beanClass, BeanClassDescriptor bcd, String classNameInternal,
        ClassWriter cw, SnippetWriter snippetWriter) {
    String classNameDescriptor = "L" + classNameInternal + ";";

    int localPropertySize = 0;
    ArrayList<PropertyDescriptor> localVarProperties = new ArrayList<PropertyDescriptor>();
    for (int i = 0; i < bcd.getPropertyCount(); i++) {
        PropertyDescriptor pd = bcd.getProperty(i);
        if (pd.getPropertySource().isGenerating() || (pd.getDefaultValue() != null)) {
            localVarProperties.add(pd);
            localPropertySize += Type.getType(pd.getPropertyClass()).getSize();
        }
    }

    final int locVarThis = 0;
    final int locVarController = 1;
    final int locVarProps = 2;
    final int locVarPropertiesOffset = 3;
    final int locVarP = 3 + localPropertySize;
    final int locVarK = 4 + localPropertySize;
    final int locVarV = 5 + localPropertySize;

    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
            "(Lorg/actorsguildframework/internal/Controller;Lorg/actorsguildframework/Props;)V", null, null);
    mv.visitCode();
    Label lTry = new Label();
    Label lCatch = new Label();
    mv.visitTryCatchBlock(lTry, lCatch, lCatch, "java/lang/ClassCastException");

    Label lBegin = new Label();
    mv.visitLabel(lBegin);
    mv.visitVarInsn(Opcodes.ALOAD, locVarThis);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(beanClass), "<init>", "()V");

    if (snippetWriter != null) {
        snippetWriter.write(mv);
    }

    Label lPropertyInit = new Label();
    mv.visitLabel(lPropertyInit);
    // load default values into the local variables for each property that must be set
    int varCount = 0;
    for (PropertyDescriptor pd : localVarProperties) {
        Type pt = Type.getType(pd.getPropertyClass());
        if (pd.getDefaultValue() != null) {
            mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(pd.getDefaultValue().getDeclaringClass()),
                    pd.getDefaultValue().getName(), Type.getDescriptor(pd.getDefaultValue().getType()));
        } else {
            GenerationUtils.generateLoadDefault(mv, pd.getPropertyClass());
        }
        mv.visitVarInsn(pt.getOpcode(Opcodes.ISTORE), locVarPropertiesOffset + varCount);
        varCount += pt.getSize();
    }

    // loop through the props argument's list
    mv.visitVarInsn(Opcodes.ALOAD, locVarProps);
    mv.visitVarInsn(Opcodes.ASTORE, locVarP);
    Label lWhile = new Label();
    Label lEndWhile = new Label();
    Label lWhileBody = new Label();
    mv.visitLabel(lWhile);
    mv.visitJumpInsn(Opcodes.GOTO, lEndWhile);
    mv.visitLabel(lWhileBody);

    mv.visitVarInsn(Opcodes.ALOAD, locVarP);
    mv.visitInsn(Opcodes.DUP);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/actorsguildframework/Props", "getKey",
            "()Ljava/lang/String;");
    mv.visitVarInsn(Opcodes.ASTORE, locVarK);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/actorsguildframework/Props", "getValue",
            "()Ljava/lang/Object;");
    mv.visitVarInsn(Opcodes.ASTORE, locVarV);

    mv.visitLabel(lTry);
    // write an if for each property
    Label lEndIf = new Label();
    varCount = 0;
    int ifCount = 0;
    for (int i = 0; i < bcd.getPropertyCount(); i++) {
        PropertyDescriptor pd = bcd.getProperty(i);
        boolean usesLocal = pd.getPropertySource().isGenerating() || (pd.getDefaultValue() != null);
        Class<?> propClass = pd.getPropertyClass();
        Type pt = Type.getType(propClass);
        mv.visitVarInsn(Opcodes.ALOAD, locVarK);
        mv.visitLdcInsn(pd.getName());
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
        Label lElse = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, lElse);

        if (!usesLocal) {
            mv.visitVarInsn(Opcodes.ALOAD, locVarThis); // for setter invocation, load 'this'
        }
        if (propClass.isPrimitive()) {
            mv.visitLdcInsn(pd.getName());
            mv.visitVarInsn(Opcodes.ALOAD, locVarV);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(BeanHelper.class),
                    String.format("get%s%sFromPropValue",
                            propClass.getName().substring(0, 1).toUpperCase(Locale.US),
                            propClass.getName().substring(1)),
                    "(Ljava/lang/String;Ljava/lang/Object;)" + pt.getDescriptor());
        } else if (!propClass.equals(Object.class)) {
            mv.visitVarInsn(Opcodes.ALOAD, locVarV);
            mv.visitTypeInsn(Opcodes.CHECKCAST, pt.getInternalName());
        } else {
            mv.visitVarInsn(Opcodes.ALOAD, locVarV);
        }

        if (!usesLocal) {
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classNameInternal, pd.getSetter().getName(),
                    Type.getMethodDescriptor(pd.getSetter()));
        } else {
            mv.visitVarInsn(pt.getOpcode(Opcodes.ISTORE), varCount + locVarPropertiesOffset);
        }

        mv.visitJumpInsn(Opcodes.GOTO, lEndIf);
        mv.visitLabel(lElse);

        ifCount++;
        if (usesLocal) {
            varCount += pt.getSize();
        }
    }

    // else (==> if not prop matched) throw IllegalArgumentException
    mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(IllegalArgumentException.class));
    mv.visitInsn(Opcodes.DUP);
    mv.visitLdcInsn("Unknown property \"%s\".");
    mv.visitInsn(Opcodes.ICONST_1);
    mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
    mv.visitInsn(Opcodes.DUP);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitVarInsn(Opcodes.ALOAD, locVarK);
    mv.visitInsn(Opcodes.AASTORE);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "format",
            "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;");
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(IllegalArgumentException.class), "<init>",
            "(Ljava/lang/String;)V");
    mv.visitInsn(Opcodes.ATHROW);

    mv.visitLabel(lCatch);
    mv.visitInsn(Opcodes.POP); // pop the exception object (not needed)
    mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(IllegalArgumentException.class));
    mv.visitInsn(Opcodes.DUP);
    mv.visitLdcInsn("Incompatible type for property \"%s\". Got %s.");
    mv.visitInsn(Opcodes.ICONST_2);
    mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
    mv.visitInsn(Opcodes.DUP);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitVarInsn(Opcodes.ALOAD, locVarK);
    mv.visitInsn(Opcodes.AASTORE);
    mv.visitInsn(Opcodes.DUP);
    mv.visitInsn(Opcodes.ICONST_1);
    mv.visitVarInsn(Opcodes.ALOAD, locVarV);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
    mv.visitInsn(Opcodes.AASTORE);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "format",
            "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;");
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(IllegalArgumentException.class), "<init>",
            "(Ljava/lang/String;)V");
    mv.visitInsn(Opcodes.ATHROW);

    mv.visitLabel(lEndIf);
    mv.visitVarInsn(Opcodes.ALOAD, locVarP);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/actorsguildframework/Props", "tail",
            "()Lorg/actorsguildframework/Props;");
    mv.visitVarInsn(Opcodes.ASTORE, locVarP);

    mv.visitLabel(lEndWhile);
    mv.visitVarInsn(Opcodes.ALOAD, locVarP);
    mv.visitJumpInsn(Opcodes.IFNONNULL, lWhileBody);

    // write local variables back into properties 
    varCount = 0;
    for (PropertyDescriptor pd : localVarProperties) {
        Type pt = Type.getType(pd.getPropertyClass());
        mv.visitVarInsn(Opcodes.ALOAD, locVarThis);
        if (pd.getPropertySource() == PropertySource.ABSTRACT_METHOD) {
            mv.visitVarInsn(pt.getOpcode(Opcodes.ILOAD), locVarPropertiesOffset + varCount);
            mv.visitFieldInsn(Opcodes.PUTFIELD, classNameInternal,
                    String.format(PROP_FIELD_NAME_TEMPLATE, pd.getName()), pt.getDescriptor());
        } else if (pd.getPropertySource() == PropertySource.USER_WRITTEN) {
            mv.visitVarInsn(pt.getOpcode(Opcodes.ILOAD), locVarPropertiesOffset + varCount);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classNameInternal, pd.getSetter().getName(),
                    Type.getMethodDescriptor(pd.getSetter()));
        } else {
            throw new RuntimeException("Internal error");
        }
        varCount += pt.getSize();
    }

    // if bean is thread-safe, publish all writes now
    if (bcd.isThreadSafe()) {
        mv.visitVarInsn(Opcodes.ALOAD, locVarThis);
        mv.visitInsn(Opcodes.DUP);
        mv.visitInsn(Opcodes.MONITORENTER);
        mv.visitInsn(Opcodes.MONITOREXIT);
    }

    mv.visitInsn(Opcodes.RETURN);
    Label lEnd = new Label();
    mv.visitLabel(lEnd);

    mv.visitLocalVariable("this", classNameDescriptor, null, lBegin, lEnd, locVarThis);
    mv.visitLocalVariable("controller", "Lorg/actorsguildframework/internal/Controller;", null, lBegin, lEnd,
            locVarController);
    mv.visitLocalVariable("props", "Lorg/actorsguildframework/Props;", null, lBegin, lEnd, locVarProps);
    varCount = 0;
    for (PropertyDescriptor pd : localVarProperties) {
        Type pt = Type.getType(pd.getPropertyClass());
        mv.visitLocalVariable("__" + pd.getName(), pt.getDescriptor(),
                GenericTypeHelper.getSignature(pd.getPropertyType()), lPropertyInit, lEnd,
                locVarPropertiesOffset + varCount);
        varCount += pt.getSize();
    }
    mv.visitLocalVariable("p", "Lorg/actorsguildframework/Props;", null, lPropertyInit, lEnd, locVarP);
    mv.visitLocalVariable("k", "Ljava/lang/String;", null, lWhile, lEndWhile, locVarK);
    mv.visitLocalVariable("v", "Ljava/lang/Object;", null, lWhile, lEndWhile, locVarV);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}