Example usage for org.objectweb.asm.tree AbstractInsnNode getOpcode

List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode getOpcode.

Prototype

public int getOpcode() 

Source Link

Document

Returns the opcode of this instruction.

Usage

From source file:nova.core.wrapper.mc.forge.v17.asm.lib.InstructionComparator.java

License:Open Source License

public static boolean methodInsnEqual(AbstractInsnNode absnode, int Opcode, ObfMapping method) {
    return absnode.getOpcode() == Opcode && absnode instanceof MethodInsnNode
            && method.matches((MethodInsnNode) absnode);
}

From source file:nova.core.wrapper.mc.forge.v17.asm.lib.InstructionComparator.java

License:Open Source License

public static boolean insnEqual(AbstractInsnNode node1, AbstractInsnNode node2) {
    if (node1.getOpcode() != node2.getOpcode()) {
        return false;
    }//w w w  .j  a v  a  2 s.  c o m

    switch (node2.getType()) {
    case VAR_INSN:
        return varInsnEqual((VarInsnNode) node1, (VarInsnNode) node2);
    case TYPE_INSN:
        return typeInsnEqual((TypeInsnNode) node1, (TypeInsnNode) node2);
    case FIELD_INSN:
        return fieldInsnEqual((FieldInsnNode) node1, (FieldInsnNode) node2);
    case METHOD_INSN:
        return methodInsnEqual((MethodInsnNode) node1, (MethodInsnNode) node2);
    case LDC_INSN:
        return ldcInsnEqual((LdcInsnNode) node1, (LdcInsnNode) node2);
    case IINC_INSN:
        return iincInsnEqual((IincInsnNode) node1, (IincInsnNode) node2);
    case INT_INSN:
        return intInsnEqual((IntInsnNode) node1, (IntInsnNode) node2);
    default:
        return true;
    }
}

From source file:org.apache.commons.javaflow.providers.asm3.ContinuableMethodNode.java

License:Apache License

