Search in sources :

Example 1 with InOut

use of com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut in project intellij-community by JetBrains.

the class Analysis method createStartFrame.

final Frame<BasicValue> createStartFrame() {
    Frame<BasicValue> frame = new Frame<>(methodNode.maxLocals, methodNode.maxStack);
    Type returnType = Type.getReturnType(methodNode.desc);
    BasicValue returnValue = Type.VOID_TYPE.equals(returnType) ? null : new BasicValue(returnType);
    frame.setReturn(returnValue);
    Type[] args = Type.getArgumentTypes(methodNode.desc);
    int local = 0;
    if ((methodNode.access & Opcodes.ACC_STATIC) == 0) {
        frame.setLocal(local++, new AbstractValues.NotNullValue(Type.getObjectType(controlFlow.className)));
    }
    for (int i = 0; i < args.length; i++) {
        BasicValue value;
        if (direction instanceof InOut && ((InOut) direction).paramIndex == i || direction instanceof In && ((In) direction).paramIndex == i) {
            value = new AbstractValues.ParamValue(args[i]);
        } else {
            value = new BasicValue(args[i]);
        }
        frame.setLocal(local++, value);
        if (args[i].getSize() == 2) {
            frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
        }
    }
    while (local < methodNode.maxLocals) {
        frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
    }
    return frame;
}
Also used : Frame(org.jetbrains.org.objectweb.asm.tree.analysis.Frame) Type(org.jetbrains.org.objectweb.asm.Type) In(com.intellij.codeInspection.bytecodeAnalysis.Direction.In) InOut(com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut) BasicValue(org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue)

Example 2 with InOut

use of com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut in project intellij-community by JetBrains.

the class InOutInterpreter method naryOperation.

@Override
public BasicValue naryOperation(AbstractInsnNode insn, List<? extends BasicValue> values) throws AnalyzerException {
    boolean propagate = resultOrigins[insns.indexOf(insn)];
    int opCode = insn.getOpcode();
    int shift = opCode == INVOKESTATIC ? 0 : 1;
    switch(opCode) {
        case INVOKESPECIAL:
        case INVOKEINTERFACE:
        case INVOKEVIRTUAL:
            if (nullAnalysis && values.get(0) instanceof ParamValue) {
                deReferenced = true;
                return super.naryOperation(insn, values);
            }
    }
    if (propagate) {
        switch(opCode) {
            case INVOKESTATIC:
            case INVOKESPECIAL:
            case INVOKEVIRTUAL:
            case INVOKEINTERFACE:
                boolean stable = opCode == INVOKESTATIC || opCode == INVOKESPECIAL;
                MethodInsnNode mNode = (MethodInsnNode) insn;
                Method method = new Method(mNode.owner, mNode.name, mNode.desc);
                Type retType = Type.getReturnType(mNode.desc);
                boolean isRefRetType = retType.getSort() == Type.OBJECT || retType.getSort() == Type.ARRAY;
                if (!Type.VOID_TYPE.equals(retType)) {
                    if (direction instanceof InOut) {
                        InOut inOut = (InOut) direction;
                        HashSet<Key> keys = new HashSet<>();
                        for (int i = shift; i < values.size(); i++) {
                            if (values.get(i) instanceof ParamValue) {
                                keys.add(new Key(method, new InOut(i - shift, inOut.inValue), stable));
                            }
                        }
                        if (isRefRetType) {
                            keys.add(new Key(method, Out, stable));
                        }
                        if (!keys.isEmpty()) {
                            return new CallResultValue(retType, keys);
                        }
                    } else if (isRefRetType) {
                        HashSet<Key> keys = new HashSet<>();
                        keys.add(new Key(method, Out, stable));
                        return new CallResultValue(retType, keys);
                    }
                }
                break;
            case MULTIANEWARRAY:
                return new NotNullValue(super.naryOperation(insn, values).getType());
            default:
        }
    }
    return super.naryOperation(insn, values);
}
Also used : Type(org.jetbrains.org.objectweb.asm.Type) InOut(com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut) HashSet(java.util.HashSet)

Aggregations

InOut (com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut)2 Type (org.jetbrains.org.objectweb.asm.Type)2 In (com.intellij.codeInspection.bytecodeAnalysis.Direction.In)1 HashSet (java.util.HashSet)1 BasicValue (org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue)1 Frame (org.jetbrains.org.objectweb.asm.tree.analysis.Frame)1