Example usage for org.objectweb.asm MethodVisitor visitLdcInsn

List of usage examples for org.objectweb.asm MethodVisitor visitLdcInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitLdcInsn.

Prototype

public void visitLdcInsn(final Object value) 

Source Link

Document

Visits a LDC instruction.

Usage

From source file:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate code to convert ldapAttribute witch is on the to of the stack to
 * Boolean/*w w w .  j av  a2  s  .  c o m*/
 * 
 * @param p_MethodVisitor
 *            The {@link MethodVisitor} of the generated method
 * @param p_ClassName
 *            Name of the generated class
 * @param p_LdapAttribute
 *            The LdapAttribute that will be used for generating the method
 * @param p_ReturnType
 *            The type of the result
 * @param p_Object
 *            Index of the object to convert on the stack
 * @param p_Result
 *            Index of the converted object on the stack
 */
private void generateConvertToBoolean(MethodVisitor p_MethodVisitor, String p_ClassName,
        LdapAttribute p_LdapAttribute, Class<?> p_ReturnType, int p_Object, int p_Result) {
    MethodVisitor mv = p_MethodVisitor;
    Label l0 = new Label();
    // return true or false instead of result
    generateConvertToBoolean(mv, p_ReturnType, p_LdapAttribute.trueValue(), true, p_Object, p_Result, l0);
    generateConvertToBoolean(mv, p_ReturnType, p_LdapAttribute.falseValue(), false, p_Object, p_Result, l0);
    // Can't convert attribute to boolean
    // throw new IllegalArgumentException(object +
    // " cannot be converted into boolean");
    mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
    mv.visitInsn(DUP);
    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
    mv.visitVarInsn(ALOAD, p_Object);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
            "(Ljava/lang/Object;)Ljava/lang/StringBuilder;");
    mv.visitLdcInsn(" cannot be converted into boolean");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
            "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V");
    mv.visitInsn(ATHROW);
    mv.visitLabel(l0);
}

From source file:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate code to convert ldapAttribute witch is on the to of the stack to
 * Boolean//from  w ww.  j  a va  2s.  c o  m
 * 
 * @param p_MethodVisitor
 *            The {@link MethodVisitor} of the generated method
 * @param p_ReturnType
 *            The type of the result
 * @param p_BValues
 *            Possible values for the attribute
 * @param p_BValue
 *            Boolean value
 * @param p_Object
 *            Index of the object to convert on the stack
 * @param p_Result
 *            Index of the converted object on the stack
 * @param p_End
 *            Destination if the conversion success
 */
private void generateConvertToBoolean(MethodVisitor p_MethodVisitor, Class<?> p_ReturnType, String[] p_BValues,
        boolean p_BValue, int p_Object, int p_Result, Label p_End) {
    MethodVisitor mv = p_MethodVisitor;
    {
        // if(trueValue.equals(result))
        Label l0 = new Label();
        for (String bValue : p_BValues) {
            mv.visitLdcInsn(bValue);
            mv.visitVarInsn(ALOAD, p_Object);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equalsIgnoreCase", "(Ljava/lang/String;)Z");
            mv.visitJumpInsn(IFNE, l0);
        }
        Label l1 = new Label();
        mv.visitJumpInsn(GOTO, l1);
        // {
        mv.visitLabel(l0);
        if (boolean.class.equals(p_ReturnType)) {
            // return true|false;
            mv.visitInsn(p_BValue ? ICONST_1 : ICONST_0);
            mv.visitVarInsn(ISTORE, p_Result);
        } else {
            // return Boolean.TRUE|Boolean.FALSE;
            mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", p_BValue ? "TRUE" : "FALSE",
                    "Ljava/lang/Boolean;");
            mv.visitVarInsn(ASTORE, p_Result);
        }
        mv.visitJumpInsn(GOTO, p_End);
        // }
        mv.visitLabel(l1);
    }
}

From source file:lombok.patcher.scripts.SetSymbolDuringMethodCallScript.java

License:Open Source License

