Example usage for org.objectweb.asm.tree.analysis BasicValue getType

List of usage examples for org.objectweb.asm.tree.analysis BasicValue getType

Introduction

In this page you can find the example usage for org.objectweb.asm.tree.analysis BasicValue getType.

Prototype

public Type getType() 

Source Link

Document

Returns the Type of this value.

Usage

From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java

License:Open Source License

private void emitNewAndDup(MethodVisitor mv, Frame frame, int stackIndex, MethodInsnNode min) {
    int arguments = frame.getStackSize() - stackIndex - 1;
    int neededLocals = 0;
    for (int i = arguments; i >= 1; i--) {
        BasicValue v = (BasicValue) frame.getStack(stackIndex + i);
        mv.visitVarInsn(v.getType().getOpcode(Opcodes.ISTORE), lvarStack + NUM_LOCALS + neededLocals);
        neededLocals += v.getSize();//from w  w  w  .  j  ava  2  s. c o m
    }
    db.log(LogLevel.DEBUG, "Inserting NEW & DUP for constructor call %s%s with %d arguments (%d locals)",
            min.owner, min.desc, arguments, neededLocals);
    if (additionalLocals < neededLocals) {
        additionalLocals = neededLocals;
    }
    ((NewValue) frame.getStack(stackIndex - 1)).insn.accept(mv);
    ((NewValue) frame.getStack(stackIndex)).insn.accept(mv);
    for (int i = 1; i <= arguments; i++) {
        BasicValue v = (BasicValue) frame.getStack(stackIndex + i);
        neededLocals -= v.getSize();
        mv.visitVarInsn(v.getType().getOpcode(Opcodes.ILOAD), lvarStack + NUM_LOCALS + neededLocals);
    }
}

From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java

License:Open Source License

private void emitStoreState(MethodVisitor mv, int idx, FrameInfo fi, int numArgsToPreserve) {
    Frame f = frames[fi.endInstruction];

    if (fi.lBefore != null)
        fi.lBefore.accept(mv);//w w w .j  a v a 2  s . com

    mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
    emitConst(mv, idx);
    emitConst(mv, fi.numSlots);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "pushMethod", "(II)V");

    // store operand stack
    for (int i = f.getStackSize(); i-- > 0;) {
        BasicValue v = (BasicValue) f.getStack(i);
        if (!isOmitted(v)) {
            if (!isNullType(v)) {
                int slotIdx = fi.stackSlotIndices[i];
                assert slotIdx >= 0 && slotIdx < fi.numSlots;
                emitStoreValue(mv, v, lvarStack, slotIdx, -1);
            } else {
                db.log(LogLevel.DEBUG, "NULL stack entry: type=%s size=%d", v.getType(), v.getSize());
                mv.visitInsn(Opcodes.POP);
            }
        }
    }

    // store local vars
    for (int i = firstLocal; i < f.getLocals(); i++) {
        BasicValue v = (BasicValue) f.getLocal(i);
        if (!isNullType(v)) {
            mv.visitVarInsn(v.getType().getOpcode(Opcodes.ILOAD), i);
            int slotIdx = fi.localSlotIndices[i];
            assert slotIdx >= 0 && slotIdx < fi.numSlots;
            emitStoreValue(mv, v, lvarStack, slotIdx, i);
        }
    }

    // restore last numArgsToPreserve operands
    for (int i = f.getStackSize() - numArgsToPreserve; i < f.getStackSize(); i++) {
        BasicValue v = (BasicValue) f.getStack(i);
        if (!isOmitted(v)) {
            if (!isNullType(v)) {
                int slotIdx = fi.stackSlotIndices[i];
                assert slotIdx >= 0 && slotIdx < fi.numSlots;
                emitRestoreValue(mv, v, lvarStack, slotIdx, -1);
            } else {
                mv.visitInsn(Opcodes.ACONST_NULL);
            }
        }
    }
}

From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java

License:Open Source License

