xref: /aosp_15_r20/art/test/1981-structural-redef-private-method-handles/src/art/Test1981.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker package art;
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.*;
20*795d594fSAndroid Build Coastguard Worker import java.lang.ref.*;
21*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.*;
22*795d594fSAndroid Build Coastguard Worker import java.util.*;
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker public class Test1981 {
25*795d594fSAndroid Build Coastguard Worker   // Allow us to hide the var-handle portions when running this on CTS.
26*795d594fSAndroid Build Coastguard Worker   public interface VarHandler {
doVarHandleTests()27*795d594fSAndroid Build Coastguard Worker     public boolean doVarHandleTests();
28*795d594fSAndroid Build Coastguard Worker 
findStaticVarHandle(MethodHandles.Lookup l, Class c, String n, Class t)29*795d594fSAndroid Build Coastguard Worker     public default Object findStaticVarHandle(MethodHandles.Lookup l, Class c, String n, Class t)
30*795d594fSAndroid Build Coastguard Worker         throws Throwable {
31*795d594fSAndroid Build Coastguard Worker       return null;
32*795d594fSAndroid Build Coastguard Worker     }
33*795d594fSAndroid Build Coastguard Worker 
get(Object vh)34*795d594fSAndroid Build Coastguard Worker     public default Object get(Object vh) throws Throwable {
35*795d594fSAndroid Build Coastguard Worker       throw new Error("Illegal call!");
36*795d594fSAndroid Build Coastguard Worker     }
37*795d594fSAndroid Build Coastguard Worker 
set(Object vh, Object v)38*795d594fSAndroid Build Coastguard Worker     public default void set(Object vh, Object v) throws Throwable {
39*795d594fSAndroid Build Coastguard Worker       throw new Error("Illegal call!");
40*795d594fSAndroid Build Coastguard Worker     }
instanceofVarHandle(Object v)41*795d594fSAndroid Build Coastguard Worker     public default boolean instanceofVarHandle(Object v) {
42*795d594fSAndroid Build Coastguard Worker       return false;
43*795d594fSAndroid Build Coastguard Worker     }
getVarTypeName(Object v)44*795d594fSAndroid Build Coastguard Worker     public default Object getVarTypeName(Object v) {
45*795d594fSAndroid Build Coastguard Worker       throw new Error("Illegal call!");
46*795d594fSAndroid Build Coastguard Worker     }
47*795d594fSAndroid Build Coastguard Worker   }
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker   // CTS Entrypoint.
run()50*795d594fSAndroid Build Coastguard Worker   public static void run() throws Exception {
51*795d594fSAndroid Build Coastguard Worker     run(() -> false);
52*795d594fSAndroid Build Coastguard Worker   }
53*795d594fSAndroid Build Coastguard Worker 
run(VarHandler varhandle_portion)54*795d594fSAndroid Build Coastguard Worker   public static void run(VarHandler varhandle_portion) throws Exception {
55*795d594fSAndroid Build Coastguard Worker     Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
56*795d594fSAndroid Build Coastguard Worker     doTest(varhandle_portion);
57*795d594fSAndroid Build Coastguard Worker   }
58*795d594fSAndroid Build Coastguard Worker 
59*795d594fSAndroid Build Coastguard Worker   private static final boolean PRINT_NONDETERMINISTIC = false;
60*795d594fSAndroid Build Coastguard Worker 
61*795d594fSAndroid Build Coastguard Worker   public static WeakHashMap<Object, Long> id_nums = new WeakHashMap<>();
62*795d594fSAndroid Build Coastguard Worker   public static long next_id = 0;
63*795d594fSAndroid Build Coastguard Worker 
printGeneric(VarHandler vh, Object o)64*795d594fSAndroid Build Coastguard Worker   public static String printGeneric(VarHandler vh, Object o) {
65*795d594fSAndroid Build Coastguard Worker     Long id = id_nums.get(o);
66*795d594fSAndroid Build Coastguard Worker     if (id == null) {
67*795d594fSAndroid Build Coastguard Worker       id = Long.valueOf(next_id++);
68*795d594fSAndroid Build Coastguard Worker       id_nums.put(o, id);
69*795d594fSAndroid Build Coastguard Worker     }
70*795d594fSAndroid Build Coastguard Worker     if (o == null) {
71*795d594fSAndroid Build Coastguard Worker       return "(ID: " + id + ") <NULL>";
72*795d594fSAndroid Build Coastguard Worker     }
73*795d594fSAndroid Build Coastguard Worker     Class oc = o.getClass();
74*795d594fSAndroid Build Coastguard Worker     if (oc.isArray() && oc.getComponentType() == Byte.TYPE) {
75*795d594fSAndroid Build Coastguard Worker       return "(ID: "
76*795d594fSAndroid Build Coastguard Worker           + id
77*795d594fSAndroid Build Coastguard Worker           + ") "
78*795d594fSAndroid Build Coastguard Worker           + Arrays.toString(Arrays.copyOf((byte[]) o, 10)).replace(']', ',')
79*795d594fSAndroid Build Coastguard Worker           + " ...]";
80*795d594fSAndroid Build Coastguard Worker     } else if (vh.instanceofVarHandle(o)) {
81*795d594fSAndroid Build Coastguard Worker       // These don't have a good to-string. Give them one.
82*795d594fSAndroid Build Coastguard Worker       return "(ID: " + id + ") " + o.getClass().getName() + "()->" + vh.getVarTypeName(o);
83*795d594fSAndroid Build Coastguard Worker     } else {
84*795d594fSAndroid Build Coastguard Worker       return "(ID: " + id + ") " + o.toString();
85*795d594fSAndroid Build Coastguard Worker     }
86*795d594fSAndroid Build Coastguard Worker   }
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker   public static class Transform {
89*795d594fSAndroid Build Coastguard Worker     static {
90*795d594fSAndroid Build Coastguard Worker     }
91*795d594fSAndroid Build Coastguard Worker 
92*795d594fSAndroid Build Coastguard Worker     private static Object BAR =
93*795d594fSAndroid Build Coastguard Worker         new Object() {
94*795d594fSAndroid Build Coastguard Worker           public String toString() {
95*795d594fSAndroid Build Coastguard Worker             return "value of <" + this.get() + ">";
96*795d594fSAndroid Build Coastguard Worker           }
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker           public Object get() {
99*795d594fSAndroid Build Coastguard Worker             return "BAR FIELD";
100*795d594fSAndroid Build Coastguard Worker           }
101*795d594fSAndroid Build Coastguard Worker         };
102*795d594fSAndroid Build Coastguard Worker     private static Object FOO =
103*795d594fSAndroid Build Coastguard Worker         new Object() {
104*795d594fSAndroid Build Coastguard Worker           public String toString() {
105*795d594fSAndroid Build Coastguard Worker             return "value of <" + this.get() + ">";
106*795d594fSAndroid Build Coastguard Worker           }
107*795d594fSAndroid Build Coastguard Worker 
108*795d594fSAndroid Build Coastguard Worker           public Object get() {
109*795d594fSAndroid Build Coastguard Worker             return "FOO FIELD";
110*795d594fSAndroid Build Coastguard Worker           }
111*795d594fSAndroid Build Coastguard Worker         };
112*795d594fSAndroid Build Coastguard Worker 
getLookup()113*795d594fSAndroid Build Coastguard Worker     public static MethodHandles.Lookup getLookup() {
114*795d594fSAndroid Build Coastguard Worker       return MethodHandles.lookup();
115*795d594fSAndroid Build Coastguard Worker     }
116*795d594fSAndroid Build Coastguard Worker 
staticToString()117*795d594fSAndroid Build Coastguard Worker     public static String staticToString() {
118*795d594fSAndroid Build Coastguard Worker       return Transform.class.toString() + "[FOO: " + FOO + ", BAR: " + BAR + "]";
119*795d594fSAndroid Build Coastguard Worker     }
120*795d594fSAndroid Build Coastguard Worker   }
121*795d594fSAndroid Build Coastguard Worker 
122*795d594fSAndroid Build Coastguard Worker   /* Base64 encoded class of:
123*795d594fSAndroid Build Coastguard Worker    * public static class Transform {
124*795d594fSAndroid Build Coastguard Worker    *   static {}
125*795d594fSAndroid Build Coastguard Worker    *   // NB This is the order the fields will be laid out in memory.
126*795d594fSAndroid Build Coastguard Worker    *   private static Object BAR;
127*795d594fSAndroid Build Coastguard Worker    *   private static Object BAZ;
128*795d594fSAndroid Build Coastguard Worker    *   private static Object FOO;
129*795d594fSAndroid Build Coastguard Worker    *   public static MethodHandles.Lookup getLookup() { return null; }
130*795d594fSAndroid Build Coastguard Worker    *   private static void reinitialize() {
131*795d594fSAndroid Build Coastguard Worker    *     BAZ = 42;
132*795d594fSAndroid Build Coastguard Worker    *   }
133*795d594fSAndroid Build Coastguard Worker    *   public static String staticToString() {
134*795d594fSAndroid Build Coastguard Worker    *    return Transform.class.toString() + "[FOO: " + FOO + ", BAR: " + BAR + ", BAZ: " + BAZ + "]";
135*795d594fSAndroid Build Coastguard Worker    *   }
136*795d594fSAndroid Build Coastguard Worker    * }
137*795d594fSAndroid Build Coastguard Worker    */
138*795d594fSAndroid Build Coastguard Worker   private static byte[] REDEFINED_DEX_BYTES =
139*795d594fSAndroid Build Coastguard Worker       Base64.getDecoder()
140*795d594fSAndroid Build Coastguard Worker           .decode(
141*795d594fSAndroid Build Coastguard Worker               "ZGV4CjAzNQDY+Vd3k8SVBE6A35RavIBzYN76h51YIqVwBgAAcAAAAHhWNBIAAAAAAAAAAKwFAAAk"
142*795d594fSAndroid Build Coastguard Worker                   + "AAAAcAAAAAwAAAAAAQAABgAAADABAAADAAAAeAEAAAwAAACQAQAAAQAAAPABAABgBAAAEAIAABoD"
143*795d594fSAndroid Build Coastguard Worker                   + "AAAjAwAALAMAADYDAAA+AwAAQwMAAEgDAABNAwAAUAMAAFMDAABXAwAAWwMAAHUDAACFAwAAqQMA"
144*795d594fSAndroid Build Coastguard Worker                   + "AMkDAADcAwAA8QMAAAUEAAAZBAAANAQAAF0EAABsBAAAdwQAAHoEAACCBAAAhQQAAJIEAACaBAAA"
145*795d594fSAndroid Build Coastguard Worker                   + "pQQAAKsEAAC5BAAAyQQAANMEAADaBAAA4wQAAAcAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAAR"
146*795d594fSAndroid Build Coastguard Worker                   + "AAAAEgAAABMAAAAUAAAAFwAAAAkAAAAGAAAABAMAAAgAAAAIAAAAAAAAAAoAAAAJAAAADAMAAAoA"
147*795d594fSAndroid Build Coastguard Worker                   + "AAAJAAAAFAMAAAgAAAAKAAAAAAAAABcAAAALAAAAAAAAAAEABwAEAAAAAQAHAAUAAAABAAcABgAA"
148*795d594fSAndroid Build Coastguard Worker                   + "AAEABQACAAAAAQAFAAMAAAABAAQAHAAAAAEABQAeAAAAAQABAB8AAAAFAAEAIAAAAAYAAAAiAAAA"
149*795d594fSAndroid Build Coastguard Worker                   + "BwAFAAMAAAAJAAUAAwAAAAkAAgAbAAAACQADABsAAAAJAAEAIAAAAAEAAAABAAAABwAAAAAAAAAV"
150*795d594fSAndroid Build Coastguard Worker                   + "AAAAnAUAAGoFAAAAAAAABQAAAAIAAAD/AgAANgAAABwAAQBuEAUAAAAMAGIBAgBiAgAAYgMBACIE"
151*795d594fSAndroid Build Coastguard Worker                   + "CQBwEAgABABuIAoABAAaABgAbiAKAAQAbiAJABQAGgAAAG4gCgAEAG4gCQAkABoAAQBuIAoABABu"
152*795d594fSAndroid Build Coastguard Worker                   + "IAkANAAaABkAbiAKAAQAbhALAAQADAARAAEAAAAAAAAA9gIAAAIAAAASABEAAAAAAAAAAADuAgAA"
153*795d594fSAndroid Build Coastguard Worker                   + "AQAAAA4AAAABAAEAAQAAAPICAAAEAAAAcBAHAAAADgABAAAAAQAAAPoCAAAJAAAAEwAqAHEQBgAA"
154*795d594fSAndroid Build Coastguard Worker                   + "AAwAaQABAA4ACgAOAAkADgAPAA4AEQAOhwAUAA4AAAEAAAAAAAAAAQAAAAcAAAABAAAACAAHLCBC"
155*795d594fSAndroid Build Coastguard Worker                   + "QVI6IAAHLCBCQVo6IAAIPGNsaW5pdD4ABjxpbml0PgADQkFSAANCQVoAA0ZPTwABSQABTAACTEkA"
156*795d594fSAndroid Build Coastguard Worker                   + "AkxMABhMYXJ0L1Rlc3QxOTgxJFRyYW5zZm9ybTsADkxhcnQvVGVzdDE5ODE7ACJMZGFsdmlrL2Fu"
157*795d594fSAndroid Build Coastguard Worker                   + "bm90YXRpb24vRW5jbG9zaW5nQ2xhc3M7AB5MZGFsdmlrL2Fubm90YXRpb24vSW5uZXJDbGFzczsA"
158*795d594fSAndroid Build Coastguard Worker                   + "EUxqYXZhL2xhbmcvQ2xhc3M7ABNMamF2YS9sYW5nL0ludGVnZXI7ABJMamF2YS9sYW5nL09iamVj"
159*795d594fSAndroid Build Coastguard Worker                   + "dDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAZTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwAnTGphdmEv"
160*795d594fSAndroid Build Coastguard Worker                   + "bGFuZy9pbnZva2UvTWV0aG9kSGFuZGxlcyRMb29rdXA7AA1UZXN0MTk4MS5qYXZhAAlUcmFuc2Zv"
161*795d594fSAndroid Build Coastguard Worker                   + "cm0AAVYABltGT086IAABXQALYWNjZXNzRmxhZ3MABmFwcGVuZAAJZ2V0TG9va3VwAARuYW1lAAxy"
162*795d594fSAndroid Build Coastguard Worker                   + "ZWluaXRpYWxpemUADnN0YXRpY1RvU3RyaW5nAAh0b1N0cmluZwAFdmFsdWUAB3ZhbHVlT2YAdn5+"
163*795d594fSAndroid Build Coastguard Worker                   + "RDh7ImNvbXBpbGF0aW9uLW1vZGUiOiJkZWJ1ZyIsIm1pbi1hcGkiOjEsInNoYS0xIjoiYTgzNTJm"
164*795d594fSAndroid Build Coastguard Worker                   + "MjU0ODg1MzYyY2NkOGQ5MDlkMzUyOWM2MDA5NGRkODk2ZSIsInZlcnNpb24iOiIxLjYuMjAtZGV2"
165*795d594fSAndroid Build Coastguard Worker                   + "In0AAgMBIRgCAgQCGgQJHRcWAwAFAAAKAQoBCgCIgASgBQGBgAS0BQEJjAUBCswFAQmQBAAAAAAC"
166*795d594fSAndroid Build Coastguard Worker                   + "AAAAWwUAAGEFAACQBQAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAkAAAAcAAAAAIA"
167*795d594fSAndroid Build Coastguard Worker                   + "AAAMAAAAAAEAAAMAAAAGAAAAMAEAAAQAAAADAAAAeAEAAAUAAAAMAAAAkAEAAAYAAAABAAAA8AEA"
168*795d594fSAndroid Build Coastguard Worker                   + "AAEgAAAFAAAAEAIAAAMgAAAFAAAA7gIAAAEQAAADAAAABAMAAAIgAAAkAAAAGgMAAAQgAAACAAAA"
169*795d594fSAndroid Build Coastguard Worker                   + "WwUAAAAgAAABAAAAagUAAAMQAAACAAAAjAUAAAYgAAABAAAAnAUAAAAQAAABAAAArAUAAA==");
170*795d594fSAndroid Build Coastguard Worker 
doTest(VarHandler vh)171*795d594fSAndroid Build Coastguard Worker   public static void doTest(VarHandler vh) throws Exception {
172*795d594fSAndroid Build Coastguard Worker     try {
173*795d594fSAndroid Build Coastguard Worker       System.out.println("Initial: " + Transform.staticToString());
174*795d594fSAndroid Build Coastguard Worker       MethodHandles.Lookup lookup = Transform.getLookup();
175*795d594fSAndroid Build Coastguard Worker       String[] names =
176*795d594fSAndroid Build Coastguard Worker           new String[] {
177*795d594fSAndroid Build Coastguard Worker             "FOO", "BAR",
178*795d594fSAndroid Build Coastguard Worker           };
179*795d594fSAndroid Build Coastguard Worker       MethodHandle[] handles =
180*795d594fSAndroid Build Coastguard Worker           new MethodHandle[] {
181*795d594fSAndroid Build Coastguard Worker             lookup.findStaticGetter(Transform.class, "FOO", Object.class),
182*795d594fSAndroid Build Coastguard Worker             lookup.findStaticGetter(Transform.class, "BAR", Object.class),
183*795d594fSAndroid Build Coastguard Worker           };
184*795d594fSAndroid Build Coastguard Worker       Object foo_handle = vh.findStaticVarHandle(lookup, Transform.class, "FOO", Object.class);
185*795d594fSAndroid Build Coastguard Worker       Object[] var_handles =
186*795d594fSAndroid Build Coastguard Worker           new Object[] {
187*795d594fSAndroid Build Coastguard Worker             foo_handle, vh.findStaticVarHandle(lookup, Transform.class, "BAR", Object.class),
188*795d594fSAndroid Build Coastguard Worker           };
189*795d594fSAndroid Build Coastguard Worker 
190*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < names.length; i++) {
191*795d594fSAndroid Build Coastguard Worker         System.out.println(
192*795d594fSAndroid Build Coastguard Worker             "Reading field "
193*795d594fSAndroid Build Coastguard Worker                 + names[i]
194*795d594fSAndroid Build Coastguard Worker                 + " using "
195*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, handles[i])
196*795d594fSAndroid Build Coastguard Worker                 + " = "
197*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, handles[i].invoke()));
198*795d594fSAndroid Build Coastguard Worker         if (vh.doVarHandleTests()) {
199*795d594fSAndroid Build Coastguard Worker           System.out.println(
200*795d594fSAndroid Build Coastguard Worker               "Reading field "
201*795d594fSAndroid Build Coastguard Worker                   + names[i]
202*795d594fSAndroid Build Coastguard Worker                   + " using "
203*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, var_handles[i])
204*795d594fSAndroid Build Coastguard Worker                   + " = "
205*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, vh.get(var_handles[i])));
206*795d594fSAndroid Build Coastguard Worker         }
207*795d594fSAndroid Build Coastguard Worker       }
208*795d594fSAndroid Build Coastguard Worker       MethodHandle old_field_write = lookup.findStaticSetter(Transform.class, "FOO", Object.class);
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker       System.out.println("Redefining Transform class");
211*795d594fSAndroid Build Coastguard Worker       Redefinition.doCommonStructuralClassRedefinition(Transform.class, REDEFINED_DEX_BYTES);
212*795d594fSAndroid Build Coastguard Worker       System.out.println("Post redefinition : " + Transform.staticToString());
213*795d594fSAndroid Build Coastguard Worker 
214*795d594fSAndroid Build Coastguard Worker       String[] new_names =
215*795d594fSAndroid Build Coastguard Worker           new String[] {
216*795d594fSAndroid Build Coastguard Worker             "BAZ", "FOO", "BAR",
217*795d594fSAndroid Build Coastguard Worker           };
218*795d594fSAndroid Build Coastguard Worker       MethodHandle[] new_handles =
219*795d594fSAndroid Build Coastguard Worker           new MethodHandle[] {
220*795d594fSAndroid Build Coastguard Worker             lookup.findStaticGetter(Transform.class, "BAZ", Object.class),
221*795d594fSAndroid Build Coastguard Worker             lookup.findStaticGetter(Transform.class, "FOO", Object.class),
222*795d594fSAndroid Build Coastguard Worker             lookup.findStaticGetter(Transform.class, "BAR", Object.class),
223*795d594fSAndroid Build Coastguard Worker           };
224*795d594fSAndroid Build Coastguard Worker       Object baz_handle = vh.findStaticVarHandle(lookup, Transform.class, "BAZ", Object.class);
225*795d594fSAndroid Build Coastguard Worker       Object[] new_var_handles =
226*795d594fSAndroid Build Coastguard Worker           new Object[] {
227*795d594fSAndroid Build Coastguard Worker             baz_handle,
228*795d594fSAndroid Build Coastguard Worker             vh.findStaticVarHandle(lookup, Transform.class, "FOO", Object.class),
229*795d594fSAndroid Build Coastguard Worker             vh.findStaticVarHandle(lookup, Transform.class, "BAR", Object.class),
230*795d594fSAndroid Build Coastguard Worker           };
231*795d594fSAndroid Build Coastguard Worker 
232*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < names.length; i++) {
233*795d594fSAndroid Build Coastguard Worker         System.out.println(
234*795d594fSAndroid Build Coastguard Worker             "Reading field "
235*795d594fSAndroid Build Coastguard Worker                 + names[i]
236*795d594fSAndroid Build Coastguard Worker                 + " using "
237*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, handles[i])
238*795d594fSAndroid Build Coastguard Worker                 + " = "
239*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, handles[i].invoke()));
240*795d594fSAndroid Build Coastguard Worker         if (vh.doVarHandleTests()) {
241*795d594fSAndroid Build Coastguard Worker           System.out.println(
242*795d594fSAndroid Build Coastguard Worker               "Reading field "
243*795d594fSAndroid Build Coastguard Worker                   + names[i]
244*795d594fSAndroid Build Coastguard Worker                   + " using "
245*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, var_handles[i])
246*795d594fSAndroid Build Coastguard Worker                   + " = "
247*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, vh.get(var_handles[i])));
248*795d594fSAndroid Build Coastguard Worker         }
249*795d594fSAndroid Build Coastguard Worker       }
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < new_names.length; i++) {
252*795d594fSAndroid Build Coastguard Worker         System.out.println(
253*795d594fSAndroid Build Coastguard Worker             "Reading new field "
254*795d594fSAndroid Build Coastguard Worker                 + new_names[i]
255*795d594fSAndroid Build Coastguard Worker                 + " using "
256*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, new_handles[i])
257*795d594fSAndroid Build Coastguard Worker                 + " = "
258*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, new_handles[i].invoke()));
259*795d594fSAndroid Build Coastguard Worker         if (vh.doVarHandleTests()) {
260*795d594fSAndroid Build Coastguard Worker           System.out.println(
261*795d594fSAndroid Build Coastguard Worker               "Reading new field "
262*795d594fSAndroid Build Coastguard Worker                   + new_names[i]
263*795d594fSAndroid Build Coastguard Worker                   + " using "
264*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, new_var_handles[i])
265*795d594fSAndroid Build Coastguard Worker                   + " = "
266*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, vh.get(new_var_handles[i])));
267*795d594fSAndroid Build Coastguard Worker         }
268*795d594fSAndroid Build Coastguard Worker       }
269*795d594fSAndroid Build Coastguard Worker 
270*795d594fSAndroid Build Coastguard Worker       String val = "foo";
271*795d594fSAndroid Build Coastguard Worker       System.out.println("Setting BAZ to " + printGeneric(vh, val) + " with new mh.");
272*795d594fSAndroid Build Coastguard Worker       lookup.findStaticSetter(Transform.class, "BAZ", Object.class).invoke(val);
273*795d594fSAndroid Build Coastguard Worker       System.out.println("Post set with new mh: " + Transform.staticToString());
274*795d594fSAndroid Build Coastguard Worker 
275*795d594fSAndroid Build Coastguard Worker       System.out.println("Setting FOO to " + printGeneric(vh, Transform.class) + " with old mh.");
276*795d594fSAndroid Build Coastguard Worker       old_field_write.invoke(Transform.class);
277*795d594fSAndroid Build Coastguard Worker       System.out.println("Post set with old mh: " + Transform.staticToString());
278*795d594fSAndroid Build Coastguard Worker 
279*795d594fSAndroid Build Coastguard Worker       Object new_val =
280*795d594fSAndroid Build Coastguard Worker           new Object() {
281*795d594fSAndroid Build Coastguard Worker             public String toString() {
282*795d594fSAndroid Build Coastguard Worker               return "new_value object";
283*795d594fSAndroid Build Coastguard Worker             }
284*795d594fSAndroid Build Coastguard Worker           };
285*795d594fSAndroid Build Coastguard Worker       if (vh.doVarHandleTests()) {
286*795d594fSAndroid Build Coastguard Worker         System.out.println("Setting FOO to '" + printGeneric(vh, new_val) + "' with old varhandle.");
287*795d594fSAndroid Build Coastguard Worker         vh.set(foo_handle, new_val);
288*795d594fSAndroid Build Coastguard Worker         System.out.println("Post set with new varhandle: " + Transform.staticToString());
289*795d594fSAndroid Build Coastguard Worker 
290*795d594fSAndroid Build Coastguard Worker         System.out.println("Setting BAZ to 'bar' with new varhandle.");
291*795d594fSAndroid Build Coastguard Worker         vh.set(baz_handle, "bar");
292*795d594fSAndroid Build Coastguard Worker         System.out.println("Post set with old varhandle: " + Transform.staticToString());
293*795d594fSAndroid Build Coastguard Worker       }
294*795d594fSAndroid Build Coastguard Worker 
295*795d594fSAndroid Build Coastguard Worker       System.out.println("Using mh to call new private method.");
296*795d594fSAndroid Build Coastguard Worker       MethodHandle reinit =
297*795d594fSAndroid Build Coastguard Worker           lookup.findStatic(Transform.class, "reinitialize", MethodType.methodType(Void.TYPE));
298*795d594fSAndroid Build Coastguard Worker       reinit.invoke();
299*795d594fSAndroid Build Coastguard Worker       System.out.println("Post reinit with mh: " + Transform.staticToString());
300*795d594fSAndroid Build Coastguard Worker 
301*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < names.length; i++) {
302*795d594fSAndroid Build Coastguard Worker         System.out.println(
303*795d594fSAndroid Build Coastguard Worker             "Reading field "
304*795d594fSAndroid Build Coastguard Worker                 + names[i]
305*795d594fSAndroid Build Coastguard Worker                 + " using "
306*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, handles[i])
307*795d594fSAndroid Build Coastguard Worker                 + " = "
308*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, handles[i].invoke()));
309*795d594fSAndroid Build Coastguard Worker         if (vh.doVarHandleTests()) {
310*795d594fSAndroid Build Coastguard Worker           System.out.println(
311*795d594fSAndroid Build Coastguard Worker               "Reading field "
312*795d594fSAndroid Build Coastguard Worker                   + names[i]
313*795d594fSAndroid Build Coastguard Worker                   + " using "
314*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, var_handles[i])
315*795d594fSAndroid Build Coastguard Worker                   + " = "
316*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, vh.get(var_handles[i])));
317*795d594fSAndroid Build Coastguard Worker         }
318*795d594fSAndroid Build Coastguard Worker       }
319*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < new_names.length; i++) {
320*795d594fSAndroid Build Coastguard Worker         System.out.println(
321*795d594fSAndroid Build Coastguard Worker             "Reading new field "
322*795d594fSAndroid Build Coastguard Worker                 + new_names[i]
323*795d594fSAndroid Build Coastguard Worker                 + " using "
324*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, new_handles[i])
325*795d594fSAndroid Build Coastguard Worker                 + " = "
326*795d594fSAndroid Build Coastguard Worker                 + printGeneric(vh, new_handles[i].invoke()));
327*795d594fSAndroid Build Coastguard Worker         if (vh.doVarHandleTests()) {
328*795d594fSAndroid Build Coastguard Worker           System.out.println(
329*795d594fSAndroid Build Coastguard Worker               "Reading new field "
330*795d594fSAndroid Build Coastguard Worker                   + new_names[i]
331*795d594fSAndroid Build Coastguard Worker                   + " using "
332*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, new_var_handles[i])
333*795d594fSAndroid Build Coastguard Worker                   + " = "
334*795d594fSAndroid Build Coastguard Worker                   + printGeneric(vh, vh.get(new_var_handles[i])));
335*795d594fSAndroid Build Coastguard Worker         }
336*795d594fSAndroid Build Coastguard Worker       }
337*795d594fSAndroid Build Coastguard Worker     } catch (Throwable t) {
338*795d594fSAndroid Build Coastguard Worker       if (t instanceof Exception) {
339*795d594fSAndroid Build Coastguard Worker         throw (Exception) t;
340*795d594fSAndroid Build Coastguard Worker       } else if (t instanceof Error) {
341*795d594fSAndroid Build Coastguard Worker         throw (Error) t;
342*795d594fSAndroid Build Coastguard Worker       } else {
343*795d594fSAndroid Build Coastguard Worker         throw new RuntimeException("Unexpected throwable!", t);
344*795d594fSAndroid Build Coastguard Worker       }
345*795d594fSAndroid Build Coastguard Worker     }
346*795d594fSAndroid Build Coastguard Worker   }
347*795d594fSAndroid Build Coastguard Worker }
348