提交 be9dae57 编写于 作者: S Skylot

fix: add explicit cast for byte literal in method invoke (#719)

上级 46290437
......@@ -8,4 +8,9 @@ public interface CallMthInterface {
MethodInfo getCallMth();
RegisterArg getInstanceArg();
/**
* Return offset to match method args from {@link #getCallMth()}
*/
int getFirstArgOffset();
}
......@@ -18,7 +18,7 @@ public class InvokeNode extends InsnNode implements CallMthInterface {
private final MethodInfo mth;
public InvokeNode(MethodInfo mth, DecodedInstruction insn, InvokeType type, boolean isRange, int resReg) {
super(InsnType.INVOKE, mth.getArgsCount() + (type != InvokeType.STATIC ? 1 : 0));
super(InsnType.INVOKE, mth.getArgsCount() + (type == InvokeType.STATIC ? 0 : 1));
this.mth = mth;
this.type = type;
......@@ -66,6 +66,11 @@ public class InvokeNode extends InsnNode implements CallMthInterface {
return null;
}
@Override
public int getFirstArgOffset() {
return type == InvokeType.STATIC ? 0 : 1;
}
@Override
public InsnNode copy() {
return copyCommonParams(new InvokeNode(mth, type, getArgsCount()));
......
......@@ -92,6 +92,11 @@ public class ConstructorInsn extends InsnNode implements CallMthInterface {
return callType == CallType.SELF;
}
@Override
public int getFirstArgOffset() {
return 0;
}
@Override
public boolean isSame(InsnNode obj) {
if (this == obj) {
......
......@@ -143,7 +143,7 @@ public class InsnNode extends LineAttrNode {
return arg;
}
protected int getArgIndex(InsnArg arg) {
public int getArgIndex(InsnArg arg) {
int count = getArgsCount();
for (int i = 0; i < count; i++) {
if (arg == arguments.get(i)) {
......
......@@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.List;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.CallMthInterface;
import jadx.core.dex.instructions.ConstStringNode;
import jadx.core.dex.instructions.IndexInsnNode;
import jadx.core.dex.instructions.InsnType;
......@@ -203,6 +205,10 @@ public class ConstInlineVisitor extends AbstractVisitor {
}
if (fieldNode != null) {
litArg.wrapInstruction(mth, new IndexInsnNode(InsnType.SGET, fieldNode.getFieldInfo(), 0));
} else {
if (needExplicitCast(useInsn, litArg)) {
litArg.add(AFlag.EXPLICIT_PRIMITIVE_TYPE);
}
}
} else {
if (!useInsn.replaceArg(arg, constArg.duplicate())) {
......@@ -214,4 +220,19 @@ public class ConstInlineVisitor extends AbstractVisitor {
}
return true;
}
private static boolean needExplicitCast(InsnNode insn, LiteralArg arg) {
if (insn instanceof CallMthInterface) {
CallMthInterface callInsn = (CallMthInterface) insn;
MethodInfo callMth = callInsn.getCallMth();
int offset = callInsn.getFirstArgOffset();
int argIndex = insn.getArgIndex(arg);
ArgType argType = callMth.getArgumentsTypes().get(argIndex - offset);
if (argType.isPrimitive()) {
arg.setType(argType);
return argType.equals(ArgType.BYTE);
}
}
return false;
}
}
......@@ -14,9 +14,9 @@ public class TestInnerEnums extends IntegrationTest {
public static class TestCls {
public enum Numbers {
ONE(1, NumString.ONE), TWO(2, NumString.TWO);
ONE((byte) 1, NumString.ONE), TWO((byte) 2, NumString.TWO);
private final int num;
private final byte num;
private final NumString str;
public enum NumString {
......@@ -33,7 +33,7 @@ public class TestInnerEnums extends IntegrationTest {
}
}
Numbers(int n, NumString str) {
Numbers(byte n, NumString str) {
this.num = n;
this.str = str;
}
......@@ -63,7 +63,7 @@ public class TestInnerEnums extends IntegrationTest {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, containsOne("ONE(1, NumString.ONE)"));
assertThat(code, containsOne("ONE((byte) 1, NumString.ONE)"));
assertThat(code, containsOne("ONE(\"one\")"));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册