private void makeWrapperMethod(ClassVisitor cv, WrapperMethodDescriptor wmd) {
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC,
            wmd.getWrapperName(), wmd.getWrapperDescriptor(), null, null);

    MethodLogistics logistics = new MethodLogistics(Opcodes.ACC_STATIC, wmd.getWrapperDescriptor());

    mv.visitCode();/*from   w  ww.j ava  2 s  . c o m*/
    Label start = new Label();
    Label end = new Label();
    Label handler = new Label();
    mv.visitTryCatchBlock(start, end, handler, null);
    mv.visitLabel(start);
    mv.visitLdcInsn(symbol);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "lombok/patcher/Symbols", "push", "(Ljava/lang/String;)V", false);
    for (int i = 0; i < logistics.getParamCount(); i++) {
        logistics.generateLoadOpcodeForParam(i, mv);
    }
    mv.visitMethodInsn(wmd.getOpcode(), wmd.getOwner(), wmd.getName(), wmd.getTargetDescriptor(), wmd.isItf());
    mv.visitLabel(end);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "lombok/patcher/Symbols", "pop", "()V", false);
    logistics.generateReturnOpcode(mv);
    mv.visitLabel(handler);
    mv.visitFrame(Opcodes.F_FULL, 0, null, 1, new Object[] { "java/lang/Throwable" });
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "lombok/patcher/Symbols", "pop", "()V", false);
    mv.visitInsn(Opcodes.ATHROW);
    mv.visitMaxs(Math.max(1, logistics.getParamCount()), logistics.getParamCount());
    mv.visitEnd();
}

From source file:lucee.transformer.bytecode.Page.java

License:Open Source License

public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {

    if (!name.equals("getSourceLastModified"))
        return super.visitMethod(access, name, desc, signature, exceptions);

    MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
    mv.visitCode();/*  ww w. j a  v a  2  s  . c om*/
    mv.visitLdcInsn(Long.valueOf(lastModified));
    mv.visitInsn(Opcodes.LRETURN);
    mv.visitEnd();
    return mv;
}

From source file:lucee.transformer.bytecode.util.MethodCleaner.java

License:Open Source License

private void exception(MethodVisitor mv) {
    mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
    mv.visitInsn(DUP);/*  w w w  .  ja  v  a  2s .  c  om*/
    mv.visitLdcInsn(msg);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V");
    mv.visitInsn(ATHROW);
    mv.visitMaxs(3, 1);
}

From source file:me.rojo8399.placeholderapi.impl.placeholder.gen.ClassPlaceholderFactory.java

License:Open Source License

private static void utilsTryCast(MethodVisitor mv, Class<?> expected, boolean orNull) {
    // assume obj to cast is already on stack and only that obj is on stack
    mv.visitLdcInsn(Type.getType(expected));
    mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;");
    mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(TypeUtils.class), "tryCast",
            "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Boolean;)Ljava/util/Optional;", false);
    if (orNull) {
        mv.visitInsn(ACONST_NULL);//from   w w  w  . j a v a 2 s  . com
        mv.visitMethodInsn(INVOKEVIRTUAL, OPT_NAME, "orElse", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
    }
}

From source file:me.rojo8399.placeholderapi.impl.placeholder.gen.ClassPlaceholderFactory.java

License:Open Source License