private void emitRestoreState(MethodVisitor mv, int idx, FrameInfo fi, int numArgsPreserved) {
    Frame f = frames[fi.endInstruction];

    // restore local vars
    for (int i = firstLocal; i < f.getLocals(); i++) {
        BasicValue v = (BasicValue) f.getLocal(i);
        if (!isNullType(v)) {
            int slotIdx = fi.localSlotIndices[i];
            assert slotIdx >= 0 && slotIdx < fi.numSlots;
            emitRestoreValue(mv, v, lvarStack, slotIdx, i);
            mv.visitVarInsn(v.getType().getOpcode(Opcodes.ISTORE), i);
        } else if (v != BasicValue.UNINITIALIZED_VALUE) {
            mv.visitInsn(Opcodes.ACONST_NULL);
            mv.visitVarInsn(Opcodes.ASTORE, i);
        }//  www . j  ava 2  s  .  com
    }

    // restore operand stack
    for (int i = 0; i < f.getStackSize() - numArgsPreserved; i++) {
        BasicValue v = (BasicValue) f.getStack(i);
        if (!isOmitted(v)) {
            if (!isNullType(v)) {
                int slotIdx = fi.stackSlotIndices[i];
                assert slotIdx >= 0 && slotIdx < fi.numSlots;
                emitRestoreValue(mv, v, lvarStack, slotIdx, -1);
            } else {
                mv.visitInsn(Opcodes.ACONST_NULL);
            }
        }
    }

    if (fi.lAfter != null) {
        fi.lAfter.accept(mv);
    }
}

From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java

License:Open Source License

private void emitStoreValue(MethodVisitor mv, BasicValue v, int lvarStack, int idx, int lvar)
        throws InternalError, IndexOutOfBoundsException {
    String desc;/*from   www  . jav  a2 s.c  o m*/

    switch (v.getType().getSort()) {
    case Type.OBJECT:
    case Type.ARRAY:
        desc = "(Ljava/lang/Object;L" + STACK_NAME + ";I)V";
        break;
    case Type.BOOLEAN:
    case Type.BYTE:
    case Type.SHORT:
    case Type.CHAR:
    case Type.INT:
        desc = "(IL" + STACK_NAME + ";I)V";
        break;
    case Type.FLOAT:
        desc = "(FL" + STACK_NAME + ";I)V";
        break;
    case Type.LONG:
        desc = "(JL" + STACK_NAME + ";I)V";
        break;
    case Type.DOUBLE:
        desc = "(DL" + STACK_NAME + ";I)V";
        break;
    default:
        throw new InternalError("Unexpected type: " + v.getType());
    }

    mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
    //        if (v.getType().getSort() == Type.OBJECT || v.getType().getSort() == Type.ARRAY)
    //            println(mv, "STORE " + (lvar >= 0 ? ("VAR " + lvar + ": ") : "OPRND: "));
    emitConst(mv, idx);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, STACK_NAME, "push", desc);
}

From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java

License:Open Source License

private void emitRestoreValue(MethodVisitor mv, BasicValue v, int lvarStack, int idx, int lvar) {
    mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
    emitConst(mv, idx);//from w w w . j  a v  a2s .  co m

    switch (v.getType().getSort()) {
    case Type.OBJECT:
        String internalName = v.getType().getInternalName();
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "getObject", "(I)Ljava/lang/Object;");
        if (!internalName.equals("java/lang/Object")) // don't cast to Object ;)
            mv.visitTypeInsn(Opcodes.CHECKCAST, internalName);
        //                println(mv, "RESTORE " + (lvar >= 0 ? ("VAR " + lvar + ": ") : "OPRND: "));
        break;
    case Type.ARRAY:
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "getObject", "(I)Ljava/lang/Object;");
        mv.visitTypeInsn(Opcodes.CHECKCAST, v.getType().getDescriptor());
        break;
    case Type.BYTE:
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "getInt", "(I)I");
        mv.visitInsn(Opcodes.I2B);
        break;
    case Type.SHORT:
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "getInt", "(I)I");
        mv.visitInsn(Opcodes.I2S);
        break;
    case Type.CHAR:
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "getInt", "(I)I");
        mv.visitInsn(Opcodes.I2C);
        break;
    case Type.BOOLEAN:
    case Type.INT:
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "getInt", "(I)I");
        break;
    case Type.FLOAT:
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "getFloat", "(I)F");
        break;
    case Type.LONG:
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "getLong", "(I)J");
        break;
    case Type.DOUBLE:
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "getDouble", "(I)D");
        break;
    default:
        throw new InternalError("Unexpected type: " + v.getType());
    }
}

From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java

License:Open Source License

