blob: 34e4f3ea6ab69fd01809a03643f8862352be99a6 [file] [log] [blame]
// Copyright (c) 2016, 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.regress;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.D8Command.Builder;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.origin.EmbeddedOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.smali.SmaliTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.util.Base64;
import java.util.Set;
import org.junit.Test;
public class Regress37740372 extends SmaliTestBase {
/*
Binary class file data for a java.lang.Object stub implementation. Runnong javap -c on the
bytecode produces the following output:
Compiled from "Object.java"
public class java.lang.Object {
public java.lang.Object();
Code:
0: new #1 // class java/lang/RuntimeException
3: dup
4: ldc #2 // String Stub!
6: invokespecial #3 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
9: athrow
protected java.lang.Object clone() throws java.lang.CloneNotSupportedException;
Code:
0: new #1 // class java/lang/RuntimeException
3: dup
4: ldc #2 // String Stub!
6: invokespecial #3 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
9: athrow
public boolean equals(java.lang.Object);
Code:
0: new #1 // class java/lang/RuntimeException
3: dup
4: ldc #2 // String Stub!
6: invokespecial #3 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
9: athrow
protected void finalize() throws java.lang.Throwable;
Code:
0: new #1 // class java/lang/RuntimeException
3: dup
4: ldc #2 // String Stub!
6: invokespecial #3 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
9: athrow
public final native java.lang.Class<?> getClass();
public native int hashCode();
public final native void notify();
public final native void notifyAll();
public java.lang.String toString();
Code:
0: new #1 // class java/lang/RuntimeException
3: dup
4: ldc #2 // String Stub!
6: invokespecial #3 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
9: athrow
public final void wait() throws java.lang.InterruptedException;
Code:
0: new #1 // class java/lang/RuntimeException
3: dup
4: ldc #2 // String Stub!
6: invokespecial #3 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
9: athrow
public final void wait(long) throws java.lang.InterruptedException;
Code:
0: new #1 // class java/lang/RuntimeException
3: dup
4: ldc #2 // String Stub!
6: invokespecial #3 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
9: athrow
public final native void wait(long, int) throws java.lang.InterruptedException;
}
*/
String javaLangObjectClassFile =
"yv66vgAAADEALwcAJwgAKAoAAQApBwAqAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1i" +
"ZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABJMamF2YS9sYW5nL09iamVjdDsB" +
"AAVjbG9uZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAKRXhjZXB0aW9ucwcAKwEABmVxdWFscwEA" +
"FShMamF2YS9sYW5nL09iamVjdDspWgEAAW8BAAhmaW5hbGl6ZQcALAEACGdldENsYXNzAQATKClM" +
"amF2YS9sYW5nL0NsYXNzOwEACVNpZ25hdHVyZQEAFigpTGphdmEvbGFuZy9DbGFzczwqPjsBAAho" +
"YXNoQ29kZQEAAygpSQEABm5vdGlmeQEACW5vdGlmeUFsbAEACHRvU3RyaW5nAQAUKClMamF2YS9s" +
"YW5nL1N0cmluZzsBAAR3YWl0BwAtAQAEKEopVgEABm1pbGxpcwEAAUoBAAUoSkkpVgEAClNvdXJj" +
"ZUZpbGUBAAtPYmplY3QuamF2YQEAGmphdmEvbGFuZy9SdW50aW1lRXhjZXB0aW9uAQAFU3R1YiEM" +
"AAUALgEAEGphdmEvbGFuZy9PYmplY3QBACRqYXZhL2xhbmcvQ2xvbmVOb3RTdXBwb3J0ZWRFeGNl" +
"cHRpb24BABNqYXZhL2xhbmcvVGhyb3dhYmxlAQAeamF2YS9sYW5nL0ludGVycnVwdGVkRXhjZXB0" +
"aW9uAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACEABAAAAAAAAAAMAAEABQAGAAEABwAAADQAAwAB" +
"AAAACrsAAVkSArcAA78AAAACAAgAAAAGAAEAAAAEAAkAAAAMAAEAAAAKAAoACwAAAAQADAANAAIA" +
"BwAAADQAAwABAAAACrsAAVkSArcAA78AAAACAAgAAAAGAAEAAAAFAAkAAAAMAAEAAAAKAAoACwAA" +
"AA4AAAAEAAEADwABABAAEQABAAcAAAA+AAMAAgAAAAq7AAFZEgK3AAO/AAAAAgAIAAAABgABAAAA" +
"BgAJAAAAFgACAAAACgAKAAsAAAAAAAoAEgALAAEABAATAAYAAgAHAAAANAADAAEAAAAKuwABWRIC" +
"twADvwAAAAIACAAAAAYAAQAAAAcACQAAAAwAAQAAAAoACgALAAAADgAAAAQAAQAUAREAFQAWAAEA" +
"FwAAAAIAGAEBABkAGgAAAREAGwAGAAABEQAcAAYAAAABAB0AHgABAAcAAAA0AAMAAQAAAAq7AAFZ" +
"EgK3AAO/AAAAAgAIAAAABgABAAAADAAJAAAADAABAAAACgAKAAsAAAARAB8ABgACAAcAAAA0AAMA" +
"AQAAAAq7AAFZEgK3AAO/AAAAAgAIAAAABgABAAAADQAJAAAADAABAAAACgAKAAsAAAAOAAAABAAB" +
"ACAAEQAfACEAAgAHAAAAPgADAAMAAAAKuwABWRICtwADvwAAAAIACAAAAAYAAQAAAA4ACQAAABYA" +
"AgAAAAoACgALAAAAAAAKACIAIwABAA4AAAAEAAEAIAERAB8AJAABAA4AAAAEAAEAIAABACUAAAAC" +
"ACY=";
private void assertIsJavaLangObjet(ClassSubject clazz) {
assertTrue(clazz.getOriginalDescriptor().equals("Ljava/lang/Object;"));
assertNull(clazz.getDexClass().superType);
}
private void checkApplicationOnlyHasJavaLangObject(AndroidApp app) throws Throwable {
CodeInspector inspector = new CodeInspector(app);
inspector.forAllClasses(this::assertIsJavaLangObjet);
}
static class MemoryConsumer extends DexIndexedConsumer.ForwardingConsumer {
byte[] data;
public MemoryConsumer() {
super(null);
}
@Override
public void accept(
int fileIndex, ByteDataView data, Set<String> descriptors, DiagnosticsHandler handler) {
assertEquals(0, fileIndex);
this.data = data.copyByteData();
}
}
@Test
public void test() throws Throwable {
// Build an application with the java.lang.Object stub from a class file.
MemoryConsumer consumer = new MemoryConsumer();
AndroidAppConsumers appConsumer = new AndroidAppConsumers();
D8.run(
D8Command.builder()
.setProgramConsumer(appConsumer.wrapProgramConsumer(consumer))
.addClassProgramData(
Base64.getDecoder().decode(javaLangObjectClassFile), EmbeddedOrigin.INSTANCE)
.build());
checkApplicationOnlyHasJavaLangObject(appConsumer.build());
// Build an application with the java.lang.Object stub from a dex file.
Builder builder = D8Command.builder();
builder.addDexProgramData(consumer.data, Origin.unknown());
appConsumer = new AndroidAppConsumers(builder);
D8.run(builder.build());
checkApplicationOnlyHasJavaLangObject(appConsumer.build());
}
}