core: fix array type for new-array instruction (fix #50)
This commit is contained in:
@@ -20,6 +20,7 @@ import jadx.core.dex.instructions.IndexInsnNode;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
import jadx.core.dex.instructions.InvokeNode;
|
||||
import jadx.core.dex.instructions.InvokeType;
|
||||
import jadx.core.dex.instructions.NewArrayNode;
|
||||
import jadx.core.dex.instructions.SwitchNode;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.instructions.args.FieldArg;
|
||||
@@ -341,7 +342,7 @@ public class InsnGen {
|
||||
break;
|
||||
|
||||
case NEW_ARRAY: {
|
||||
ArgType arrayType = insn.getResult().getType();
|
||||
ArgType arrayType = ((NewArrayNode) insn).getArrayType();
|
||||
code.add("new ");
|
||||
useType(code, arrayType.getArrayRootElement());
|
||||
code.add('[');
|
||||
|
||||
@@ -3,11 +3,13 @@ package jadx.core.dex.instructions;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class FilledNewArrayNode extends InsnNode {
|
||||
|
||||
private final ArgType elemType;
|
||||
|
||||
public FilledNewArrayNode(ArgType elemType, int size) {
|
||||
public FilledNewArrayNode(@NotNull ArgType elemType, int size) {
|
||||
super(InsnType.FILLED_NEW_ARRAY, size);
|
||||
this.elemType = elemType;
|
||||
}
|
||||
|
||||
@@ -535,8 +535,9 @@ public class InsnDecoder {
|
||||
InsnArg.reg(insn, 0, dex.getType(insn.getIndex())));
|
||||
|
||||
case Opcodes.NEW_ARRAY:
|
||||
return insn(InsnType.NEW_ARRAY,
|
||||
InsnArg.reg(insn, 0, dex.getType(insn.getIndex())),
|
||||
ArgType arrType = dex.getType(insn.getIndex());
|
||||
return new NewArrayNode(arrType,
|
||||
InsnArg.reg(insn, 0, arrType),
|
||||
InsnArg.reg(insn, 1, ArgType.INT));
|
||||
|
||||
case Opcodes.FILL_ARRAY_DATA:
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package jadx.core.dex.instructions;
|
||||
|
||||
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.InsnNode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class NewArrayNode extends InsnNode {
|
||||
|
||||
private final ArgType arrType;
|
||||
|
||||
public NewArrayNode(@NotNull ArgType arrType, RegisterArg res, InsnArg size) {
|
||||
super(InsnType.NEW_ARRAY, 1);
|
||||
this.arrType = arrType;
|
||||
setResult(res);
|
||||
addArg(size);
|
||||
}
|
||||
|
||||
public ArgType getArrayType() {
|
||||
return arrType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSame(InsnNode obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof NewArrayNode) || !super.isSame(obj)) {
|
||||
return false;
|
||||
}
|
||||
NewArrayNode other = (NewArrayNode) obj;
|
||||
return arrType == other.arrType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " type: " + arrType;
|
||||
}
|
||||
}
|
||||
@@ -222,7 +222,9 @@ public class ConstInlinerVisitor extends AbstractVisitor {
|
||||
break;
|
||||
|
||||
case NEW_ARRAY:
|
||||
litArg.merge(ArgType.INT);
|
||||
if (litArg == insn.getArg(0)) {
|
||||
litArg.merge(ArgType.INT);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -12,6 +12,7 @@ import jadx.core.dex.instructions.FilledNewArrayNode;
|
||||
import jadx.core.dex.instructions.IndexInsnNode;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
import jadx.core.dex.instructions.InvokeNode;
|
||||
import jadx.core.dex.instructions.NewArrayNode;
|
||||
import jadx.core.dex.instructions.SwitchNode;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
@@ -108,7 +109,8 @@ public class ModVisitor extends AbstractVisitor {
|
||||
InsnNode ni = block.getInstructions().get(next);
|
||||
if (ni.getType() == InsnType.FILL_ARRAY) {
|
||||
ni.getResult().merge(insn.getResult());
|
||||
((FillArrayNode) ni).mergeElementType(insn.getResult().getType().getArrayElement());
|
||||
ArgType arrType = ((NewArrayNode) insn).getArrayType();
|
||||
((FillArrayNode) ni).mergeElementType(arrType.getArrayElement());
|
||||
remover.add(insn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import jadx.core.dex.instructions.FilledNewArrayNode;
|
||||
import jadx.core.dex.instructions.IndexInsnNode;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
import jadx.core.dex.instructions.InvokeNode;
|
||||
import jadx.core.dex.instructions.NewArrayNode;
|
||||
import jadx.core.dex.instructions.SwitchNode;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
@@ -70,19 +71,21 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
*/
|
||||
private static InsnNode processNewArray(MethodNode mth, List<InsnNode> instructions, int i,
|
||||
InstructionRemover remover) {
|
||||
InsnNode insn = instructions.get(i);
|
||||
InsnArg arg = insn.getArg(0);
|
||||
NewArrayNode newArrayInsn = (NewArrayNode) instructions.get(i);
|
||||
InsnArg arg = newArrayInsn.getArg(0);
|
||||
if (!arg.isLiteral()) {
|
||||
return null;
|
||||
}
|
||||
int len = (int) ((LiteralArg) arg).getLiteral();
|
||||
int size = instructions.size();
|
||||
if (len <= 0 || i + len >= size || instructions.get(i + len).getType() != InsnType.APUT) {
|
||||
if (len <= 0
|
||||
|| i + len >= size
|
||||
|| instructions.get(i + len).getType() != InsnType.APUT) {
|
||||
return null;
|
||||
}
|
||||
ArgType arrType = insn.getResult().getType();
|
||||
ArgType arrType = newArrayInsn.getArrayType();
|
||||
InsnNode filledArr = new FilledNewArrayNode(arrType.getArrayElement(), len);
|
||||
filledArr.setResult(insn.getResult());
|
||||
filledArr.setResult(newArrayInsn.getResult());
|
||||
for (int j = 0; j < len; j++) {
|
||||
InsnNode put = instructions.get(i + 1 + j);
|
||||
if (put.getType() != InsnType.APUT) {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package jadx.tests.integration.arrays;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static jadx.tests.api.utils.JadxMatchers.containsOne;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class TestArrays3 extends IntegrationTest {
|
||||
public static class TestCls {
|
||||
|
||||
private Object test(byte[] bArr) {
|
||||
return new Object[]{bArr};
|
||||
}
|
||||
|
||||
public void check() {
|
||||
assertThat(test(new byte[]{1, 2}), instanceOf(Object[].class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
noDebugInfo();
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("return new Object[]{bArr};"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user