List of usage examples for org.objectweb.asm Frame getLocal
private int getLocal(final int localIndex)
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); }