Example usage for org.objectweb.asm Opcodes UNINITIALIZED_THIS

List of usage examples for org.objectweb.asm Opcodes UNINITIALIZED_THIS

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes UNINITIALIZED_THIS.

Prototype

Integer UNINITIALIZED_THIS

To view the source code for org.objectweb.asm Opcodes UNINITIALIZED_THIS.

Click Source Link

Usage

From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java

License:Open Source License

public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack,
        final Object[] stack) {
    if (type != Opcodes.F_NEW) { // uncompressed frame
        throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag");
    }/*from w  w w . j a v a2  s. c  o m*/

    // dumpFrame(nLocal, local, nStack, stack);

    // adjust the local types array

    int toRemove = localTypes.size();

    for (int i = toRemove; i > 0; i--) {
        localTypes.remove(i - 1);
    }

    int nextLocal = 0;

    for (int i = 0; i < nLocal; i++) {
        Object t = local[i];
        if (t == Opcodes.TOP) {
            localTypes.add(null);
        } else if (t == null) {
            localTypes.add(null);
        } else if (t == Opcodes.INTEGER) {
            localTypes.add(Type.INT_TYPE);
        } else if (t == Opcodes.FLOAT) {
            localTypes.add(Type.FLOAT_TYPE);
        } else if (t == Opcodes.DOUBLE) {
            localTypes.add(Type.DOUBLE_TYPE);
            nextLocal++;
            localTypes.add(null);
        } else if (t == Opcodes.LONG) {
            localTypes.add(Type.LONG_TYPE);
            nextLocal++;
            localTypes.add(null);
        } else if (t == Opcodes.NULL) {
            localTypes.add(null);
        } else if (t == Opcodes.UNINITIALIZED_THIS) {
            localTypes.add(null);
        } else if (t instanceof String) {
            localTypes.add(Type.getObjectType((String) t));
        } else {
            localTypes.add(null);
        }
        nextLocal++;
    }

    this.nextLocal = nextLocal;

    mv.visitFrame(type, nLocal, local, nStack, stack);
}

From source file:org.spongepowered.asm.util.Locals.java

License:MIT License

/**
 * <p>Attempts to identify available locals at an arbitrary point in the
 * bytecode specified by node.</p>
 * /*from   w w w  .  ja  v  a2 s.  com*/
 * <p>This method builds an approximate view of the locals available at an
 * arbitrary point in the bytecode by examining the following features in
 * the bytecode:</p> 
 * <ul>
 *   <li>Any available stack map frames</li>
 *   <li>STORE opcodes</li>
 *   <li>The local variable table</li>
 * </ul>
 * 
 * <p>Inference proceeds by walking the bytecode from the start of the
 * method looking for stack frames and STORE opcodes. When either of these
 * is encountered, an attempt is made to cross-reference the values in the
 * stack map or STORE opcode with the value in the local variable table
 * which covers the code range. Stack map frames overwrite the entire
 * simulated local variable table with their own value types, STORE opcodes
 * overwrite only the local slot to which they pertain. Values in the
 * simulated locals array are spaced according to their size (unlike the
 * representation in FrameNode) and this TOP, NULL and UNINTITIALIZED_THIS
 * opcodes will be represented as null values in the simulated frame.</p>
 * 
 * <p>This code does not currently simulate the prescribed JVM behaviour
 * where overwriting the second slot of a DOUBLE or LONG actually
 * invalidates the DOUBLE or LONG stored in the previous location, so we
 * have to hope (for now) that this behaviour isn't emitted by the compiler
 * or any upstream transformers. I may have to re-think this strategy if
 * this situation is encountered in the wild.</p>
 * 
 * @param classNode ClassNode containing the method, used to initialise the
 *      implicit "this" reference in simple methods with no stack frames
 * @param method MethodNode to explore
 * @param node Node indicating the position at which to determine the locals
 *      state. The locals will be enumerated UP TO the specified node, so
 *      bear in mind that if the specified node is itself a STORE opcode,
 *      then we will be looking at the state of the locals PRIOR to its
 *      invocation
 * @return A sparse array containing a view (hopefully) of the locals at the
 *      specified location
 */
public static LocalVariableNode[] getLocalsAt(ClassNode classNode, MethodNode method, AbstractInsnNode node) {
    LocalVariableNode[] frame = new LocalVariableNode[method.maxLocals];
    int local = 0, index = 0;

    // Initialise implicit "this" reference in non-static methods
    if ((method.access & Opcodes.ACC_STATIC) == 0) {
        frame[local++] = new LocalVariableNode("this", classNode.name, null, null, null, 0);
    }

    // Initialise method arguments
    for (Type argType : Type.getArgumentTypes(method.desc)) {
        frame[local] = new LocalVariableNode("arg" + index++, argType.toString(), null, null, null, local);
        local += argType.getSize();
    }

    for (Iterator<AbstractInsnNode> iter = method.instructions.iterator(); iter.hasNext();) {
        AbstractInsnNode insn = iter.next();
        if (insn instanceof FrameNode) {
            FrameNode frameNode = (FrameNode) insn;

            // localPos tracks the location in the frame node's locals list, which doesn't leave space for TOP entries
            for (int localPos = 0, framePos = 0; framePos < frame.length; framePos++, localPos++) {
                // Get the local at the current position in the FrameNode's locals list
                final Object localType = (localPos < frameNode.local.size()) ? frameNode.local.get(localPos)
                        : null;

                if (localType instanceof String) { // String refers to a reference type
                    frame[framePos] = Locals.getLocalVariableAt(classNode, method, node, framePos);
                } else if (localType instanceof Integer) { // Integer refers to a primitive type or other marker
                    boolean isMarkerType = localType == Opcodes.UNINITIALIZED_THIS || localType == Opcodes.TOP
                            || localType == Opcodes.NULL;
                    boolean is32bitValue = localType == Opcodes.INTEGER || localType == Opcodes.FLOAT;
                    boolean is64bitValue = localType == Opcodes.DOUBLE || localType == Opcodes.LONG;
                    if (isMarkerType) {
                        frame[framePos] = null;
                    } else if (is32bitValue || is64bitValue) {
                        frame[framePos] = Locals.getLocalVariableAt(classNode, method, node, framePos);

                        if (is64bitValue) {
                            framePos++;
                            frame[framePos] = null; // TOP
                        }
                    } else {
                        throw new RuntimeException(
                                "Unrecognised locals opcode " + localType + " in locals array at position "
                                        + localPos + " in " + classNode.name + "." + method.name + method.desc);
                    }
                } else if (localType == null) {
                    frame[framePos] = null;
                } else {
                    throw new RuntimeException("Invalid value " + localType + " in locals array at position "
                            + localPos + " in " + classNode.name + "." + method.name + method.desc);
                }
            }
        } else if (insn instanceof VarInsnNode) {
            VarInsnNode varNode = (VarInsnNode) insn;
            frame[varNode.var] = Locals.getLocalVariableAt(classNode, method, node, varNode.var);
        } else if (insn == node) {
            break;
        }
    }

    return frame;
}