blob: 677d57aa34ca27340032f5aa8a3a4ee906c62217 [file] [log] [blame]
// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.smali;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
public class DexMoveInstructionsTest extends SmaliTestBase {
public static final String CLASS = "Test";
@Test
public void testValidObjectMoves() throws Throwable {
ProcessResult result = testMoves("ExpectedToPass", "Ljava/lang/String;", Arrays.asList(
"move-object",
"move-object/from16",
"move-object/16"));
assertEquals(result.toString(), 0, result.exitCode);
}
@Test
public void testInvalidObjectMoves() throws Throwable {
ProcessResult result = testMoves("ExpectedToFail", "Ljava/lang/String;", Arrays.asList(
"move",
"move/from16",
"move/16"));
assertEquals(result.toString(), 1, result.exitCode);
assertTrue("Did not find 'Verification error' in " + result.stderr,
result.stderr.contains("Verification error") || result.stderr.contains("VerifyError"));
}
@Test
public void testValidSingleMoves() throws Throwable {
ProcessResult result = testMoves("ExpectedToPass", "I", Arrays.asList(
"move",
"move/from16",
"move/16"));
assertEquals(result.toString(), 0, result.exitCode);
}
@Test
public void testInvalidSingleMoves() throws Throwable {
ProcessResult result = testMoves("ExpectedToFail", "I", Arrays.asList(
"move-object",
"move-object/from16",
"move-object/16"));
assertEquals(result.toString(), 1, result.exitCode);
assertTrue("Did not find 'Verification error' in " + result.stderr,
result.stderr.contains("Verification error") || result.stderr.contains("VerifyError"));
}
private ProcessResult testMoves(String clazz, String typeDesc, List<String> moveOps)
throws Throwable {
String typeName = DescriptorUtils.descriptorToJavaType(typeDesc);
SmaliBuilder builder = new SmaliBuilder(clazz);
int i = 0;
for (String moveOp : moveOps) {
builder.addStaticMethod(typeName, "test" + i++, Collections.singletonList(typeName),
1,
" " + moveOp + " v0, p0",
typeDesc.startsWith("L") ? "return-object v0" : " return v0"
);
}
List<String> main = new ArrayList<>();
main.add(" sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;");
main.add(" const v2, 0");
i = 0;
for (String moveOp : moveOps) {
main.add(" invoke-static { v2 }, L" + clazz + ";->test" + i++
+ "(" + typeDesc + ")" + typeDesc);
if (typeDesc.startsWith("L")) {
main.add(" move-result-object v1");
} else {
main.add(" move-result v1");
}
main.add(" invoke-virtual { v0, v1 }, Ljava/io/PrintStream;->print(" + typeDesc + ")V");
}
main.add(" return-void");
builder.addMainMethod(3, main.toArray(StringUtils.EMPTY_ARRAY));
return runOnArtRaw(builder.build(), clazz);
}
}