Example usage for org.objectweb.asm MethodVisitor visitJumpInsn

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

Introduction

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

Prototype

public void visitJumpInsn(final int opcode, final Label label) 

Source Link

Document

Visits a jump instruction.

Usage

From source file:jtaint.ServletAdapter.java

License:Apache License

private void buildTaintedReturnWrapper(MethodVisitor mv, Klass k, int access, String name, String desc) {
    mv.visitCode();// w  ww .  j a v  a  2  s  . com
    Type[] args = Type.getArgumentTypes(desc);
    Type ret = Type.getReturnType(desc);
    boolean isStatic = (access & ACC_STATIC) != 0;
    int l = 0;

    if (!isStatic) {
        mv.visitVarInsn(ALOAD, 0);
        l = 1;
    }

    for (int i = 0; i < args.length; l += args[i].getSize(), i++)
        mv.visitVarInsn(args[i].getOpcode(ILOAD), l);
    mv.visitMethodInsn(isStatic ? INVOKESTATIC : INVOKESPECIAL, className, ByteCodeUtil.internalName(name),
            desc);

    String taintDesc = Type.getMethodDescriptor(ret, new Type[] { ret });

    if (k.isExact()) {
        /* We already know that we need to wrap...no runtime check needed */
        mv.visitMethodInsn(INVOKESTATIC, "jtaint/StringUtil", "toTainted", taintDesc);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(l, l);
        mv.visitEnd();
        return;
    }

    /* Now taint the return type, if we need to */
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, ByteCodeUtil.internalName("is" + k.simpleName()), "Z");
    Label l0 = new Label();
    mv.visitJumpInsn(IFEQ, l0);
    mv.visitMethodInsn(INVOKESTATIC, "jtaint/StringUtil", "toTainted", taintDesc);

    mv.visitLabel(l0);
    if (version == V1_6)
        mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { ret.getInternalName() });
    mv.visitInsn(ARETURN);
    mv.visitMaxs(Math.max(l, 2), l);
    mv.visitEnd();
}

From source file:jtaint.ServletAdapter.java

License:Apache License

private void buildServletWrapper(MethodVisitor mv, Klass k, String name, String desc) {
    mv.visitCode();/*w  ww  .j av a 2s .co m*/

    Label start = new Label(), end = new Label(), handler = new Label();
    mv.visitTryCatchBlock(start, end, handler, null);
    mv.visitLabel(start);

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, ByteCodeUtil.internalName("is" + k.simpleName()), "Z");
    Label l0 = new Label();
    mv.visitJumpInsn(IFEQ, l0);

    Type[] t = Type.getArgumentTypes(desc);

    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEINTERFACE, t[0].getInternalName(), "getParameterMap", "()Ljava/util/Map;");

    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEINTERFACE, t[0].getInternalName(), "getRemoteHost", "()Ljava/lang/String;");

    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEINTERFACE, t[0].getInternalName(), "getRemoteAddr", "()Ljava/lang/String;");

    mv.visitMethodInsn(INVOKESTATIC, "jtaint/HttpUtil", "preService",
            "(Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;)V");
    mv.visitLabel(l0);
    if (version == V1_6)
        mv.visitFrame(F_SAME, 0, null, 0, null);

    mv.visitVarInsn(ALOAD, 0);
    int l = 1;

    for (int i = 0; i < t.length; l += t[i].getSize(), i++)
        mv.visitVarInsn(t[i].getOpcode(ILOAD), l);
    mv.visitMethodInsn(INVOKESPECIAL, className, ByteCodeUtil.internalName(name), desc);

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, ByteCodeUtil.internalName("is" + k.simpleName()), "Z");
    Label l1 = new Label();
    mv.visitJumpInsn(IFEQ, l1);

    mv.visitMethodInsn(INVOKESTATIC, "jtaint/HttpUtil", "postService", "()V");
    mv.visitLabel(l1);
    if (version == V1_6)
        mv.visitFrame(F_SAME, 0, null, 0, null);
    mv.visitInsn(RETURN);
    mv.visitLabel(end);

    mv.visitLabel(handler);
    if (version == V1_6)
        mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, ByteCodeUtil.internalName("is" + k.simpleName()), "Z");
    Label l2 = new Label();
    mv.visitJumpInsn(IFEQ, l2);
    mv.visitMethodInsn(INVOKESTATIC, "jtaint/HttpUtil", "postService", "()V");
    mv.visitLabel(l2);
    if (version == V1_6)
        mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });

    mv.visitInsn(ATHROW);
    mv.visitMaxs(Math.max(l, 3), l);
    mv.visitEnd();
}

