/*
|
* Copyright 2017 The Android Open Source Project
|
*
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* you may not use this file except in compliance with the License.
|
* You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing, software
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* See the License for the specific language governing permissions and
|
* limitations under the License.
|
*/
|
|
import java.util.*;
|
|
public class Main {
|
|
public static void main(String[] args) throws Exception {
|
System.loadLibrary(args[0]);
|
|
if (!checkAppImageLoaded()) {
|
System.out.println("AppImage not loaded.");
|
}
|
|
expectNotPreInit(Day.class);
|
expectNotPreInit(ClInit.class); // should pass
|
expectNotPreInit(A.class); // should pass
|
expectNotPreInit(B.class); // should fail
|
expectNotPreInit(C.class); // should fail
|
expectNotPreInit(G.class); // should fail
|
expectNotPreInit(Gs.class); // should fail
|
expectNotPreInit(Gss.class); // should fail
|
|
expectNotPreInit(Add.class);
|
expectNotPreInit(Mul.class);
|
expectNotPreInit(ObjectRef.class);
|
|
A x = new A();
|
System.out.println("A.a: " + A.a);
|
|
B y = new B();
|
C z = new C();
|
System.out.println("A.a: " + A.a);
|
System.out.println("B.b: " + B.b);
|
System.out.println("C.c: " + C.c);
|
|
ClInit c = new ClInit();
|
int aa = c.a;
|
|
System.out.println("X: " + c.getX());
|
System.out.println("Y: " + c.getY());
|
System.out.println("str: " + c.str);
|
System.out.println("ooo: " + c.ooo);
|
System.out.println("Z: " + c.getZ());
|
System.out.println("A: " + c.getA());
|
System.out.println("AA: " + aa);
|
|
if (c.a != 101) {
|
System.out.println("a != 101");
|
}
|
|
return;
|
}
|
|
static void expectPreInit(Class<?> klass) {
|
if (checkInitialized(klass) == false) {
|
System.out.println(klass.getName() + " should be initialized!");
|
}
|
}
|
|
static void expectNotPreInit(Class<?> klass) {
|
if (checkInitialized(klass) == true) {
|
System.out.println(klass.getName() + " should not be initialized!");
|
}
|
}
|
|
public static native boolean checkAppImageLoaded();
|
public static native boolean checkAppImageContains(Class<?> klass);
|
public static native boolean checkInitialized(Class<?> klass);
|
}
|
|
enum Day {
|
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
|
THURSDAY, FRIDAY, SATURDAY
|
}
|
|
class ClInit {
|
|
static String ooo = "OoooooO";
|
static String str;
|
static int z;
|
static int x, y;
|
public static volatile int a = 100;
|
|
static {
|
StringBuilder sb = new StringBuilder();
|
sb.append("Hello ");
|
sb.append("World!");
|
str = sb.toString();
|
|
z = 0xFF;
|
z += 0xFF00;
|
z += 0xAA0000;
|
|
for(int i = 0; i < 100; i++) {
|
x += i;
|
}
|
|
y = x;
|
for(int i = 0; i < 40; i++) {
|
y += i;
|
}
|
}
|
|
int getX() {
|
return x;
|
}
|
|
int getZ() {
|
return z;
|
}
|
|
int getY() {
|
return y;
|
}
|
|
int getA() {
|
return a;
|
}
|
}
|
|
class A {
|
public static int a = 2;
|
static {
|
a = 5; // self-updating, pass
|
}
|
}
|
|
class B {
|
public static int b;
|
static {
|
A.a = 10; // write other's static field, fail
|
b = A.a; // read other's static field, fail
|
}
|
}
|
|
class C {
|
public static int c;
|
static {
|
c = A.a; // read other's static field, fail
|
}
|
}
|
|
class G {
|
static G g;
|
static int i;
|
static {
|
g = new Gss(); // fail because recursive dependency
|
i = A.a; // read other's static field, fail
|
}
|
}
|
|
// Gs will be successfully initialized as G's status is initializing at that point, which will
|
// later aborted but Gs' transaction is already committed.
|
// Instantiation of Gs will fail because we try to invoke G's <init>
|
// but G's status will be StatusVerified. INVOKE_DIRECT will not initialize class.
|
class Gs extends G {} // fail because super class can't be initialized
|
class Gss extends Gs {}
|
|
// pruned because holding reference to non-image class
|
class ObjectRef {
|
static Class<?> klazz[] = new Class<?>[]{Add.class, Mul.class};
|
}
|
|
// non-image
|
class Add {
|
static int exec(int a, int b) {
|
return a + b;
|
}
|
}
|
|
// non-image
|
class Mul {
|
static int exec(int a, int b) {
|
return a * b;
|
}
|
}
|