Example usage for org.objectweb.asm Frame getLocal

List of usage examples for org.objectweb.asm Frame getLocal

Introduction

In this page you can find the example usage for org.objectweb.asm Frame getLocal.

Prototype

private int getLocal(final int localIndex) 

Source Link

Document

Returns the abstract type stored at the given local variable index in the output frame.

Usage

From source file:jaspex.speculation.newspec.FlowFrame.java

License:Open Source License

private static Object[] locals(Frame<BasicValue> currentFrame) {
    UtilList<BasicValue> localsValues = new UtilArrayList<BasicValue>();
    for (int i = 0; i < currentFrame.getLocals(); i++) {
        localsValues.add(currentFrame.getLocal(i));
    }//  w w  w  . j  a v  a 2  s .c  o  m
    return convertToFrame(localsValues, true);
}

From source file:kilim.analysis.CallWeaver.java

License:Open Source License

/**
 * The basic block's frame tells us the number of parameters in the stack
 * and which local variables are needed later on.
 * /*  w  w  w . j ava 2s  .  com*/
 * If the method is pausable, we'll need the bottom part of the stack and
 * the object reference from the top part of the stack to be able to resume
 * it. We don't need to worry about the arguments, because they will be
 * saved (if needed) in the _called_ method's state.
 * 
 * The "this" arg (var0) is given special treatment. It is always saved in
 * all states, so it doesn't count as "data".
 */
private void assignRegisters() {
    Frame f = bb.startFrame;
    MethodWeaver mw = methodWeaver;
    varUsage.set(mw.getFiberVar());
    numVars = mw.getFiberVar() + 1; // knowing fiberVar is beyond anything
                                    // that's used
    mw.ensureMaxVars(numVars);
    Usage u = bb.usage;
    valInfoList = new ValInfoList();

    /*
     * Create ValInfos for each Value that needs to be saved (all live-in
     * vars (except var 0, if not static) and all stack bottom vars count,
     * except if they are duplicates of earlier ones or are constants which
     * can be reproduced in bytecode itself.
     * 
     * Process local vars before the stack, so that we can figure out which
     * elements of the stack are duplicates. Saving the stack requires more
     * processing, and the more we can reduce it, the better.
     */

    // ensure we don't touch any of the locals in the range that the
    // original
    // code knows about.
    varUsage.set(0, f.getMaxLocals());

    int i = bb.flow.isStatic() ? 0 : 1;
    for (; i < f.getMaxLocals(); i++) {
        Value v = f.getLocal(i);
        if (u.isLiveIn(i)) {
            if (!(v.isConstant() || valInfoList.contains(v))) {
                ValInfo vi = new ValInfo(v);
                vi.var = i;
                valInfoList.add(vi);
            }
        }
    }

    /*
     * All stack values at the bottom (those not consumed by the called
     * method) will have to be saved, if they are are not already accounted
     * for or they are constants.
     */
    int numBottom = getNumBottom();
    for (i = 0; i < numBottom; i++) {
        Value v = f.getStack(i);
        if (!(v.isConstant() || valInfoList.contains(v))) {
            ValInfo vi = new ValInfo(v);
            valInfoList.add(vi);
        }
    }
    Collections.sort(valInfoList); // sorts by type and var
    int fieldNum = 0;
    for (ValInfo vi : valInfoList) {
        vi.fieldName = "f" + fieldNum++;
    }
}

From source file:kilim.analysis.CallWeaver.java

License:Open Source License

/**
 * <pre>// w  w w. j a  va2 s . c o m
 * 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);
}

From source file:kilim.analysis.CallWeaver.java

License:Open Source License

private void genRestoreVars(MethodVisitor mv, int stateVar) {
    Frame f = bb.startFrame;

    if (valInfoList.size() > 0) {
        // need to have state in a local variable
        loadVar(mv, TOBJECT, methodWeaver.getFiberVar());
        mv.visitFieldInsn(GETFIELD, FIBER_CLASS, "curState", D_STATE);
        if (!stateClassName.equals(STATE_CLASS)) {
            mv.visitTypeInsn(CHECKCAST, stateClassName);
        }//from   w w  w.j a  va2  s.  com
        storeVar(mv, TOBJECT, stateVar);
    }

    // no need to restore "this" if it's already there.
    Usage u = bb.usage;
    int len = f.getMaxLocals();
    int i = bb.flow.isStatic() ? 0 : 1;
    for (; i < len; i++) {
        if (!u.isLiveIn(i))
            continue;
        Value v = f.getLocal(i);
        int vmt = VMType.toVmType(v.getTypeDesc());
        if (v.isConstant()) {
            loadConstant(mv, v);
        } else {
            ValInfo vi = valInfoList.find(v);
            if (vi.var == i) {
                // load val from state
                loadVar(mv, TOBJECT, stateVar);
                mv.visitFieldInsn(GETFIELD, stateClassName, vi.fieldName, vi.fieldDesc());
                checkcast(mv, v); // don't need to do this in the constant case
            } else {
                // It is a duplicate of another var. No need to load this var from stack
                assert vi.var < i;
                loadVar(mv, vi.vmt, vi.var);
            }
        }
        // Convert types from vm types to value's real type, if necessary
        // store into local
        storeVar(mv, vmt, i);
    }
    releaseVar(stateVar, 1);
}