fix: inline constants in chained move instructions (#399)

This commit is contained in:
Skylot
2018-12-01 13:28:28 +03:00
parent 21e11c1d47
commit 95f9ab035d
4 changed files with 177 additions and 54 deletions
@@ -24,6 +24,10 @@ public abstract class SmaliTest extends IntegrationTest {
return getClassNodeFromSmali(path + File.separatorChar + clsName, clsName);
}
protected ClassNode getClassNodeFromSmaliWithPkg(String pkg, String clsName) {
return getClassNodeFromSmali(pkg + File.separatorChar + clsName, pkg + '.' + clsName);
}
protected ClassNode getClassNodeFromSmali(String clsName) {
return getClassNodeFromSmali(clsName, clsName);
}
@@ -0,0 +1,38 @@
package jadx.tests.integration.types;
import org.junit.Test;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.SmaliTest;
import static jadx.tests.api.utils.JadxMatchers.containsOne;
import static org.junit.Assert.assertThat;
public class TestConstInline extends SmaliTest {
// private static String test(boolean b) {
// List<String> list;
// String str;
// if (b) {
// list = Collections.emptyList();
// str = "1";
// } else {
// list = null;
// str = list; // not correct assign in java but bytecode allow it
// }
// return use(list, str);
// }
//
// private static String use(List<String> list, String str) {
// return list + str;
// }
@Test
public void test() {
ClassNode cls = getClassNodeFromSmaliWithPkg("types", "TestConstInline");
String code = cls.getCode().toString();
assertThat(code, containsOne("list = null;"));
assertThat(code, containsOne("str = null;"));
}
}
@@ -0,0 +1,72 @@
.class public Ltypes/TestConstInline;
.super Ljava/lang/Object;
.method private static test(Z)Ljava/lang/String;
.registers 4
.param p0, "b" # Z
if-eqz p0, :cond_d
invoke-static {}, Ltypes/TestConstInline;->list()Ljava/util/List;
move-result-object v0
const-string v1, "1"
goto :goto_return
:cond_d
const/4 v2, 0x0
# chained move instead zero const loading
move v0, v2
move v1, v0
goto :goto_return
:goto_return
invoke-static {v0, v1}, Ltypes/TestConstInline;->use(Ljava/util/List;Ljava/lang/String;)Ljava/lang/String;
move-result-object v2
return-object v2
.end method
.method private static use(Ljava/util/List;Ljava/lang/String;)Ljava/lang/String;
.registers 3
.annotation system Ldalvik/annotation/Signature;
value = {
"(",
"Ljava/util/List",
"<",
"Ljava/lang/String;",
">;",
"Ljava/lang/String;",
")",
"Ljava/lang/String;"
}
.end annotation
new-instance v0, Ljava/lang/StringBuilder;
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
invoke-virtual {v0, p0}, Ljava/lang/StringBuilder;->append(Ljava/lang/Object;)Ljava/lang/StringBuilder;
move-result-object v0
invoke-virtual {v0, p1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v0
return-object v0
.end method
.method private static list()Ljava/util/List;
.registers 1
.annotation system Ldalvik/annotation/Signature;
value = {
"()",
"Ljava/util/List",
"<",
"Ljava/lang/String;",
">;"
}
.end annotation
invoke-static {}, Ljava/util/Collections;->emptyList()Ljava/util/List;
move-result-object v0
return-object v0
.end method