private byte[] generateClass(String name, Class<?> handle, Method method) {
    name = name.replace(".", "/");
    final String handleName = Type.getInternalName(handle);
    final String handleDescriptor = Type.getDescriptor(handle);
    List<Parameter> pm = Arrays.asList(method.getParameters());
    boolean token = pm.stream().anyMatch(p -> p.isAnnotationPresent(Token.class));
    final boolean source = pm.stream().anyMatch(p -> p.isAnnotationPresent(Source.class));
    final boolean observer = pm.stream().anyMatch(p -> p.isAnnotationPresent(Observer.class));
    final boolean srcNullable = pm.stream().filter(p -> p.isAnnotationPresent(Source.class))
            .anyMatch(p -> p.isAnnotationPresent(Nullable.class));
    final boolean optionalTokenType = token && pm.stream().anyMatch(p -> p.getType().equals(Optional.class));
    final Optional<Class<?>> tokenClass = token
            ? pm.stream().filter(p -> p.isAnnotationPresent(Token.class)).findAny().map(pr -> {
                if (optionalTokenType) {
                    return (Class<?>) ((ParameterizedType) pr.getParameterizedType())
                            .getActualTypeArguments()[0];
                } else {
                    return pr.getType();
                }//  w  w w.  j av a  2s. c  o m
            })
            : Optional.empty();
    token = token && tokenClass.isPresent();
    final boolean obsNullable = pm.stream().filter(p -> p.isAnnotationPresent(Observer.class))
            .anyMatch(p -> p.isAnnotationPresent(Nullable.class));
    final boolean tokNullable = token && !optionalTokenType
            && pm.stream().filter(p -> p.isAnnotationPresent(Token.class))
                    .anyMatch(p -> p.isAnnotationPresent(Nullable.class));
    final boolean fixToken = token && pm.stream().filter(p -> p.isAnnotationPresent(Token.class))
            .map(p -> p.getAnnotation(Token.class)).anyMatch(Token::fix);
    final Optional<Class<?>> sourceType = pm.stream().filter(p -> p.isAnnotationPresent(Source.class))
            .findFirst().map(Parameter::getType);
    final Optional<Class<?>> observerType = pm.stream().filter(p -> p.isAnnotationPresent(Observer.class))
            .findFirst().map(Parameter::getType);
    Class<?> returnType = method.getReturnType();
    if (returnType.equals(Void.TYPE)) {
        returnType = Object.class;
    }
    String retString = Type.getDescriptor(returnType);
    String parseMethodDescriptor = "(L" + Type.getInternalName(sourceType.orElse(Locatable.class)) + ";L"
            + Type.getInternalName(observerType.orElse(Locatable.class)) + ";L" + OPT_NAME + ";)" + retString;
    String externalParseDescriptor = "(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/Optional;)Ljava/lang/Object;";
    String methodDescriptor = Type.getMethodDescriptor(method);
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    MethodVisitor mv;
    cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, name, null, PLACEHOLDER_NAME, null);
    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", '(' + handleDescriptor + ")V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitLdcInsn(method.getAnnotation(Placeholder.class).id());
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESPECIAL, PLACEHOLDER_NAME, "<init>",
                "(L" + STRING_NAME + ";L" + OBJECT_NAME + ";)V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "parse", parseMethodDescriptor, null,
                new String[] { "java/lang/Exception" });
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, name, "handle", "L" + OBJECT_NAME + ";");
        mv.visitTypeInsn(CHECKCAST, handleName);
        if (token) {
            if (!String.class.isAssignableFrom(tokenClass.get()) || (tokenClass.get().isArray()
                    && String.class.isAssignableFrom(tokenClass.get().getComponentType()))) {
                mv.visitVarInsn(ALOAD, 3);
                mv.visitInsn(ACONST_NULL);
                mv.visitMethodInsn(INVOKEVIRTUAL, OPT_NAME, "orElse", "(Ljava/lang/Object;)Ljava/lang/Object;",
                        false);
                if (optionalTokenType) {
                    utilsTryCast(mv, boxedPrim(tokenClass.get()), false);
                    mv.visitVarInsn(ASTORE, 3);
                } else {
                    mv.visitVarInsn(ASTORE, 4);
                    mv.visitVarInsn(ALOAD, 4);
                    skipIfNull(mv, mv2 -> {
                        mv2.visitVarInsn(ALOAD, 4);
                        utilsTryCast(mv2, boxedPrim(tokenClass.get()), true);
                        mv2.visitVarInsn(ASTORE, 4);
                    });
                }
            } else {
                if (!optionalTokenType) {
                    mv.visitVarInsn(ALOAD, 3);
                    mv.visitInsn(ACONST_NULL);
                    mv.visitMethodInsn(INVOKEVIRTUAL, OPT_NAME, "orElse",
                            "(Ljava/lang/Object;)Ljava/lang/Object;", false);
                    mv.visitVarInsn(ASTORE, 4);
                    if (fixToken) {
                        mv.visitVarInsn(ALOAD, 4);
                        skipIfNull(mv, mv2 -> {
                            mv2.visitVarInsn(ALOAD, 4);
                            mv2.visitTypeInsn(CHECKCAST, STRING_NAME);
                            mv2.visitMethodInsn(INVOKEVIRTUAL, STRING_NAME, "toLowerCase", TLC_SIG, false);
                            mv2.visitMethodInsn(INVOKEVIRTUAL, STRING_NAME, "trim", TRIM_SIG, false);
                            mv2.visitVarInsn(ASTORE, 4);
                        });
                    }
                }
            }
        }
        for (int i = 0; i < method.getParameterCount(); i++) {
            int x;
            Parameter p = method.getParameters()[i];
            x = getOrder(p);
            if (x == 2 && !optionalTokenType) {
                x = 3;
            }
            mv.visitVarInsn(ALOAD, x + 1);
            boolean nullable = false;
            switch (x) {
            case 0:
                nullable = srcNullable;
                break;
            case 1:
                nullable = obsNullable;
                break;
            case 3:
                nullable = tokNullable;
                break;
            }
            final int x1 = x;
            nullCheck(mv, nullable, mv2 -> mv2.visitVarInsn(ALOAD, x1 + 1), x == 3 && token);
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(boxedPrim(p.getType())));
            boxToPrim(mv, p.getType(), x1 + 1);
        }
        mv.visitMethodInsn(INVOKEVIRTUAL, handleName, method.getName(), methodDescriptor, false);
        if (method.getReturnType().equals(Void.TYPE)) {
            mv.visitLdcInsn("");
        }
        if (!retString.startsWith("L")) {
            returnInsn(mv, returnType);
        } else {
            mv.visitInsn(ARETURN);
        }
        mv.visitMaxs(10, 10);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "parse", externalParseDescriptor, null,
                new String[] { "java/lang/Exception" });
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        if (sourceType.isPresent() && source) {
            mv.visitVarInsn(ALOAD, 1);
            tryCatch(mv, mv2 -> mv2.visitTypeInsn(CHECKCAST, Type.getInternalName(sourceType.get())), mv2 -> {
                mv2.visitLdcInsn("");
                mv2.visitInsn(ARETURN);
            });
        } else {
            mv.visitInsn(ACONST_NULL);
        }
        if (observerType.isPresent() && observer) {
            mv.visitVarInsn(ALOAD, 2);
            tryCatch(mv, mv2 -> mv2.visitTypeInsn(CHECKCAST, Type.getInternalName(observerType.get())), mv2 -> {
                mv2.visitLdcInsn("");
                mv2.visitInsn(ARETURN);
            });
        } else {
            mv.visitInsn(ACONST_NULL);
        }
        mv.visitVarInsn(ALOAD, 3);
        mv.visitMethodInsn(INVOKEVIRTUAL, name, "parse", parseMethodDescriptor, false);
        unboxFromPrim(mv, returnType);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
    cw.visitEnd();
    return cw.toByteArray();
}