void moveNew() throws AnalyzerException {
    final SourceInterpreter i = new SourceInterpreter();
    final Analyzer a = new Analyzer(i);
    a.analyze(className, this);

    final HashMap<AbstractInsnNode, MethodInsnNode> movable = new HashMap<AbstractInsnNode, MethodInsnNode>();

    final Frame[] frames = a.getFrames();
    for (int j = 0; j < methods.size(); j++) {
        final MethodInsnNode mnode = (MethodInsnNode) methods.get(j);
        // require to move NEW instruction
        int n = instructions.indexOf(mnode);
        Frame f = frames[n];/*from  w  ww .j a va  2 s.co  m*/
        Type[] args = Type.getArgumentTypes(mnode.desc);

        SourceValue v = (SourceValue) f.getStack(f.getStackSize() - args.length - 1);
        @SuppressWarnings("unchecked")
        Set<AbstractInsnNode> insns = v.insns;
        for (final AbstractInsnNode ins : insns) {
            if (ins.getOpcode() == NEW) {
                movable.put(ins, mnode);
            } else {
                // other known patterns
                int n1 = instructions.indexOf(ins);
                if (ins.getOpcode() == DUP) { // <init> with params
                    AbstractInsnNode ins1 = instructions.get(n1 - 1);
                    if (ins1.getOpcode() == NEW) {
                        movable.put(ins1, mnode);
                    }
                } else if (ins.getOpcode() == SWAP) { // in exception handler
                    AbstractInsnNode ins1 = instructions.get(n1 - 1);
                    AbstractInsnNode ins2 = instructions.get(n1 - 2);
                    if (ins1.getOpcode() == DUP_X1 && ins2.getOpcode() == NEW) {
                        movable.put(ins2, mnode);
                    }
                }
            }
        }
    }

    int updateMaxStack = 0;
    for (final Map.Entry<AbstractInsnNode, MethodInsnNode> e : movable.entrySet()) {
        AbstractInsnNode node1 = e.getKey();
        int n1 = instructions.indexOf(node1);
        AbstractInsnNode node2 = instructions.get(n1 + 1);
        AbstractInsnNode node3 = instructions.get(n1 + 2);
        int producer = node2.getOpcode();

        instructions.remove(node1); // NEW
        boolean requireDup = false;
        if (producer == DUP) {
            instructions.remove(node2); // DUP
            requireDup = true;
        } else if (producer == DUP_X1) {
            instructions.remove(node2); // DUP_X1
            instructions.remove(node3); // SWAP
            requireDup = true;
        }

        MethodInsnNode mnode = (MethodInsnNode) e.getValue();
        AbstractInsnNode nm = mnode;

        int varOffset = stackRecorderVar + 1;
        Type[] args = Type.getArgumentTypes(mnode.desc);

        // optimizations for some common cases
        if (args.length == 0) {
            final InsnList doNew = new InsnList();
            doNew.add(node1); // NEW
            if (requireDup)
                doNew.add(new InsnNode(DUP));
            instructions.insertBefore(nm, doNew);
            nm = doNew.getLast();
            continue;
        }

        if (args.length == 1 && args[0].getSize() == 1) {
            final InsnList doNew = new InsnList();
            doNew.add(node1); // NEW
            if (requireDup) {
                doNew.add(new InsnNode(DUP));
                doNew.add(new InsnNode(DUP2_X1));
                doNew.add(new InsnNode(POP2));
                updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values
            } else
                doNew.add(new InsnNode(SWAP));
            instructions.insertBefore(nm, doNew);
            nm = doNew.getLast();
            continue;
        }

        // TODO this one untested!
        if ((args.length == 1 && args[0].getSize() == 2)
                || (args.length == 2 && args[0].getSize() == 1 && args[1].getSize() == 1)) {
            final InsnList doNew = new InsnList();
            doNew.add(node1); // NEW
            if (requireDup) {
                doNew.add(new InsnNode(DUP));
                doNew.add(new InsnNode(DUP2_X2));
                doNew.add(new InsnNode(POP2));
                updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values
            } else {
                doNew.add(new InsnNode(DUP_X2));
                doNew.add(new InsnNode(POP));
                updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for temp value
            }
            instructions.insertBefore(nm, doNew);
            nm = doNew.getLast();
            continue;
        }

        final InsnList doNew = new InsnList();
        // generic code using temporary locals
        // save stack
        for (int j = args.length - 1; j >= 0; j--) {
            Type type = args[j];

            doNew.add(new VarInsnNode(type.getOpcode(ISTORE), varOffset));
            varOffset += type.getSize();
        }
        if (varOffset > maxLocals) {
            maxLocals = varOffset;
        }

        doNew.add(node1); // NEW

        if (requireDup)
            doNew.add(new InsnNode(DUP));

        // restore stack
        for (int j = 0; j < args.length; j++) {
            Type type = args[j];
            varOffset -= type.getSize();

            doNew.add(new VarInsnNode(type.getOpcode(ILOAD), varOffset));

            // clean up store to avoid memory leak?
            if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
                updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for ACONST_NULL

                doNew.add(new InsnNode(ACONST_NULL));

                doNew.add(new VarInsnNode(type.getOpcode(ISTORE), varOffset));
            }
        }
        instructions.insertBefore(nm, doNew);
        nm = doNew.getLast();
    }

    maxStack += updateMaxStack;
}

From source file:org.apache.commons.javaflow.providers.asm3.ContinuableMethodVisitor.java

License:Apache License

private static int getOwnerSize(final AbstractInsnNode node) {
    if (node instanceof MethodInsnNode) {
        return node.getOpcode() == INVOKESTATIC ? 0 : 1;
    } else {/*from  ww w .  ja  va  2 s .c o  m*/
        // INVOKEDYNAMIC
        return 0;
    }
}

From source file:org.apache.commons.javaflow.providers.asm3.ContinuableMethodVisitor.java

License:Apache License