static boolean isNullType(BasicValue v) {
    return (v == BasicValue.UNINITIALIZED_VALUE)
            || (v.isReference() && v.getType().getInternalName().equals("null"));
}

From source file:com.android.tools.lint.checks.SecureRandomDetector.java

License:Apache License

@Override
public void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode, @NonNull MethodNode method,
        @NonNull MethodInsnNode call) {//www.  ja va  2s.  c  o  m
    String owner = call.owner;
    String desc = call.desc;
    if (owner.equals(OWNER_SECURE_RANDOM)) {
        if (desc.startsWith(LONG_ARG)) {
            checkValidSetSeed(context, call);
        } else if (desc.startsWith("([B)")) { //$NON-NLS-1$
            // setSeed(byte[]) ...
            // We could do some flow analysis here to see whether the byte array getting
            // passed in appears to be fixed.
            // However, people calling this constructor rather than the simpler one
            // with a fixed integer are probably less likely to make that mistake... right?
        }
    } else if (owner.equals(OWNER_RANDOM) && desc.startsWith(LONG_ARG)) {
        // Called setSeed(long) on an instanceof a Random object. Flag this if the instance
        // is likely a SecureRandom.

        // Track allocations such that we know whether the type of the call
        // is on a SecureRandom rather than a Random
        Analyzer analyzer = new Analyzer(new BasicInterpreter() {
            @Override
            public BasicValue newValue(Type type) {
                if (type != null && type.getDescriptor().equals(VM_SECURE_RANDOM)) {
                    return new BasicValue(type);
                }
                return super.newValue(type);
            }
        });
        try {
            Frame[] frames = analyzer.analyze(classNode.name, method);
            InsnList instructions = method.instructions;
            Frame frame = frames[instructions.indexOf(call)];
            int stackSlot = frame.getStackSize();
            for (Type type : Type.getArgumentTypes(desc)) {
                stackSlot -= type.getSize();
            }
            BasicValue stackValue = (BasicValue) frame.getStack(stackSlot);
            Type type = stackValue.getType();
            if (type != null && type.getDescriptor().equals(VM_SECURE_RANDOM)) {
                checkValidSetSeed(context, call);
            }
        } catch (AnalyzerException e) {
            context.log(e, null);
        }
    } else if (owner.equals(OWNER_RANDOM) && desc.startsWith(LONG_ARG)) {
        // Called setSeed(long) on an instanceof a Random object. Flag this if the instance
        // is likely a SecureRandom.
        // TODO
    }
}

From source file:com.android.tools.lint.checks.ViewTagDetector.java

License:Apache License

@Override
public void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode, @NonNull MethodNode method,
        @NonNull MethodInsnNode call) {/*from ww w.j av a  2s . c o m*/
    // The leak behavior is fixed in ICS:
    // http://code.google.com/p/android/issues/detail?id=18273
    if (context.getMainProject().getMinSdk() >= 14) {
        return;
    }

    String owner = call.owner;
    String desc = call.desc;
    if (owner.equals("android/view/View") //$NON-NLS-1$
            && desc.equals("(ILjava/lang/Object;)V")) { //$NON-NLS-1$
        Analyzer analyzer = new Analyzer(new BasicInterpreter() {
            @Override
            public BasicValue newValue(Type type) {
                if (type == null) {
                    return BasicValue.UNINITIALIZED_VALUE;
                } else if (type.getSort() == Type.VOID) {
                    return null;
                } else {
                    return new BasicValue(type);
                }
            }
        });
        try {
            Frame[] frames = analyzer.analyze(classNode.name, method);
            InsnList instructions = method.instructions;
            Frame frame = frames[instructions.indexOf(call)];
            if (frame.getStackSize() < 3) {
                return;
            }
            BasicValue stackValue = (BasicValue) frame.getStack(2);
            Type type = stackValue.getType();
            if (type == null) {
                return;
            }

            String internalName = type.getInternalName();
            String className = type.getClassName();
            LintDriver driver = context.getDriver();

            SdkInfo sdkInfo = context.getClient().getSdkInfo(context.getMainProject());
            String objectType = null;
            while (className != null) {
                if (className.equals("android.view.View")) { //$NON-NLS-1$
                    objectType = "views";
                    break;
                } else if (className.endsWith("ViewHolder")) { //$NON-NLS-1$
                    objectType = "view holders";
                    break;
                } else if (className.endsWith("Cursor") //$NON-NLS-1$
                        && className.startsWith("android.")) { //$NON-NLS-1$
                    objectType = "cursors";
                    break;
                }

                // TBD: Bitmaps, drawables? That's tricky, because as explained in
                // http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html
                // apparently these are used along with nulling out the callbacks,
                // and that's harder to detect here

                String parent = sdkInfo.getParentViewClass(className);
                if (parent == null) {
                    if (internalName == null) {
                        internalName = className.replace('.', '/');
                    }
                    assert internalName != null;
                    parent = driver.getSuperClass(internalName);
                }
                className = parent;
                internalName = null;
            }

            if (objectType != null) {
                Location location = context.getLocation(call);
                String message = String.format("Avoid setting %1$s as values for setTag: "
                        + "Can lead to memory leaks in versions older than Android 4.0", objectType);
                context.report(ISSUE, method, call, location, message, null);
            }
        } catch (AnalyzerException e) {
            context.log(e, null);
        }
    }
}