From source file:jtaint.ServletAdapter.java

License:Apache License

private void buildGetPathTranslatedWrapper(MethodVisitor mv) {
    mv.visitCode();//from  w w w.  ja  v a  2  s  .co m

    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, className, ByteCodeUtil.internalName("getPathTranslated"),
            "()Ljava/lang/String;");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, ByteCodeUtil.internalName("isHttpServletRequest"), "Z");
    Label l0 = new Label();
    mv.visitJumpInsn(IFEQ, l0);

    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESTATIC, "jtaint/HttpUtil", "getPathTranslated",
            "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;");

    mv.visitLabel(l0);
    if (version == V1_6)
        mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/String" });
    mv.visitInsn(ARETURN);
    mv.visitMaxs(2, 1);
    mv.visitEnd();
}

From source file:jtaint.ServletAdapter.java

License:Apache License

private void buildHtmlValidatorWrapper(MethodVisitor mv, String name, String desc) {
    mv.visitCode();//ww  w  .j  av a 2 s .c  o  m

    Type[] t = Type.getArgumentTypes(desc);
    Type r = Type.getReturnType(desc);

    mv.visitVarInsn(ALOAD, 0);
    int l = 1;

    for (int i = 0; i < t.length; l += t[i].getSize(), i++)
        mv.visitVarInsn(t[i].getOpcode(ILOAD), l);
    mv.visitMethodInsn(INVOKESPECIAL, className, ByteCodeUtil.internalName(name), desc);

    Label l0 = new Label();
    mv.visitInsn(DUP);
    mv.visitJumpInsn(IFNULL, l0);

    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKEVIRTUAL, r.getInternalName(), ByteCodeUtil.internalName("getHtmlValidator"),
            "()Ljtaint/HtmlValidator;");
    mv.visitJumpInsn(IFNONNULL, l0);

    /* Okay, we have a valid print object and null html validator, time 
     * to initialize...
     */

    mv.visitInsn(DUP);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESTATIC, "jtaint/HttpUtil", "getHtmlValidator",
            "(Ljava/lang/Object;)Ljtaint/HtmlValidator;");
    mv.visitMethodInsn(INVOKEVIRTUAL, r.getInternalName(), ByteCodeUtil.internalName("setHtmlValidator"),
            "(Ljtaint/HtmlValidator;)V");

    mv.visitLabel(l0);
    if (version == V1_6)
        mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { r.getInternalName() });
    mv.visitInsn(ARETURN);

    mv.visitMaxs(Math.max(l, 3), l);
    mv.visitEnd();
}

From source file:jtaint.SqlAdapter.java

License:Apache License