From source file:me.themallard.bitmmo.impl.plugin.chathook.ChatHook.java

License:Open Source License

private void createSendMessage(ClassNode cn) {
    Pattern p = new PatternBuilder().add(new InstructionElement(INVOKESTATIC), new AnyElement(),
            new LdcElement(new LdcInsnNode("Chat")), new InstructionElement(INVOKEVIRTUAL)).build();

    MethodInsnNode newBuilder = null;/*w  w  w  . ja  va  2  s .  c o m*/
    MethodInsnNode setChatText = null;
    MethodInsnNode ebola1 = null;
    MethodInsnNode ebola2 = null;
    MethodInsnNode ebola3 = null;
    MethodInsnNode ebola4 = null;
    MethodInsnNode ebola5 = null;
    MethodInsnNode ebola6 = null;
    MethodInsnNode ebola7 = null;

    for (MethodNode mn : cn.methods) {
        if (!p.contains(mn.instructions))
            continue;

        int offset = p.getOffset(mn.instructions);

        newBuilder = (MethodInsnNode) mn.instructions.get(offset - 9); // newbuilder
        // then var insn of parameter, ldc or w/e
        setChatText = (MethodInsnNode) mn.instructions.get(offset - 7); // setchattext
        ebola1 = (MethodInsnNode) mn.instructions.get(offset - 6); // U a
        ebola2 = (MethodInsnNode) mn.instructions.get(offset - 5); // U p
        ebola3 = (MethodInsnNode) mn.instructions.get(offset - 4); // Player
        // r
        ebola4 = (MethodInsnNode) mn.instructions.get(offset - 3); // setMapID
        ebola5 = (MethodInsnNode) mn.instructions.get(offset - 2); // build
        // store that crap
        ebola6 = (MethodInsnNode) mn.instructions.get(offset); // i e
        // load crap again
        // LDC "Chat"
        ebola7 = (MethodInsnNode) mn.instructions.get(offset + 3); // i a
    }

    {
        MethodVisitor mv = cn.visitMethod(ACC_PUBLIC, "sendChatMessage", "(Ljava/lang/String;)V", null, null);
        mv.visitMethodInsn(INVOKESTATIC, newBuilder.owner, newBuilder.name, newBuilder.desc, newBuilder.itf);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKEVIRTUAL, setChatText.owner, setChatText.name, setChatText.desc,
                setChatText.itf);
        mv.visitMethodInsn(INVOKESTATIC, ebola1.owner, ebola1.name, ebola1.desc, ebola1.itf);
        mv.visitMethodInsn(INVOKEVIRTUAL, ebola2.owner, ebola2.name, ebola2.desc, ebola2.itf);
        mv.visitMethodInsn(INVOKEVIRTUAL, ebola3.owner, ebola3.name, ebola3.desc, ebola3.itf);
        mv.visitMethodInsn(INVOKEVIRTUAL, ebola4.owner, ebola4.name, ebola4.desc, ebola4.itf);
        mv.visitMethodInsn(INVOKEVIRTUAL, ebola5.owner, ebola5.name, ebola5.desc, ebola5.itf);
        mv.visitVarInsn(ASTORE, 2);
        mv.visitMethodInsn(INVOKESTATIC, ebola6.owner, ebola6.name, ebola6.desc, ebola6.itf);
        mv.visitVarInsn(ALOAD, 2);
        mv.visitLdcInsn("Chat");
        mv.visitMethodInsn(INVOKEVIRTUAL, ebola7.owner, ebola7.name, ebola7.desc, ebola7.itf);
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }
}