public void visitCode() {
    mv.visitCode();/* w ww. j ava2s.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 + ";");
    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");
    mv.visitTableSwitchInsn(0, fsize - 1, l0, restoreLabels);

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

        AbstractInsnNode mnode = (AbstractInsnNode) nodes.get(i);
        //Frame frame = analyzer.getFrames()[methodNode.getIndex(mnode)];
        Frame frame = methodNode.getFrameByNode(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;");
                    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());
                    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 j = 0; j < monitoredLocals.length; j++) {
                //System.out.println(System.identityHashCode(frame)+" AMonitored local "+monitoredLocals[j]);
                mv.visitVarInsn(ALOAD, monitoredLocals[j]);
                mv.visitInsn(MONITORENTER);
            }
        }

        // stack
        final Type[] paramTypes = getArgumentTypes(mnode);
        int argSize = paramTypes.length;
        int ownerSize = getOwnerSize(mnode);
        int initSize = mnode.getOpcode() == INVOKESPECIAL
                && MethodInsnNode.class.cast(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;");
                mv.visitTypeInsn(CHECKCAST, value.getType().getInternalName());
            } else {
                Type type = value.getType();
                mv.visitVarInsn(ALOAD, stackRecorderVar);
                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPopMethod(type),
                        "()" + type.getDescriptor());
            }
        }

        if (ownerSize > 0) {
            // 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 {
                mv.visitVarInsn(ALOAD, stackRecorderVar);
                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Reference",
                        "()Ljava/lang/Object;");
                mv.visitTypeInsn(CHECKCAST, value.getType().getInternalName());
            }
        }

        // Create null types for the parameters of the method invocation

        for (int j = 0; j < argSize; j++) {
            pushDefault(paramTypes[j]);
        }

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

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

From source file:org.apache.commons.javaflow.providers.asm5.ContinuableMethodVisitor.java

License:Apache License

public void visitCode() {
    mv.visitCode();/*ww  w.ja v a 2s .  com*/

    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 = (Label) labels.get(i);
        mv.visitLabel(restoreLabels[i]);

        AbstractInsnNode mnode = (AbstractInsnNode) nodes.get(i);
        //Frame frame = analyzer.getFrames()[methodNode.getIndex(mnode)];
        Frame frame = methodNode.getFrameByNode(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 j = 0; j < monitoredLocals.length; j++) {
                //System.out.println(System.identityHashCode(frame)+" AMonitored local "+monitoredLocals[j]);
                mv.visitVarInsn(ALOAD, monitoredLocals[j]);
                mv.visitInsn(MONITORENTER);
            }
        }

        // stack
        final Type[] paramTypes = getArgumentTypes(mnode);
        int argSize = paramTypes.length;
        int ownerSize = getOwnerSize(mnode);
        int initSize = mnode.getOpcode() == INVOKESPECIAL
                && MethodInsnNode.class.cast(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);
            }
        }

        if (ownerSize > 0) {
            // 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 {
                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

        for (int j = 0; j < argSize; j++) {
            pushDefault(paramTypes[j]);
        }

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

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

From source file:org.apache.drill.exec.compile.bytecode.ReplacingInterpreter.java

License:Apache License

@Override
public BasicValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
    if (insn.getOpcode() == Opcodes.NEW) {
        TypeInsnNode t = (TypeInsnNode) insn;
        ValueHolderIden iden = HOLDERS.get(t.desc);

        if (iden != null) {
            return new ReplacingBasicValue(Type.getObjectType(t.desc), iden, index++);
        }// www .j av a2s .co m
    }

    return super.newOperation(insn);
}

From source file:org.apache.flink.api.java.sca.NestedMethodAnalyzer.java

License:Apache License

@Override
public BasicValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
    switch (insn.getOpcode()) {
    case ACONST_NULL:
        return new TaggedValue(Type.getObjectType("null"), Tag.NULL);
    case NEW:/*from  ww w  .j  a  va  2s .  co  m*/
        analyzer.incrNewOperationCounters(topLevelMethod);
        // make new objects a tagged value to have possibility to tag an 
        // input container later
        return new TaggedValue(Type.getObjectType(((TypeInsnNode) insn).desc));
    // tag "int"-like constants
    case BIPUSH:
    case SIPUSH:
        final IntInsnNode intInsn = (IntInsnNode) insn;
        return new TaggedValue(intInsn.operand);
    case LDC:
        final Object cst = ((LdcInsnNode) insn).cst;
        if (cst instanceof Integer) {
            return new TaggedValue((Integer) cst);
        }
        return super.newOperation(insn);
    case ICONST_M1:
        return new TaggedValue(-1);
    case ICONST_0:
        return new TaggedValue(0);
    case ICONST_1:
        return new TaggedValue(1);
    case ICONST_2:
        return new TaggedValue(2);
    case ICONST_3:
        return new TaggedValue(3);
    case ICONST_4:
        return new TaggedValue(4);
    case ICONST_5:
        return new TaggedValue(5);
    default:
        return super.newOperation(insn);
    }
}