private void addSqlValidator() {
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC
            //[ifJava4]
            + ACC_SYNCHRONIZED//from  w  w  w .j a  v a 2 s  .c o  m
    //[fiJava4] 
            , ByteCodeUtil.internalName("sqlValidator"), "()Ljtaint/SqlValidator;", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, ByteCodeUtil.internalName("validator"), "Ljtaint/SqlValidator;");
    mv.visitInsn(DUP);

    Label l0 = new Label();
    mv.visitJumpInsn(IFNULL, l0);
    mv.visitInsn(ARETURN);

    mv.visitLabel(l0);
    if (version == V1_6)
        mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "jtaint/SqlValidator" });

    mv.visitInsn(POP);

    /* XXX This is an industrial-sized barrel of fun. We have to avoid
     * infinite recursion here when initializing the validator field --
     * i.e. when sqlValidator is called for the first time. In this case,
     * what can happen is:
     * connection.sqlValidator -> jtaint.SqlUtil.getSqlValidator
     * -> Connection.getDatabaseMetadata 
     * -> Connection.sqlValidator ->
     * -> jtaint.SqlUtil.getSqlValidator
     * -> Connection.getDatabaseMetadata
     * ... (repeat last three steps forever), where -> denotes a method call
     * So if we ever find that we already own the lock that we are about
     * to acquire, then we return an EmptySqlValidator to break
     * the recursion(Note that once the recursion unwinds, the validator
     * field will be correctly set, so we will begin returning the correct
     * sql validator. This corner case applies only during initialization).
     */

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, ByteCodeUtil.internalName("lockObj"), "Ljava/lang/Object;");
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "holdsLock", "(Ljava/lang/Object;)Z");
    Label l1 = new Label();
    mv.visitJumpInsn(IFEQ, l1);

    /* Break the recursion */
    mv.visitFieldInsn(GETSTATIC, "jtaint/EmptySqlValidator", "INSTANCE", "Ljtaint/EmptySqlValidator;");
    mv.visitInsn(ARETURN);

    /* No recursion -- acquire the lock and initialize our field */
    mv.visitLabel(l1);
    if (version == V1_6)
        mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Object" });
    mv.visitInsn(DUP);
    mv.visitInsn(MONITORENTER);

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, ByteCodeUtil.internalName("validator"), "Ljtaint/SqlValidator;");
    mv.visitInsn(DUP);
    Label l2 = new Label();
    mv.visitJumpInsn(IFNULL, l2);
    mv.visitInsn(SWAP);
    mv.visitInsn(MONITOREXIT);
    mv.visitInsn(ARETURN);

    mv.visitLabel(l2);
    if (version == V1_6)
        mv.visitFrame(F_FULL, 1, new Object[] { className }, 2,
                new Object[] { "java/lang/Object", "jtaint/SqlValidator" });
    mv.visitInsn(POP);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESTATIC, "jtaint/SqlUtil", "getSqlValidator",
            "(Ljava/lang/Object;)Ljtaint/SqlValidator;");
    mv.visitInsn(DUP_X1);
    mv.visitFieldInsn(PUTFIELD, className, ByteCodeUtil.internalName("validator"), "Ljtaint/SqlValidator;");
    mv.visitInsn(SWAP);
    mv.visitInsn(MONITOREXIT);
    mv.visitInsn(ARETURN);

    mv.visitMaxs(4, 1);
    mv.visitEnd();
}

From source file:jtaint.StringAdapter.java

License:Apache License

/** Create new method that compares its argument to the package-private
 * constant Character.ERROR. This must be exported for jtaint helper
 * methods. Equivalent to the following Java code:
 *
 * public static boolean isError(int c) {
 *     return c == Character.ERROR;// ww  w .  j a  v  a  2  s .c om
 * }
 */
private void addIsErrorMethod(ClassVisitor cv) {
    boolean isError = false;
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC + ACC_STATIC, ByteCodeUtil.internalName("isError"), "(I)Z",
            null, null);
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 0);

    /* Test to see if java/lang/Character uses ERROR or CHAR_ERROR 
     * If ERROR cannot be found, an getDeclaredFields throws an exception
     */
    try {
        Character.class.getDeclaredField("ERROR");
        isError = true;
    } catch (Throwable th) {
        /* ignore */ }

    if (isError)
        mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "ERROR", "I");
    else
        mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "CHAR_ERROR", "C");

    Label l = new Label();
    mv.visitJumpInsn(IF_ICMPEQ, l);
    mv.visitInsn(ICONST_0);
    mv.visitInsn(IRETURN);

    mv.visitLabel(l);
    if (version == V1_6)
        mv.visitFrame(F_SAME, 0, null, 0, null);

    mv.visitInsn(ICONST_1);
    mv.visitInsn(IRETURN);
    mv.visitMaxs(2, 1);
    mv.visitEnd();
}

From source file:jtaint.StringAdapter.java

License:Apache License

/** Create a new method that returns a Taint object representing the taint
 * for this String. Equivalent to the following Java code:
 * /* w  w w. j  a  v a 2 s  . com*/
 * public Taint taint() {
 *     if (!tainted) {
 *         return null;
 *     } else {
 *         return jtaint.StringUtil.stringToTaint(value, count);
 *     }
 * }
 */

private void addTaintMethod(ClassVisitor cv) {
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, ByteCodeUtil.internalName("taint"), "()Ljtaint/Taint;", null,
            null);
    mv.visitCode();

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, ByteCodeUtil.internalName("tainted"), "Z");

    Label l = new Label();
    mv.visitJumpInsn(IFNE, l);
    mv.visitInsn(ACONST_NULL);
    mv.visitInsn(ARETURN);

    mv.visitLabel(l);
    if (version == V1_6)
        mv.visitFrame(F_SAME, 0, null, 0, null);

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, "value", "[C");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, "count", "I");
    mv.visitMethodInsn(INVOKESTATIC, "jtaint/StringUtil", "stringToTaint", "([CI)Ljtaint/Taint;");
    mv.visitInsn(ARETURN);
    mv.visitMaxs(4, 1);
    mv.visitEnd();
}