From source file:me.themallard.bitmmo.impl.plugin.chathook.ChatHook.java

License:Open Source License

private void createAddMessage(ClassNode cn) {
    Pattern p = new PatternBuilder().add(new InstructionElement(ALOAD), new LdcElement(new LdcInsnNode("")),
            new InstructionElement(ALOAD), new InstructionElement(INVOKEVIRTUAL)).build();

    MethodInsnNode ebola1 = null;/*  www .j av a  2  s. co m*/

    for (MethodNode mn : cn.methods) {
        if (!p.contains(mn.instructions))
            continue;

        int offset = p.getOffset(mn.instructions);

        ebola1 = (MethodInsnNode) mn.instructions.get(offset + 3);
    }

    {
        MethodVisitor mv = cn.visitMethod(ACC_PUBLIC, "addChatMessage", "(Ljava/lang/String;)V", null, null);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitLdcInsn("");
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKEVIRTUAL, ebola1.owner, ebola1.name, ebola1.desc, ebola1.itf);
        mv.visitInsn(RETURN);
        mv.visitEnd();
    }
}

From source file:mt.swift.Deserializer.java

License:Apache License

private void compileDeserializeMethod(StructureType type, ClassVisitor writer, String targetClassName,
        Class targetClass) {/*from ww w.  j  ava2 s. co m*/
    MethodVisitor methodVisitor = writer.visitMethod(
            ACC_PUBLIC, "deserialize", "(L" + Util.getInternalName(Deserializer.class)
                    + ";Lcom/facebook/thrift/protocol/TProtocol;)L" + targetClassName + ";",
            null, new String[] { "com/facebook/thrift/TException" });

    FrameRegisterManager context = new FrameRegisterManager();
    context.bindSlot("this", 0);
    context.bindSlot("deserializer", 1);
    context.bindSlot("protocol", 2);
    context.newSlot("target");
    context.newSlot("tfield");

    methodVisitor.visitCode();

    // <target> result = new <target>()
    methodVisitor.visitTypeInsn(NEW, targetClassName);
    methodVisitor.visitInsn(DUP);
    methodVisitor.visitMethodInsn(INVOKESPECIAL, targetClassName, "<init>", "()V");
    methodVisitor.visitVarInsn(ASTORE, context.getSlot("target"));

    // protocol.readStructBegin()
    methodVisitor.visitVarInsn(ALOAD, context.getSlot("protocol"));
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "com/facebook/thrift/protocol/TProtocol", "readStructBegin",
            "()Lcom/facebook/thrift/protocol/TStruct;");
    methodVisitor.visitInsn(POP); // discard return value

    // while (true)
    Label whileLabel = new Label();
    methodVisitor.visitLabel(whileLabel);

    // TField tfield = protocol.readFieldBegin()
    methodVisitor.visitVarInsn(ALOAD, context.getSlot("protocol"));
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "com/facebook/thrift/protocol/TProtocol", "readFieldBegin",
            "()Lcom/facebook/thrift/protocol/TField;");
    methodVisitor.visitVarInsn(ASTORE, context.getSlot("tfield"));

    // tfield.type
    methodVisitor.visitVarInsn(ALOAD, context.getSlot("tfield"));
    methodVisitor.visitFieldInsn(GETFIELD, "com/facebook/thrift/protocol/TField", "type", "B");

    methodVisitor.visitFieldInsn(GETSTATIC, "com/facebook/thrift/protocol/TType", "STOP", "B");

    // if (tfield.type == TType.STOP) { break; }
    Label endWhile = new Label();
    methodVisitor.visitJumpInsn(IF_ICMPEQ, endWhile);

    // tfield.id
    methodVisitor.visitVarInsn(ALOAD, context.getSlot("tfield"));
    methodVisitor.visitFieldInsn(GETFIELD, "com/facebook/thrift/protocol/TField", "id", "S");

    List<Field> fields = new ArrayList<Field>(type.getFields());
    int[] ids = new int[fields.size()];
    Label[] labels = new Label[fields.size()];
    for (int i = 0; i < fields.size(); ++i) {
        ids[i] = fields.get(i).getId();
        labels[i] = new Label();
    }

    Label fieldSkipped = new Label();

    methodVisitor.visitLookupSwitchInsn(fieldSkipped, ids, labels);

    for (int i = 0; i < fields.size(); ++i) {
        Field field = fields.get(i);

        methodVisitor.visitLabel(labels[i]);

        // if (tfield.type == ###)
        methodVisitor.visitVarInsn(ALOAD, context.getSlot("tfield"));
        methodVisitor.visitFieldInsn(GETFIELD, "com/facebook/thrift/protocol/TField", "type", "B");
        methodVisitor.visitIntInsn(BIPUSH, field.getType().getTType());
        methodVisitor.visitJumpInsn(IF_ICMPNE, fieldSkipped);

        methodVisitor.visitVarInsn(ALOAD, context.getSlot("target"));
        if (Map.class.isAssignableFrom(targetClass)) {
            methodVisitor.visitLdcInsn(field.getName());
            generateReadElement(methodVisitor, context, field.getType());
            generateAddToMap(targetClassName, methodVisitor, context, field);
        } else {
            generateReadElement(methodVisitor, context, field.getType());
            generateSetTargetField(targetClassName, methodVisitor, context, field);
        }

        methodVisitor.visitJumpInsn(GOTO, whileLabel);
    }

    methodVisitor.visitLabel(fieldSkipped);
    methodVisitor.visitVarInsn(ALOAD, context.getSlot("protocol"));
    methodVisitor.visitVarInsn(ALOAD, context.getSlot("tfield"));
    methodVisitor.visitFieldInsn(GETFIELD, "com/facebook/thrift/protocol/TField", "type", "B");
    methodVisitor.visitMethodInsn(INVOKESTATIC, "com/facebook/thrift/protocol/TProtocolUtil", "skip",
            "(Lcom/facebook/thrift/protocol/TProtocol;B)V");

    // end while
    methodVisitor.visitJumpInsn(GOTO, whileLabel);

    methodVisitor.visitLabel(endWhile);

    // protocol.readStructEnd()
    methodVisitor.visitVarInsn(ALOAD, context.getSlot("protocol"));
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "com/facebook/thrift/protocol/TProtocol", "readStructEnd",
            "()V");

    // return result
    methodVisitor.visitVarInsn(ALOAD, context.getSlot("target"));
    methodVisitor.visitInsn(ARETURN);

    methodVisitor.visitMaxs(1, 1); // TODO: what should these be?
    methodVisitor.visitEnd();
}