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