From source file:org.apache.flink.api.java.sca.NestedMethodAnalyzer.java

License:Apache License

@Override
public BasicValue copyOperation(AbstractInsnNode insn, BasicValue value) throws AnalyzerException {
    switch (insn.getOpcode()) {
    case ILOAD://from w  w  w .  jav a 2s .co m
        // int constants are only supported if they are used in the subsequent operation
        // otherwise we can not guarantee that it isn't modified elsewhere (e.g. do-while loop)
        if (isTagged(value) && tagged(value).isIntConstant()) {
            tagged(value).makeRegular();
        }
        return super.copyOperation(insn, value);
    // if input is stored "call by value", it will be copied
    case ISTORE:
    case LSTORE:
    case FSTORE:
    case DSTORE:
    case ASTORE:
    case DUP:
    case DUP_X1:
    case DUP_X2:
    case DUP2:
    case DUP2_X1:
    case DUP2_X2:
        if (isTagged(value) && tagged(value).isInput() && tagged(value).isCallByValue()) {
            return tagged(value).copy();
        }
    default:
        return super.copyOperation(insn, value);
    }
}

From source file:org.apache.flink.api.java.sca.NestedMethodAnalyzer.java

License:Apache License

@Override
public BasicValue unaryOperation(AbstractInsnNode insn, BasicValue value) throws AnalyzerException {
    switch (insn.getOpcode()) {
    // modify jump instructions if we can assume that the hasNext operation will always
    // be true at the first call
    case IFEQ:/*from  ww w. ja  v a2 s . c  o m*/
        if (isTagged(value) && tagged(value).isIteratorTrueAssumption()) {
            modifiedAsmAnalyzer.requestIFEQLoopModification();
        }
        return super.unaryOperation(insn, value);
    case IFNE:
        if (isTagged(value) && tagged(value).isIteratorTrueAssumption()) {
            modifiedAsmAnalyzer.requestIFNELoopModification();
        }
        return super.unaryOperation(insn, value);

    case CHECKCAST:
        return value;
    case PUTSTATIC:
        analyzer.handlePutStatic();
        return super.unaryOperation(insn, value);
    case GETFIELD:
        final FieldInsnNode field = (FieldInsnNode) insn;
        // skip untagged values
        if (!isTagged(value)) {
            return super.unaryOperation(insn, value);
        }
        final TaggedValue taggedValue = (TaggedValue) value;

        // inputs are atomic, a GETFIELD results in undefined state
        if (taggedValue.isInput()) {
            return super.unaryOperation(insn, value);
        }
        // access of input container field
        // or access of a KNOWN UDF instance variable
        else if (taggedValue.canContainFields() && taggedValue.containerContains(field.name)) {
            final TaggedValue tv = taggedValue.getContainerMapping().get(field.name);
            if (tv != null) {
                return tv;
            }
        }
        // access of a yet UNKNOWN UDF instance variable
        else if (taggedValue.isThis() && !taggedValue.containerContains(field.name)) {
            final TaggedValue tv = new TaggedValue(Type.getType(field.desc));
            taggedValue.addContainerMapping(field.name, tv, currentFrame);
            return tv;
        }
        // access of a yet unknown container, mark it as a container
        else if (taggedValue.isRegular()) {
            taggedValue.setTag(Tag.CONTAINER);
            final TaggedValue tv = new TaggedValue(Type.getType(field.desc));
            taggedValue.addContainerMapping(field.name, tv, currentFrame);
            return tv;
        }
        return super.unaryOperation(insn, value);
    case IINC:
        // modification of a local variable or input
        if (isTagged(value) && (tagged(value).isIntConstant() || tagged(value).isInput())) {
            tagged(value).makeRegular();
        }
        return super.unaryOperation(insn, value);
    default:
        return super.unaryOperation(insn, value);
    }
}