From source file:jtaint.StringAdapter.java

License:Apache License

/** Add a new constructor to a create a (partially or fully) tainted 
 * String. Equivalent to the following Java code:
 *
 * public String(String original, Taint t) {
 *     super();//from ww  w. ja  v  a 2  s  .c o m
 *     this.count = original.count;
 *
 *     if (!t.isTainted()) {
 *         this.offset = original.offset;
 *         this.value = original.value;
 *         this.tainted = original.tainted;
 *         return
 *     }
 *
 *     this.offset = 0;
 *     this.value = jtaint.StringUtil.taintToString(original, t)
 *     if (this.value.length == this.count)
 *         this.tainted = false;
 *     else
 *         this.tainted = true;
 *     return;
 * The final check (if value.length == count) is true only when an error
 * occurs during the execution of taintToString
 */

private void addConstructor(ClassVisitor cv) {
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;Ljtaint/Taint;)V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");

    copyField(mv, "count", "I");

    Label l0 = new Label();
    mv.visitVarInsn(ALOAD, 2);
    mv.visitMethodInsn(INVOKEVIRTUAL, "jtaint/Taint", "isTainted", "()Z");
    mv.visitJumpInsn(IFNE, l0);

    /* Taint object is actually untainted, copy all fields and return */
    copyField(mv, "offset", "I");
    copyField(mv, "value", "[C");
    copyField(mv, ByteCodeUtil.internalName("tainted"), "Z");
    mv.visitInsn(RETURN);

    mv.visitLabel(l0);
    if (version == V1_6)
        mv.visitFrame(F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitInsn(ICONST_0);
    mv.visitFieldInsn(PUTFIELD, className, "offset", "I");

    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitMethodInsn(INVOKESTATIC, "jtaint/StringUtil", "taintToString",
            "(Ljava/lang/String;Ljtaint/Taint;)[C");
    mv.visitInsn(DUP_X1);
    mv.visitFieldInsn(PUTFIELD, className, "value", "[C");
    mv.visitInsn(ARRAYLENGTH);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, "count", "I");

    Label l1 = new Label();
    mv.visitJumpInsn(IF_ICMPEQ, l1);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitInsn(ICONST_1);
    mv.visitFieldInsn(PUTFIELD, className, ByteCodeUtil.internalName("tainted"), "Z");
    mv.visitInsn(RETURN);

    mv.visitLabel(l1);
    if (version == V1_6)
        mv.visitFrame(F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitInsn(ICONST_0);
    mv.visitFieldInsn(PUTFIELD, className, ByteCodeUtil.internalName("tainted"), "Z");

    mv.visitInsn(RETURN);

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

From source file:jtaint.XssAdapter.java

License:Apache License

private void buildWriteIntWrapper(final MethodVisitor mv, final String methodName, final String desc) {
    new XssLockBuilder(mv, version, className, methodName, desc) {
        public void onUnlocked() {
            mv.visitVarInsn(ALOAD, 0);// w  ww  . j av a 2s.  co m
            mv.visitMethodInsn(INVOKEVIRTUAL, className, ByteCodeUtil.internalName("getHtmlValidator"),
                    "()Ljtaint/HtmlValidator;");

            if ("javax/servlet/ServletOutputStream".equals(className)) {
                mv.visitVarInsn(ILOAD, 1);
                mv.visitInsn(I2B);
                mv.visitMethodInsn(INVOKEVIRTUAL, "jtaint/HtmlValidator", "write", "(B)V");
            } else if ("java/io/PrintWriter".equals(className)) {
                mv.visitVarInsn(ILOAD, 1);
                mv.visitInsn(I2C);
                mv.visitMethodInsn(INVOKEVIRTUAL, "jtaint/HtmlValidator", "print", "(C)V");
            } else {
                /* Runtime check required */
                Label l0 = new Label();
                Label l1 = new Label();

                mv.visitVarInsn(ALOAD, 0);
                mv.visitTypeInsn(INSTANCEOF, "java/io/PrintWriter");
                mv.visitJumpInsn(IFNE, l1);

                /* If-branch, we're a ServletOutputStream.  */
                mv.visitVarInsn(ILOAD, 1);
                mv.visitInsn(I2B);
                mv.visitMethodInsn(INVOKEVIRTUAL, "jtaint/HtmlValidator", "write", "(B)V");
                mv.visitJumpInsn(GOTO, l0);

                /* Else-branch, we're a PrintWriter  */
                mv.visitLabel(l1);
                if (version == V1_6)
                    mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "jtaint/HtmlValidator" });

                mv.visitVarInsn(ILOAD, 1);
                mv.visitInsn(I2C);
                mv.visitMethodInsn(INVOKEVIRTUAL, "jtaint/HtmlValidator", "print", "(C)V");
                mv.visitLabel(l0);
                if (version == V1_6) {
                    mv.visitFrame(F_SAME, 0, null, 0, null);
                    /* We can't end on a visitFrame because 
                     * InstrumentationLockAdapter performs a visitFrame 
                     * after this method completes. Two consecutive 
                     * visitFrames cause the Java 6 type checker to barf, 
                     * so just pad with a single NOP.
                     */
                    mv.visitInsn(NOP);
                }
            }
        }
    }.build();
}

