core: fix method inline
This commit is contained in:
@@ -13,13 +13,13 @@ import jadx.core.dex.visitors.IDexTreeVisitor;
|
||||
import jadx.core.dex.visitors.MethodInlineVisitor;
|
||||
import jadx.core.dex.visitors.ModVisitor;
|
||||
import jadx.core.dex.visitors.PrepareForCodeGen;
|
||||
import jadx.core.dex.visitors.ssa.SSATransform;
|
||||
import jadx.core.dex.visitors.SimplifyVisitor;
|
||||
import jadx.core.dex.visitors.regions.CheckRegions;
|
||||
import jadx.core.dex.visitors.regions.IfRegionVisitor;
|
||||
import jadx.core.dex.visitors.regions.ProcessVariables;
|
||||
import jadx.core.dex.visitors.regions.RegionMakerVisitor;
|
||||
import jadx.core.dex.visitors.ssa.EliminatePhiNodes;
|
||||
import jadx.core.dex.visitors.ssa.SSATransform;
|
||||
import jadx.core.dex.visitors.typeinference.FinishTypeInference;
|
||||
import jadx.core.dex.visitors.typeinference.TypeInference;
|
||||
import jadx.core.utils.Utils;
|
||||
|
||||
@@ -3,7 +3,6 @@ package jadx.core.codegen;
|
||||
import jadx.core.dex.attributes.AttributeFlag;
|
||||
import jadx.core.dex.attributes.AttributeType;
|
||||
import jadx.core.dex.attributes.FieldReplaceAttr;
|
||||
import jadx.core.dex.attributes.IAttribute;
|
||||
import jadx.core.dex.attributes.MethodInlineAttr;
|
||||
import jadx.core.dex.info.ClassInfo;
|
||||
import jadx.core.dex.info.FieldInfo;
|
||||
@@ -583,9 +582,7 @@ public class InsnGen {
|
||||
|
||||
// inline method
|
||||
MethodNode callMthNode = mth.dex().resolveMethod(callMth);
|
||||
if (callMthNode != null
|
||||
&& callMthNode.getAttributes().contains(AttributeType.METHOD_INLINE)) {
|
||||
inlineMethod(callMthNode, insn, code);
|
||||
if (callMthNode != null && inlineMethod(callMthNode, insn, code)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -662,9 +659,12 @@ public class InsnGen {
|
||||
}
|
||||
}
|
||||
|
||||
private void inlineMethod(MethodNode callMthNode, InvokeNode insn, CodeWriter code) throws CodegenException {
|
||||
IAttribute mia = callMthNode.getAttributes().get(AttributeType.METHOD_INLINE);
|
||||
InsnNode inl = ((MethodInlineAttr) mia).getInsn();
|
||||
private boolean inlineMethod(MethodNode callMthNode, InvokeNode insn, CodeWriter code) throws CodegenException {
|
||||
MethodInlineAttr mia = (MethodInlineAttr) callMthNode.getAttributes().get(AttributeType.METHOD_INLINE);
|
||||
if (mia == null) {
|
||||
return false;
|
||||
}
|
||||
InsnNode inl = mia.getInsn();
|
||||
if (callMthNode.getMethodInfo().getArgumentsTypes().isEmpty()) {
|
||||
makeInsn(inl, code, Flags.BODY_ONLY);
|
||||
} else {
|
||||
@@ -681,12 +681,13 @@ public class InsnGen {
|
||||
inl.getRegisterArgs(inlArgs);
|
||||
Map<RegisterArg, InsnArg> toRevert = new HashMap<RegisterArg, InsnArg>();
|
||||
for (RegisterArg r : inlArgs) {
|
||||
if (r.getRegNum() >= regs.length) {
|
||||
LOG.warn("Unknown register number {} in method call: {}, {}", r, callMthNode, mth);
|
||||
int regNum = r.getRegNum();
|
||||
if (regNum >= regs.length) {
|
||||
LOG.warn("Unknown register number {} in method call: {} from {}", r, callMthNode, mth);
|
||||
} else {
|
||||
InsnArg repl = regs[r.getRegNum()];
|
||||
InsnArg repl = regs[regNum];
|
||||
if (repl == null) {
|
||||
LOG.warn("Not passed register {} in method call: {}, {}", r, callMthNode, mth);
|
||||
LOG.warn("Not passed register {} in method call: {} from {}", r, callMthNode, mth);
|
||||
} else {
|
||||
inl.replaceArg(r, repl);
|
||||
toRevert.put(r, repl);
|
||||
@@ -694,11 +695,12 @@ public class InsnGen {
|
||||
}
|
||||
}
|
||||
makeInsn(inl, code, Flags.BODY_ONLY);
|
||||
// revert changes
|
||||
// revert changes in 'MethodInlineAttr'
|
||||
for (Map.Entry<RegisterArg, InsnArg> e : toRevert.entrySet()) {
|
||||
inl.replaceArg(e.getValue(), e.getKey());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void makeTernary(TernaryInsn insn, CodeWriter code, EnumSet<Flags> state) throws CodegenException {
|
||||
|
||||
@@ -81,15 +81,16 @@ public class InsnNode extends LineAttrNode {
|
||||
arguments.set(n, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace instruction arg with another using recursive search.
|
||||
* <br>
|
||||
* <b>Caution:</b> this method don't change usage information for replaced argument.
|
||||
*/
|
||||
public boolean replaceArg(InsnArg from, InsnArg to) {
|
||||
int count = getArgsCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
InsnArg arg = arguments.get(i);
|
||||
if (arg == from) {
|
||||
if (arg.isRegister()) {
|
||||
RegisterArg registerArg = (RegisterArg) arg;
|
||||
registerArg.getSVar().removeUse(registerArg);
|
||||
}
|
||||
setArg(i, to);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public class MethodInlineVisitor extends AbstractVisitor {
|
||||
BlockNode block = mth.getBasicBlocks().get(1);
|
||||
InsnNode insn = block.getInstructions().get(0);
|
||||
InsnNode inl = new InsnNode(InsnType.ARGS, 1);
|
||||
// set arg from 'return' instruction
|
||||
inl.addArg(insn.getArg(0));
|
||||
addInlineAttr(mth, inl);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user