core: fixed types for arguments from overloaded methods
This commit is contained in:
@@ -523,7 +523,29 @@ public class InsnGen {
|
||||
break;
|
||||
}
|
||||
code.add(callMth.getName());
|
||||
addArgs(code, insn, k);
|
||||
if (callMthNode != null && callMthNode.isArgsOverload()) {
|
||||
int argsCount = insn.getArgsCount();
|
||||
List<ArgType> originalType = callMth.getArgumentsTypes();
|
||||
int origPos = 0;
|
||||
|
||||
code.add('(');
|
||||
for (int i = k; i < argsCount; i++) {
|
||||
InsnArg arg = insn.getArg(i);
|
||||
ArgType origType = originalType.get(origPos);
|
||||
if (!arg.getType().equals(origType)) {
|
||||
code.add('(').add(useType(origType)).add(')').add(arg(arg));
|
||||
} else {
|
||||
code.add(arg(arg));
|
||||
}
|
||||
if (i < argsCount - 1) {
|
||||
code.add(", ");
|
||||
}
|
||||
origPos++;
|
||||
}
|
||||
code.add(')');
|
||||
} else {
|
||||
addArgs(code, insn, k);
|
||||
}
|
||||
}
|
||||
|
||||
private void inlineMethod(MethodNode callMthNode, InvokeNode insn, CodeWriter code) throws CodegenException {
|
||||
@@ -566,11 +588,14 @@ public class InsnGen {
|
||||
}
|
||||
|
||||
private void addArgs(CodeWriter code, InsnNode insn, int k) throws CodegenException {
|
||||
int argsCount = insn.getArgsCount();
|
||||
code.add('(');
|
||||
for (int i = k; i < insn.getArgsCount(); i++) {
|
||||
code.add(arg(insn, i));
|
||||
if (i < insn.getArgsCount() - 1)
|
||||
if (k < argsCount) {
|
||||
code.add(arg(insn, k));
|
||||
for (int i = k + 1; i < argsCount; i++) {
|
||||
code.add(", ");
|
||||
code.add(arg(insn, i));
|
||||
}
|
||||
}
|
||||
code.add(')');
|
||||
}
|
||||
|
||||
@@ -455,8 +455,23 @@ public class MethodNode extends LineAttrNode implements ILoadable {
|
||||
return exceptionHandlers;
|
||||
}
|
||||
|
||||
public boolean isMethodOverloaded() {
|
||||
// TODO
|
||||
/**
|
||||
* Return true if exists method with same name and arguments count
|
||||
*/
|
||||
public boolean isArgsOverload() {
|
||||
int argsCount = mthInfo.getArgumentsTypes().size();
|
||||
if (argsCount == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String name = getName();
|
||||
List<MethodNode> methods = parentClass.getMethods();
|
||||
for (MethodNode method : methods) {
|
||||
if (this != method
|
||||
&& method.getName().equals(name)
|
||||
&& method.mthInfo.getArgumentsTypes().size() == argsCount)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@ public class FinishTypeResolver extends AbstractVisitor {
|
||||
int i = 0;
|
||||
do {
|
||||
change = false;
|
||||
for (BlockNode block : mth.getBasicBlocks())
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
for (InsnNode insn : block.getInstructions())
|
||||
if (PostTypeResolver.visit(insn))
|
||||
if (PostTypeResolver.visit(mth, insn))
|
||||
change = true;
|
||||
|
||||
}
|
||||
i++;
|
||||
if (i > 1000)
|
||||
break;
|
||||
|
||||
+44
-17
@@ -1,35 +1,41 @@
|
||||
package jadx.core.dex.visitors.typeresolver.finish;
|
||||
|
||||
import jadx.core.dex.info.MethodInfo;
|
||||
import jadx.core.dex.instructions.IfNode;
|
||||
import jadx.core.dex.instructions.InvokeNode;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
import jadx.core.dex.instructions.args.LiteralArg;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PostTypeResolver {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PostTypeResolver.class);
|
||||
|
||||
public static boolean visit(InsnNode insn) {
|
||||
public static boolean visit(MethodNode mth, InsnNode insn) {
|
||||
switch (insn.getType()) {
|
||||
case CONST:
|
||||
if (insn.getArgsCount() > 0) {
|
||||
RegisterArg res = insn.getResult();
|
||||
LiteralArg litArg = (LiteralArg) insn.getArg(0);
|
||||
if (res.getType().isObject()) {
|
||||
long lit = litArg.getLiteral();
|
||||
if (lit != 0) {
|
||||
// incorrect literal value for object
|
||||
ArgType type = (lit == 1 ? ArgType.BOOLEAN : ArgType.INT);
|
||||
// can't merge with object -> force it
|
||||
litArg.getTypedVar().forceSetType(type);
|
||||
res.getTypedVar().forceSetType(type);
|
||||
return true;
|
||||
}
|
||||
RegisterArg res = insn.getResult();
|
||||
LiteralArg litArg = (LiteralArg) insn.getArg(0);
|
||||
if (res.getType().isObject()) {
|
||||
long lit = litArg.getLiteral();
|
||||
if (lit != 0) {
|
||||
// incorrect literal value for object
|
||||
ArgType type = (lit == 1 ? ArgType.BOOLEAN : ArgType.INT);
|
||||
// can't merge with object -> force it
|
||||
litArg.getTypedVar().forceSetType(type);
|
||||
res.getTypedVar().forceSetType(type);
|
||||
return true;
|
||||
}
|
||||
// return litArg.getTypedVar().forceSetType(res.getType());
|
||||
return litArg.merge(res);
|
||||
}
|
||||
break;
|
||||
// return litArg.getTypedVar().forceSetType(res.getType());
|
||||
return litArg.merge(res);
|
||||
|
||||
case MOVE: {
|
||||
boolean change = false;
|
||||
@@ -58,6 +64,27 @@ public class PostTypeResolver {
|
||||
return change;
|
||||
}
|
||||
|
||||
// check argument types for overloaded methods
|
||||
case INVOKE: {
|
||||
boolean change = false;
|
||||
InvokeNode inv = (InvokeNode) insn;
|
||||
MethodInfo callMth = inv.getCallMth();
|
||||
MethodNode node = mth.dex().resolveMethod(callMth);
|
||||
if (node != null && node.isArgsOverload()) {
|
||||
List<ArgType> args = callMth.getArgumentsTypes();
|
||||
int j = inv.getArgsCount() - 1;
|
||||
for (int i = args.size() - 1; i >= 0; i--) {
|
||||
ArgType argType = args.get(i);
|
||||
InsnArg insnArg = inv.getArg(j--);
|
||||
if (insnArg.isRegister() && !argType.equals(insnArg.getType())) {
|
||||
insnArg.getTypedVar().forceSetType(argType);
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user