From source file:com.dragome.callbackevictor.serverside.bytecode.transformation.asm.ContinuationMethodAdapter.java

License:Apache License

public void visitCode() {
    mv.visitCode();/* w  ww . j  a  va2  s  .  c o m*/

    int fsize = labels.size();
    Label[] restoreLabels = new Label[fsize];
    for (int i = 0; i < restoreLabels.length; i++) {
        restoreLabels[i] = new Label();
    }

    // verify if restoring
    Label l0 = new Label();

    // PC: StackRecorder stackRecorder = StackRecorder.get();
    mv.visitMethodInsn(INVOKESTATIC, STACK_RECORDER, "get", "()L" + STACK_RECORDER + ";", false);
    mv.visitInsn(DUP);
    mv.visitVarInsn(ASTORE, stackRecorderVar);
    mv.visitLabel(startLabel);

    // PC: if (stackRecorder != null && !stackRecorder.isRestoring) {  
    mv.visitJumpInsn(IFNULL, l0);
    mv.visitVarInsn(ALOAD, stackRecorderVar);
    mv.visitFieldInsn(GETFIELD, STACK_RECORDER, "isRestoring", "Z");
    mv.visitJumpInsn(IFEQ, l0);

    mv.visitVarInsn(ALOAD, stackRecorderVar);
    // PC:    stackRecorder.popInt();
    mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Int", "()I", false);
    mv.visitTableSwitchInsn(0, fsize - 1, l0, restoreLabels);

    // switch cases
    for (int i = 0; i < fsize; i++) {
        Label frameLabel = labels.get(i);
        mv.visitLabel(restoreLabels[i]);

        MethodInsnNode mnode = nodes.get(i);
        Frame frame = analyzer.getFrames()[canalyzer.getIndex(mnode)];

        // for each local variable store the value in locals popping it from the stack!
        // locals
        int lsize = frame.getLocals();
        for (int j = lsize - 1; j >= 0; j--) {
            BasicValue value = (BasicValue) frame.getLocal(j);
            if (isNull(value)) {
                mv.visitInsn(ACONST_NULL);
                mv.visitVarInsn(ASTORE, j);
            } else if (value == BasicValue.UNINITIALIZED_VALUE) {
                // TODO ??
            } else if (value == BasicValue.RETURNADDRESS_VALUE) {
                // TODO ??
            } else {
                mv.visitVarInsn(ALOAD, stackRecorderVar);
                Type type = value.getType();
                if (value.isReference()) {
                    mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Object",
                            "()Ljava/lang/Object;", false);
                    Type t = value.getType();
                    String desc = t.getDescriptor();
                    if (desc.charAt(0) == '[') {
                        mv.visitTypeInsn(CHECKCAST, desc);
                    } else {
                        mv.visitTypeInsn(CHECKCAST, t.getInternalName());
                    }
                    mv.visitVarInsn(ASTORE, j);

                } else {
                    mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPopMethod(type),
                            "()" + type.getDescriptor(), false);
                    mv.visitVarInsn(type.getOpcode(ISTORE), j);
                }
            }
        }

        if (frame instanceof MonitoringFrame) {
            int[] monitoredLocals = ((MonitoringFrame) frame).getMonitored();
            // System.out.println(System.identityHashCode(frame)+" AMonitored locals "+monitoredLocals.length);
            for (int monitoredLocal : monitoredLocals) {
                // System.out.println(System.identityHashCode(frame)+" AMonitored local "+monitoredLocals[j]);
                mv.visitVarInsn(ALOAD, monitoredLocal);
                mv.visitInsn(MONITORENTER);
            }
        }

        // stack
        int argSize = Type.getArgumentTypes(mnode.desc).length;
        int ownerSize = mnode.getOpcode() == INVOKESTATIC ? 0 : 1; // TODO
        int initSize = mnode.name.equals("<init>") ? 2 : 0;
        int ssize = frame.getStackSize();
        for (int j = 0; j < ssize - argSize - ownerSize - initSize; j++) {
            BasicValue value = (BasicValue) frame.getStack(j);
            if (isNull(value)) {
                mv.visitInsn(ACONST_NULL);
            } else if (value == BasicValue.UNINITIALIZED_VALUE) {
                // TODO ??
            } else if (value == BasicValue.RETURNADDRESS_VALUE) {
                // TODO ??
            } else if (value.isReference()) {
                mv.visitVarInsn(ALOAD, stackRecorderVar);
                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Object", "()Ljava/lang/Object;",
                        false);
                mv.visitTypeInsn(CHECKCAST, value.getType().getInternalName());
            } else {
                Type type = value.getType();
                mv.visitVarInsn(ALOAD, stackRecorderVar);
                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPopMethod(type),
                        "()" + type.getDescriptor(), false);
            }
        }

        boolean hasMethodRef = false;
        if (mnode.getOpcode() != INVOKESTATIC) {
            // Load the object whose method we are calling  
            BasicValue value = ((BasicValue) frame.getStack(ssize - argSize - 1));
            if (isNull(value)) {
                // If user code causes NPE, then we keep this behavior: load null to get NPE at runtime 
                mv.visitInsn(ACONST_NULL);
            } else {
                hasMethodRef = true;

                mv.visitVarInsn(ALOAD, stackRecorderVar);
                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Reference",
                        "()Ljava/lang/Object;", false);
                mv.visitTypeInsn(CHECKCAST, value.getType().getInternalName());

            }
        }

        // Create null types for the parameters of the method invocation
        // RS:
        if (hasMethodRef && canalyzer._continueReflection && mnode.name.contains("invoke")
                && mnode.owner.contains("java/lang/reflect/Method")) {
            ContinuationMethodAnalyzer.MyVariables vars = canalyzer._reflectMapping.get(mnode);
            mv.visitVarInsn(ALOAD, vars.objectVar());
            mv.visitVarInsn(ALOAD, vars.argsVar());
            //mv.visitVarInsn(ALOAD, 2);
            //mv.visitVarInsn(ALOAD, 4);
        }
        //RS:
        else {
            for (Type paramType : Type.getArgumentTypes(mnode.desc)) {
                pushDefault(paramType);
            }
        }

        // continue to the next method
        mv.visitJumpInsn(GOTO, frameLabel);
    }

    // PC: }
    // end of start block
    mv.visitLabel(l0);
}

