package jadx.core.dex.instructions;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.utils.InstructionRemover;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import java.util.IdentityHashMap;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
public final class PhiInsn extends InsnNode {
private final Map<RegisterArg, BlockNode> blockBinds;
public PhiInsn(int regNum, int predecessors) {
super(InsnType.PHI, predecessors);
this.blockBinds = new IdentityHashMap<RegisterArg, BlockNode>(predecessors);
setResult(InsnArg.reg(regNum, ArgType.UNKNOWN));
add(AFlag.DONT_INLINE);
}
public RegisterArg bindArg(BlockNode pred) {
RegisterArg arg = InsnArg.reg(getResult().getRegNum(), getResult().getType());
bindArg(arg, pred);
return arg;
}
public void bindArg(RegisterArg arg, BlockNode pred) {
if (blockBinds.containsValue(pred)) {
throw new JadxRuntimeException("Duplicate predecessors in PHI insn: " + pred + ", " + this);
}
addArg(arg);
blockBinds.put(arg, pred);
}
public BlockNode getBlockByArg(RegisterArg arg) {
return blockBinds.get(arg);
}
public Map<RegisterArg, BlockNode> getBlockBinds() {
return blockBinds;
}
@Override
@NotNull
public RegisterArg getArg(int n) {
return (RegisterArg) super.getArg(n);
}
@Override
public boolean removeArg(InsnArg arg) {
if (!(arg instanceof RegisterArg)) {
return false;
}
RegisterArg reg = (RegisterArg) arg;
if (super.removeArg(reg)) {
blockBinds.remove(reg);
InstructionRemover.fixUsedInPhiFlag(reg);
return true;
}
return false;
}
@Override
public boolean replaceArg(InsnArg from, InsnArg to) {
if (!(from instanceof RegisterArg) || !(to instanceof RegisterArg)) {
return false;
}
BlockNode pred = getBlockByArg((RegisterArg) from);
if (pred == null) {
throw new JadxRuntimeException("Unknown predecessor block by arg " + from + " in PHI: " + this);
}
if (removeArg(from)) {
bindArg((RegisterArg) to, pred);
}
return true;
}
@Override
public void setArg(int n, InsnArg arg) {
throw new JadxRuntimeException("Unsupported operation for PHI node");
}
@Override
public String toString() {
return "PHI: " + getResult() + " = " + Utils.listToString(getArguments())
+ " binds: " + blockBinds;
}
}