use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project intellij-community by JetBrains.
the class InOutInterpreter method generalize.
private Conf generalize(Conf conf) {
Frame<BasicValue> frame = new Frame<>(conf.frame);
for (int i = generalizeShift; i < frame.getLocals(); i++) {
BasicValue value = frame.getLocal(i);
Class<?> valueClass = value.getClass();
if (valueClass != BasicValue.class && valueClass != ParamValue.class) {
frame.setLocal(i, new BasicValue(value.getType()));
}
}
BasicValue[] stack = new BasicValue[frame.getStackSize()];
for (int i = 0; i < frame.getStackSize(); i++) {
stack[i] = frame.getStack(i);
}
frame.clearStack();
for (BasicValue value : stack) {
Class<?> valueClass = value.getClass();
if (valueClass != BasicValue.class && valueClass != ParamValue.class) {
frame.push(new BasicValue(value.getType()));
} else {
frame.push(value);
}
}
return new Conf(conf.insnIndex, frame);
}
use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project intellij-community by JetBrains.
the class InOutInterpreter method processState.
void processState(State state) throws AnalyzerException {
Conf preConf = state.conf;
int insnIndex = preConf.insnIndex;
boolean loopEnter = dfsTree.loopEnters[insnIndex];
Conf conf = loopEnter ? generalize(preConf) : preConf;
List<Conf> history = state.history;
boolean taken = state.taken;
Frame<BasicValue> frame = conf.frame;
AbstractInsnNode insnNode = methodNode.instructions.get(insnIndex);
List<Conf> nextHistory = loopEnter ? append(history, conf) : history;
Frame<BasicValue> nextFrame = execute(frame, insnNode);
addComputed(insnIndex, state);
if (interpreter.deReferenced) {
return;
}
int opcode = insnNode.getOpcode();
switch(opcode) {
case ARETURN:
case IRETURN:
case LRETURN:
case FRETURN:
case DRETURN:
case RETURN:
BasicValue stackTop = popValue(frame);
Result subResult;
if (FalseValue == stackTop) {
subResult = new Final(Value.False);
} else if (TrueValue == stackTop) {
subResult = new Final(Value.True);
} else if (NullValue == stackTop) {
subResult = new Final(Value.Null);
} else if (stackTop instanceof NotNullValue) {
subResult = new Final(Value.NotNull);
} else if (stackTop instanceof ParamValue) {
subResult = new Final(inValue);
} else if (stackTop instanceof CallResultValue) {
Set<Key> keys = ((CallResultValue) stackTop).inters;
subResult = new Pending(Collections.singleton(new Product(Value.Top, keys)));
} else {
earlyResult = new Final(Value.Top);
return;
}
internalResult = resultUtil.join(internalResult, subResult);
if (internalResult instanceof Final && ((Final) internalResult).value == Value.Top) {
earlyResult = internalResult;
}
return;
case ATHROW:
return;
default:
}
if (opcode == IFNONNULL && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = inValue == Value.Null ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode) insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
pendingPush(nextState);
return;
}
if (opcode == IFNULL && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = inValue == Value.NotNull ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode) insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
pendingPush(nextState);
return;
}
if (opcode == IFEQ && popValue(frame) == InstanceOfCheckValue && inValue == Value.Null) {
int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode) insnNode).label);
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
pendingPush(nextState);
return;
}
if (opcode == IFNE && popValue(frame) == InstanceOfCheckValue && inValue == Value.Null) {
int nextInsnIndex = insnIndex + 1;
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
pendingPush(nextState);
return;
}
// general case
for (int nextInsnIndex : controlFlow.transitions[insnIndex]) {
Frame<BasicValue> nextFrame1 = nextFrame;
if (controlFlow.errors[nextInsnIndex] && controlFlow.errorTransitions.contains(new Edge(insnIndex, nextInsnIndex))) {
nextFrame1 = new Frame<>(frame);
nextFrame1.clearStack();
nextFrame1.push(ASMUtils.THROWABLE_VALUE);
}
pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame1), nextHistory, taken, false));
}
}
use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project intellij-community by JetBrains.
the class NullableInterpreter method processState.
private void processState(State state) throws AnalyzerException {
Conf conf = state.conf;
int insnIndex = conf.insnIndex;
List<Conf> history = state.history;
boolean taken = state.taken;
Frame<BasicValue> frame = conf.frame;
AbstractInsnNode insnNode = methodNode.instructions.get(insnIndex);
List<Conf> nextHistory = dfsTree.loopEnters[insnIndex] ? append(history, conf) : history;
addComputed(insnIndex, state);
execute(frame, insnNode, taken);
if (subResult == NPE || top) {
earlyResult = NPE;
return;
}
if (subResult instanceof ConditionalNPE) {
myResult = combineNullable(myResult, subResult);
}
int opcode = insnNode.getOpcode();
switch(opcode) {
case ARETURN:
if (popValue(frame) instanceof ParamValue) {
earlyResult = NPE;
}
return;
case IRETURN:
case LRETURN:
case FRETURN:
case DRETURN:
case RETURN:
return;
default:
}
if (opcode == ATHROW) {
if (taken) {
earlyResult = NPE;
}
return;
}
if (opcode == IFNONNULL && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = insnIndex + 1;
pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false));
return;
}
if (opcode == IFNULL && popValue(frame) instanceof ParamValue) {
int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode) insnNode).label);
pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false));
return;
}
if (opcode == IFEQ && popValue(frame) == InstanceOfCheckValue) {
int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode) insnNode).label);
pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false));
return;
}
if (opcode == IFNE && popValue(frame) == InstanceOfCheckValue) {
int nextInsnIndex = insnIndex + 1;
pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false));
return;
}
// general case
for (int nextInsnIndex : controlFlow.transitions[insnIndex]) {
Frame<BasicValue> nextFrame1 = nextFrame;
if (controlFlow.errors[nextInsnIndex] && controlFlow.errorTransitions.contains(new Edge(insnIndex, nextInsnIndex))) {
nextFrame1 = new Frame<>(frame);
nextFrame1.clearStack();
nextFrame1.push(ASMUtils.THROWABLE_VALUE);
}
pendingPush(new State(++id, new Conf(nextInsnIndex, nextFrame1), nextHistory, taken, false));
}
}
use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project intellij-community by JetBrains.
the class NullableMethodInterpreter method naryOperation.
@Override
public BasicValue naryOperation(AbstractInsnNode insn, List<? extends BasicValue> values) throws AnalyzerException {
int opCode = insn.getOpcode();
switch(opCode) {
case INVOKESPECIAL:
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
BasicValue receiver = values.get(0);
if (receiver instanceof Calls) {
delta = ((Calls) receiver).mergedLabels;
}
if (receiver instanceof LabeledNull) {
nullsDelta = ((LabeledNull) receiver).origins;
}
break;
default:
}
switch(opCode) {
case INVOKESTATIC:
case INVOKESPECIAL:
case INVOKEVIRTUAL:
int insnIndex = insns.indexOf(insn);
if (origins[insnIndex]) {
boolean stable = opCode == INVOKESTATIC || opCode == INVOKESPECIAL;
MethodInsnNode mNode = ((MethodInsnNode) insn);
Method method = new Method(mNode.owner, mNode.name, mNode.desc);
int label = 1 << originsMapping[insnIndex];
if (keys[insnIndex] == null) {
keys[insnIndex] = new Key(method, Direction.NullableOut, stable);
}
return new Calls(label);
}
break;
default:
}
return super.naryOperation(insn, values);
}
use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project intellij-community by JetBrains.
the class NullableInterpreter method naryOperation.
@Override
public BasicValue naryOperation(AbstractInsnNode insn, List<? extends BasicValue> values) throws AnalyzerException {
int opcode = insn.getOpcode();
boolean isStaticInvoke = opcode == INVOKESTATIC;
int shift = isStaticInvoke ? 0 : 1;
if ((opcode == INVOKESPECIAL || opcode == INVOKEINTERFACE || opcode == INVOKEVIRTUAL) && values.get(0) instanceof ParamValue) {
subResult = NPE;
}
switch(opcode) {
case INVOKEINTERFACE:
if (nullableAnalysis) {
for (int i = shift; i < values.size(); i++) {
if (values.get(i) instanceof ParamValue) {
top = true;
return super.naryOperation(insn, values);
}
}
}
break;
case INVOKESTATIC:
case INVOKESPECIAL:
case INVOKEVIRTUAL:
boolean stable = opcode == INVOKESTATIC || opcode == INVOKESPECIAL;
MethodInsnNode methodNode = (MethodInsnNode) insn;
Method method = new Method(methodNode.owner, methodNode.name, methodNode.desc);
for (int i = shift; i < values.size(); i++) {
BasicValue value = values.get(i);
if (value instanceof ParamValue || (NullValue == value && nullityMask == In.NULLABLE_MASK && "<init>".equals(methodNode.name))) {
subResult = combine(subResult, new ConditionalNPE(new Key(method, new In(i - shift, nullityMask), stable)));
}
}
break;
default:
}
return super.naryOperation(insn, values);
}
Aggregations