use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project kotlin by JetBrains.
the class RedundantBoxingMethodTransformer method getValuesStoredOrLoadedToVariable.
@NotNull
private static List<BasicValue> getValuesStoredOrLoadedToVariable(@NotNull LocalVariableNode localVariableNode, @NotNull MethodNode node, @NotNull Frame<BasicValue>[] frames) {
List<BasicValue> values = new ArrayList<BasicValue>();
InsnList insnList = node.instructions;
int from = insnList.indexOf(localVariableNode.start) + 1;
int to = insnList.indexOf(localVariableNode.end) - 1;
Frame<BasicValue> frameForFromInstr = frames[from];
if (frameForFromInstr != null) {
BasicValue localVarValue = frameForFromInstr.getLocal(localVariableNode.index);
if (localVarValue != null) {
values.add(localVarValue);
}
}
for (int i = from; i <= to; i++) {
if (i < 0 || i >= insnList.size())
continue;
AbstractInsnNode insn = insnList.get(i);
if ((insn.getOpcode() == Opcodes.ASTORE || insn.getOpcode() == Opcodes.ALOAD) && ((VarInsnNode) insn).var == localVariableNode.index) {
if (frames[i] == null) {
//unreachable code
continue;
}
if (insn.getOpcode() == Opcodes.ASTORE) {
values.add(frames[i].getStack(frames[i].getStackSize() - 1));
} else {
values.add(frames[i].getLocal(((VarInsnNode) insn).var));
}
}
}
return values;
}
use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project kotlin by JetBrains.
the class RedundantBoxingMethodTransformer method adaptLocalVariableTableForBoxedValues.
private static void adaptLocalVariableTableForBoxedValues(@NotNull MethodNode node, @NotNull Frame<BasicValue>[] frames) {
for (LocalVariableNode localVariableNode : node.localVariables) {
if (Type.getType(localVariableNode.desc).getSort() != Type.OBJECT) {
continue;
}
for (BasicValue value : getValuesStoredOrLoadedToVariable(localVariableNode, node, frames)) {
if (!(value instanceof BoxedBasicValue))
continue;
BoxedValueDescriptor descriptor = ((BoxedBasicValue) value).getDescriptor();
if (!descriptor.isSafeToRemove())
continue;
localVariableNode.desc = descriptor.getUnboxedType().getDescriptor();
}
}
}
use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project kotlin by JetBrains.
the class RedundantBoxingMethodTransformer method removeValuesClashingWithVariablesPass.
private static boolean removeValuesClashingWithVariablesPass(@NotNull RedundantBoxedValuesCollection values, @NotNull MethodNode node, @NotNull Frame<BasicValue>[] frames) {
boolean needToRepeat = false;
for (LocalVariableNode localVariableNode : node.localVariables) {
if (Type.getType(localVariableNode.desc).getSort() != Type.OBJECT) {
continue;
}
List<BasicValue> variableValues = getValuesStoredOrLoadedToVariable(localVariableNode, node, frames);
Collection<BasicValue> boxed = CollectionsKt.filter(variableValues, new Function1<BasicValue, Boolean>() {
@Override
public Boolean invoke(BasicValue value) {
return value instanceof BoxedBasicValue;
}
});
if (boxed.isEmpty())
continue;
BoxedValueDescriptor firstBoxed = ((BoxedBasicValue) boxed.iterator().next()).getDescriptor();
if (isUnsafeToRemoveBoxingForConnectedValues(variableValues, firstBoxed.getUnboxedType())) {
for (BasicValue value : variableValues) {
if (!(value instanceof BoxedBasicValue))
continue;
BoxedValueDescriptor descriptor = ((BoxedBasicValue) value).getDescriptor();
if (descriptor.isSafeToRemove()) {
values.remove(descriptor);
needToRepeat = true;
}
}
}
}
return needToRepeat;
}
use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project kotlin by JetBrains.
the class RedundantBoxingMethodTransformer method interpretPopInstructionsForBoxedValues.
private static void interpretPopInstructionsForBoxedValues(@NotNull RedundantBoxingInterpreter interpreter, @NotNull MethodNode node, @NotNull Frame<BasicValue>[] frames) {
for (int i = 0; i < node.instructions.size(); i++) {
AbstractInsnNode insn = node.instructions.get(i);
if ((insn.getOpcode() != Opcodes.POP && insn.getOpcode() != Opcodes.POP2) || frames[i] == null) {
continue;
}
BasicValue top = frames[i].getStack(frames[i].getStackSize() - 1);
interpreter.processPopInstruction(insn, top);
if (top.getSize() == 1 && insn.getOpcode() == Opcodes.POP2) {
interpreter.processPopInstruction(insn, frames[i].getStack(frames[i].getStackSize() - 2));
}
}
}
use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue in project intellij-community by JetBrains.
the class NegationInterpreter method naryOperation.
@Override
public BasicValue naryOperation(AbstractInsnNode insn, List<? extends BasicValue> values) throws AnalyzerException {
int opCode = insn.getOpcode();
int shift = opCode == INVOKESTATIC ? 0 : 1;
int origin = insnIndex(insn);
switch(opCode) {
case INVOKESPECIAL:
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
BasicValue receiver = values.get(0);
if (receiver instanceof NthParamValue) {
dereferencedParams[((NthParamValue) receiver).n] = true;
}
if (receiver instanceof Trackable) {
dereferencedValues[((Trackable) receiver).getOriginInsnIndex()] = true;
}
default:
}
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);
for (int i = shift; i < values.size(); i++) {
if (values.get(i) instanceof NthParamValue) {
int n = ((NthParamValue) values.get(i)).n;
if (opCode == INVOKEINTERFACE) {
notNullableParams[n] = true;
} else {
Set<ParamKey> npKeys = parameterFlow[n];
if (npKeys == null) {
npKeys = new HashSet<>();
parameterFlow[n] = npKeys;
}
npKeys.add(new ParamKey(method, i - shift, stable));
}
}
}
BasicValue receiver = null;
if (shift == 1) {
receiver = values.remove(0);
}
boolean thisCall = (opCode == INVOKEINTERFACE || opCode == INVOKEVIRTUAL) && receiver == ThisValue;
return new TrackableCallValue(origin, retType, method, values, stable, thisCall);
case MULTIANEWARRAY:
return new NotNullValue(super.naryOperation(insn, values).getType());
default:
}
return track(origin, super.naryOperation(insn, values));
}
Aggregations