use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class ProcessVariables method visit.
@Override
public void visit(MethodNode mth) throws JadxException {
if (mth.isNoCode()) {
return;
}
final Map<Variable, Usage> usageMap = new LinkedHashMap<Variable, Usage>();
for (RegisterArg arg : mth.getArguments(true)) {
addToUsageMap(arg, usageMap);
}
// collect all variables usage
IRegionVisitor collect = new CollectUsageRegionVisitor(usageMap);
DepthRegionTraversal.traverse(mth, collect);
// reduce assigns map
List<RegisterArg> mthArgs = mth.getArguments(true);
for (RegisterArg arg : mthArgs) {
usageMap.remove(new Variable(arg));
}
Iterator<Entry<Variable, Usage>> umIt = usageMap.entrySet().iterator();
while (umIt.hasNext()) {
Entry<Variable, Usage> entry = umIt.next();
Usage u = entry.getValue();
// if no assigns => remove
if (u.getAssigns().isEmpty()) {
umIt.remove();
continue;
}
// variable declared at 'catch' clause
InsnNode parentInsn = u.getArg().getParentInsn();
if (parentInsn == null || parentInsn.getType() == InsnType.MOVE_EXCEPTION) {
umIt.remove();
}
}
if (usageMap.isEmpty()) {
return;
}
Map<IContainer, Integer> regionsOrder = new HashMap<IContainer, Integer>();
calculateOrder(mth.getRegion(), regionsOrder, 0, true);
for (Iterator<Entry<Variable, Usage>> it = usageMap.entrySet().iterator(); it.hasNext(); ) {
Entry<Variable, Usage> entry = it.next();
Usage u = entry.getValue();
// check if variable can be declared at current assigns
for (IRegion assignRegion : u.getAssigns()) {
if (u.getArgRegion() == assignRegion && canDeclareInRegion(u, assignRegion, regionsOrder)) {
if (declareAtAssign(u)) {
it.remove();
break;
}
}
}
}
if (usageMap.isEmpty()) {
return;
}
// apply
for (Entry<Variable, Usage> entry : usageMap.entrySet()) {
Usage u = entry.getValue();
// find region which contain all usage regions
Set<IRegion> set = u.getUseRegions();
for (Iterator<IRegion> it = set.iterator(); it.hasNext(); ) {
IRegion r = it.next();
IRegion parent = r.getParent();
if (parent != null && set.contains(parent)) {
it.remove();
}
}
IRegion region = null;
if (!set.isEmpty()) {
region = set.iterator().next();
} else if (!u.getAssigns().isEmpty()) {
region = u.getAssigns().iterator().next();
}
if (region == null) {
continue;
}
IRegion parent = region;
boolean declared = false;
while (parent != null) {
if (canDeclareInRegion(u, region, regionsOrder)) {
declareVar(region, u.getArg());
declared = true;
break;
}
region = parent;
parent = region.getParent();
}
if (!declared) {
declareVar(mth.getRegion(), u.getArg());
}
}
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class ProcessVariables method declareAtAssign.
private static boolean declareAtAssign(Usage u) {
RegisterArg arg = u.getArg();
InsnNode parentInsn = arg.getParentInsn();
if (!arg.equals(parentInsn.getResult())) {
return false;
}
parentInsn.add(AFlag.DECLARE_VAR);
return true;
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class BlockExceptionHandler method markExceptionHandlers.
/**
* Set exception handler attribute for whole block
*/
private static void markExceptionHandlers(BlockNode block) {
if (block.getInstructions().isEmpty()) {
return;
}
InsnNode me = block.getInstructions().get(0);
ExcHandlerAttr handlerAttr = me.get(AType.EXC_HANDLER);
if (handlerAttr == null || me.getType() != InsnType.MOVE_EXCEPTION) {
return;
}
ExceptionHandler excHandler = handlerAttr.getHandler();
block.addAttr(handlerAttr);
// set correct type for 'move-exception' operation
ArgType type = excHandler.isCatchAll() ? ArgType.THROWABLE : excHandler.getCatchType().getType();
RegisterArg resArg = me.getResult();
resArg = InsnArg.reg(resArg.getRegNum(), type);
me.setResult(resArg);
me.add(AFlag.DONT_INLINE);
excHandler.setArg(resArg);
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class ModVisitor method removeAssignChain.
/**
* Remove instructions on 'move' chain until instruction with type 'insnType'
*/
private static InsnNode removeAssignChain(InsnNode insn, InstructionRemover remover, InsnType insnType) {
if (insn == null) {
return null;
}
remover.add(insn);
InsnType type = insn.getType();
if (type == insnType) {
return insn;
}
if (type == InsnType.MOVE) {
RegisterArg arg = (RegisterArg) insn.getArg(0);
return removeAssignChain(arg.getAssignInsn(), remover, insnType);
}
return null;
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class ModVisitor method getArgsToFieldsMapping.
private static Map<InsnArg, FieldNode> getArgsToFieldsMapping(MethodNode callMthNode, ConstructorInsn co) {
Map<InsnArg, FieldNode> map = new LinkedHashMap<InsnArg, FieldNode>();
ClassNode parentClass = callMthNode.getParentClass();
List<RegisterArg> argList = callMthNode.getArguments(false);
int startArg = parentClass.getAccessFlags().isStatic() ? 0 : 1;
int argsCount = argList.size();
for (int i = startArg; i < argsCount; i++) {
RegisterArg arg = argList.get(i);
InsnNode useInsn = getParentInsnSkipMove(arg);
if (useInsn == null) {
return Collections.emptyMap();
}
FieldNode fieldNode = null;
if (useInsn.getType() == InsnType.IPUT) {
FieldInfo field = (FieldInfo) ((IndexInsnNode) useInsn).getIndex();
fieldNode = parentClass.searchField(field);
if (fieldNode == null || !fieldNode.getAccessFlags().isSynthetic()) {
return Collections.emptyMap();
}
} else if (useInsn.getType() == InsnType.CONSTRUCTOR) {
ConstructorInsn superConstr = (ConstructorInsn) useInsn;
if (!superConstr.isSuper()) {
return Collections.emptyMap();
}
} else {
return Collections.emptyMap();
}
map.put(co.getArg(i), fieldNode);
}
return map;
}
Aggregations