From source file:kilim.analysis.CallWeaver.java

License:Open Source License

/**
 * <pre>//from   www  .  j  av  a  2  s  . com
 * The following template is produced in the method's prelude for each
 * pausable method. 
 * F_REWIND: 
 *   for each bottom stack operand
 *      introduce a dummy constant of the appropriate type.
 *         (iconst_0, aconst_null, etc.)
 *      if the call is not static, 
 *         we need the called object's object reference
 *         ask the next state in the fiber's list
 *   goto F_CALL: // jump to the invocation site.
 * </pre>
 * 
 * @param mv
 */
void genRewind(MethodVisitor mv) {
    Frame f = bb.startFrame;

    // The last parameter to the method is fiber, but the original
    // code doesn't know that and will use up that slot as it
    // pleases. If we are going to jump directly to the basicblock
    // bb, we'll have to make sure it has some dummy value of that
    // type going in just to keep the verifier happy. 

    for (int i = methodWeaver.getFiberArgVar(); i < f.getMaxLocals();) {
        Value v = f.getLocal(i);
        if (v.getTypeDesc() != D_UNDEFINED) {
            //            if (u.isLiveIn(i)) {
            int vmt = toVmType(v.getTypeDesc());
            mv.visitInsn(VMType.constInsn[vmt]);
            storeVar(mv, vmt, i);
        }
        i += v.isCategory2() ? 2 : 1;
    }

    // store dummy values in stack. The constants have to correspond
    // to the types of each of the bottom elements.
    int numBottom = getNumBottom();

    // spos == stack pos. Note that it is incremented beyond the
    // 'for' loop below.
    int spos;
    for (spos = 0; spos < numBottom; spos++) {
        Value v = f.getStack(spos);
        if (v.isConstant()) {
            mv.visitInsn(VMType.constInsn[VMType.toVmType(v.getTypeDesc())]);
        } else {
            ValInfo vi = valInfoList.find(v);
            mv.visitInsn(VMType.constInsn[vi.vmt]);
        }
    }
    if (!isStaticCall()) {
        // The next element in the stack after numBottom is the object
        // reference for the callee. This can't be a dummy because it 
        // is needed by the invokevirtual call. If this reference
        // is found in the local vars, we'll use it, otherwise we need
        // to dip into the next activation frame in the fiber to
        // retrieve it.
        Value v = f.getStack(numBottom);
        if (!methodWeaver.isStatic() && f.getLocal(0) == v) {
            // "this" is already properly initialized.
            mv.visitInsn(ALOAD_0);
        } else {
            loadVar(mv, TOBJECT, methodWeaver.getFiberVar());
            mv.visitMethodInsn(INVOKEVIRTUAL, FIBER_CLASS, "getCallee", "()Ljava/lang/Object;");
            mv.visitTypeInsn(CHECKCAST, getReceiverTypename());
        }
        spos++;
    }

    int len = f.getStackLen();
    // fill rest of stack with dummy args
    for (; spos < len; spos++) {
        Value v = f.getStack(spos);
        int vmt = VMType.toVmType(v.getTypeDesc());
        mv.visitInsn(VMType.constInsn[vmt]);
    }

    mv.visitJumpInsn(GOTO, callLabel);
}