• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import java.util.*;
18 
19 public class Main {
20 
main(String[] args)21   public static void main(String[] args) throws Exception {
22     System.loadLibrary(args[0]);
23 
24     if (!checkAppImageLoaded("660-clinit")) {
25       System.out.println("AppImage not loaded.");
26     }
27     if (!checkAppImageContains(ClInit.class)) {
28       System.out.println("ClInit class is not in app image!");
29     }
30 
31     expectPreInit(ClInit.class);
32     expectPreInit(A.class);
33     expectPreInit(E.class);
34     expectNotPreInit(B.class);
35     expectNotPreInit(C.class);
36     expectNotPreInit(G.class);
37     expectNotPreInit(Gs.class);
38     expectNotPreInit(Gss.class);
39     expectPreInit(InvokeStatic.class);
40     expectNotPreInit(ClinitE.class);
41 
42     expectNotPreInit(Add.class);
43     expectNotPreInit(Mul.class);
44     expectNotPreInit(ObjectRef.class);
45     expectNotPreInit(Print.class);
46 
47     Print p = new Print();
48     Gs gs = new Gs();
49 
50     A x = new A();
51     System.out.println("A.a: " + A.a);
52 
53     B y = new B();
54     C z = new C();
55     System.out.println("A.a: " + A.a);
56     System.out.println("B.b: " + B.b);
57     System.out.println("C.c: " + C.c);
58 
59     ClInit c = new ClInit();
60     int aa = c.a;
61 
62     System.out.println("X: " + c.getX());
63     System.out.println("Y: " + c.getY());
64     System.out.println("str: " + c.str);
65     System.out.println("ooo: " + c.ooo);
66     System.out.println("Z: " + c.getZ());
67     System.out.println("A: " + c.getA());
68     System.out.println("AA: " + aa);
69 
70     if (c.a != 101) {
71       System.out.println("a != 101");
72     }
73 
74     try {
75       ClinitE e = new ClinitE();
76     } catch (Error err) { }
77 
78     return;
79   }
80 
expectPreInit(Class<?> klass)81   static void expectPreInit(Class<?> klass) {
82     if (checkInitialized(klass) == false) {
83       System.out.println(klass.getName() + " should be initialized!");
84     }
85   }
86 
expectNotPreInit(Class<?> klass)87   static void expectNotPreInit(Class<?> klass) {
88     if (checkInitialized(klass) == true) {
89       System.out.println(klass.getName() + " should not be initialized!");
90     }
91   }
92 
checkAppImageLoaded(String name)93   public static native boolean checkAppImageLoaded(String name);
checkAppImageContains(Class<?> klass)94   public static native boolean checkAppImageContains(Class<?> klass);
checkInitialized(Class<?> klass)95   public static native boolean checkInitialized(Class<?> klass);
96 }
97 
98 enum Day {
99     SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
100     THURSDAY, FRIDAY, SATURDAY
101 }
102 
103 class ClInit {
104 
105   static String ooo = "OoooooO";
106   static String str;
107   static int z;
108   static int x, y;
109   public static volatile int a = 100;
110 
111   static {
112     StringBuilder sb = new StringBuilder();
113     sb.append("Hello ");
114     sb.append("World!");
115     str = sb.toString();
116 
117     z = 0xFF;
118     z += 0xFF00;
119     z += 0xAA0000;
120 
121     for(int i = 0; i < 100; i++) {
122       x += i;
123     }
124 
125     y = x;
126     for(int i = 0; i < 40; i++) {
127       y += i;
128     }
129   }
130 
getX()131   int getX() {
132     return x;
133   }
134 
getZ()135   int getZ() {
136     return z;
137   }
138 
getY()139   int getY() {
140     return y;
141   }
142 
getA()143   int getA() {
144     return a;
145   }
146 }
147 
148 class A {
149   public static int a = 2;
150   static {
151     a = 5;  // self-updating, pass
152   }
153 }
154 
155 class B {
156   public static int b;
157   static {
158     A.a = 10;  // write other's static field, fail
159     b = A.a;   // read other's static field, fail
160   }
161 }
162 
163 class C {
164   public static int c;
165   static {
166     c = A.a; // read other's static field, fail
167   }
168 }
169 
170 class E {
171   public static final int e;
172   static {
173     e = 100;
174   }
175 }
176 
177 class G {
178   static G g;
179   static int i;
180   static {
181     g = new Gss(); // fail because recursive dependency
182     i = A.a;  // read other's static field, fail
183   }
184 }
185 
186 // Gs will be successfully initialized as G's status is initializing at that point, which will
187 // later aborted but Gs' transaction is already committed.
188 // Instantiation of Gs will fail because we try to invoke G's <init>
189 // but G's status will be StatusVerified. INVOKE_DIRECT will not initialize class.
190 class Gs extends G {}  // fail because super class can't be initialized
191 class Gss extends Gs {}
192 
193 // pruned because holding reference to non-image class
194 class ObjectRef {
195   static Class<?> klazz[] = new Class<?>[]{Add.class, Mul.class};
196 }
197 
198 // non-image
199 class Add {
exec(int a, int b)200   static int exec(int a, int b) {
201     return a + b;
202   }
203 }
204 
205 class InImage {
exec(int a, int b)206   static int exec(int a, int b) {
207     return a + b;
208   }
209 }
210 
211 // test of INVOKE_STATIC instruction
212 class InvokeStatic {
213   static int a;
214   static int b;
215   static {
216     a = InImage.exec(10, 20);
217     b = InImage.exec(10, 20);
218   }
219 }
220 
221 // non-image
222 class Mul {
exec(int a, int b)223   static int exec(int a, int b) {
224     return a * b;
225   }
226 }
227 
228 class ClinitE {
229   static {
230     if (Math.sin(3) < 0.5) {
231       // throw anyway, can't initialized
232       throw new ExceptionInInitializerError("Can't initialize this class!");
233     }
234   }
235 }
236 
237 // fail because JNI
238 class Print {
239   static {
240     System.out.println("hello world");
241   }
242 }
243