From source file:com.dragome.callbackevictor.serverside.bytecode.transformation.asm.ContinuationMethodAdapter.java

License:Apache License

public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
    mv.visitMethodInsn(opcode, owner, name, desc, itf);

    if (currentFrame != null) {
        Label fl = new Label();

        mv.visitVarInsn(ALOAD, stackRecorderVar);
        mv.visitJumpInsn(IFNULL, fl);// w  w  w .  j  a va  2  s. c om
        mv.visitVarInsn(ALOAD, stackRecorderVar);
        mv.visitFieldInsn(GETFIELD, STACK_RECORDER, "isCapturing", "Z");
        mv.visitJumpInsn(IFEQ, fl);

        // save stack
        Type returnType = Type.getReturnType(desc);
        boolean hasReturn = returnType != Type.VOID_TYPE;
        if (hasReturn) {
            mv.visitInsn(returnType.getSize() == 1 ? POP : POP2);
        }

        Type[] params = Type.getArgumentTypes(desc);
        int argSize = params.length;
        int ownerSize = opcode == INVOKESTATIC ? 0 : 1; // TODO
        int ssize = currentFrame.getStackSize() - argSize - ownerSize;
        for (int i = ssize - 1; i >= 0; i--) {
            BasicValue value = (BasicValue) currentFrame.getStack(i);
            if (isNull(value)) {
                mv.visitInsn(POP);
            } else if (value == BasicValue.UNINITIALIZED_VALUE) {
                // TODO ??
            } else if (value.isReference()) {
                mv.visitVarInsn(ALOAD, stackRecorderVar);
                mv.visitInsn(SWAP);
                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, PUSH_METHOD + "Object",
                        "(Ljava/lang/Object;)V", false);
            } else {
                Type type = value.getType();
                if (type.getSize() > 1) {
                    mv.visitInsn(ACONST_NULL); // dummy stack entry
                    mv.visitVarInsn(ALOAD, stackRecorderVar);
                    mv.visitInsn(DUP2_X2); // swap2 for long/double
                    mv.visitInsn(POP2);
                    mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPushMethod(type),
                            "(" + type.getDescriptor() + ")V", false);
                    mv.visitInsn(POP); // remove dummy stack entry
                } else {
                    mv.visitVarInsn(ALOAD, stackRecorderVar);
                    mv.visitInsn(SWAP);
                    mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPushMethod(type),
                            "(" + type.getDescriptor() + ")V", false);
                }
            }
        }

        if (!isStatic) {
            //RS:
            if (canalyzer._continueReflection && name.equals("invoke")
                    && owner.startsWith("java/lang/reflect/Method")) {
                mv.visitVarInsn(ALOAD, stackRecorderVar);
                ContinuationMethodAnalyzer.MyVariables vars = canalyzer._reflectMapping
                        .get(nodes.get(currentIndex));
                //               System.out.println("Class:" + canalyzer.className + "method:" + stackRecorderVar + ":" + name + ":" + owner + ":" + desc + ":" + vars.methodVar());
                mv.visitVarInsn(ALOAD, vars.methodVar());
                //mv.visitVarInsn(ALOAD, 3);
                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "replace" + "Reference",
                        "(Ljava/lang/Object;)V", false);
            }
            //RS:
            mv.visitVarInsn(ALOAD, stackRecorderVar);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, PUSH_METHOD + "Reference",
                    "(Ljava/lang/Object;)V", false);
        }

        // save locals
        int fsize = currentFrame.getLocals();
        for (int j = 0; j < fsize; j++) {
            BasicValue value = (BasicValue) currentFrame.getLocal(j);
            if (isNull(value)) {
                // no need to save null
            } else if (value == BasicValue.UNINITIALIZED_VALUE) {
                // no need to save uninitialized objects
            } else if (value.isReference()) {
                mv.visitVarInsn(ALOAD, stackRecorderVar);
                mv.visitVarInsn(ALOAD, j);
                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, PUSH_METHOD + "Object",
                        "(Ljava/lang/Object;)V", false);
            } else {
                mv.visitVarInsn(ALOAD, stackRecorderVar);
                Type type = value.getType();
                mv.visitVarInsn(type.getOpcode(ILOAD), j);
                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPushMethod(type),
                        "(" + type.getDescriptor() + ")V", false);
            }
        }

        mv.visitVarInsn(ALOAD, stackRecorderVar);
        if (currentIndex >= 128) {
            // if > 127 then it's a SIPUSH, not a BIPUSH...
            mv.visitIntInsn(SIPUSH, currentIndex);
        } else {
            // TODO optimize to iconst_0...
            mv.visitIntInsn(BIPUSH, currentIndex);
        }
        mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "pushInt", "(I)V", false);

        if (currentFrame instanceof MonitoringFrame) {
            int[] monitoredLocals = ((MonitoringFrame) currentFrame).getMonitored();
            // System.out.println(System.identityHashCode(currentFrame)+" Monitored locals "+monitoredLocals.length);
            for (int monitoredLocal : monitoredLocals) {
                // System.out.println(System.identityHashCode(currentFrame)+" Monitored local "+monitoredLocals[j]);
                mv.visitVarInsn(ALOAD, monitoredLocal);
                mv.visitInsn(MONITOREXIT);
            }
        }

        Type methodReturnType = Type.getReturnType(methodDesc);
        pushDefault(methodReturnType);
        mv.visitInsn(methodReturnType.getOpcode(IRETURN));
        mv.visitLabel(fl);

        currentIndex++;
        currentFrame = null;
    }
}