1 /*
2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 Pseudo Java code:
26
27 class CondyNestedResolution {
28 public static Object bsm1arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4) {
29 System.out.println("In bsm1arg");
30 System.out.println(p4);
31 return p4;
32 }
33 public static Object bsm2arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4, Object p5) {
34 System.out.println("In bsm2arg");
35 System.out.println(p4);
36 System.out.println(p5);
37 return p4;
38 }
39 public static Object bsm3arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4, Object p5, Object p6) {
40 System.out.println("In bsm3arg");
41 System.out.println(p4);
42 System.out.println(p5);
43 System.out.println(p6);
44 return p4;
45 }
46 public static Object bsm4arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4, Object p5, Object p6, Object p7) {
47 System.out.println("In bsm4arg");
48 System.out.println(p4);
49 System.out.println(p5);
50 System.out.println(p6);
51 System.out.println(p7);
52 return p4;
53 }
54
55 public static void test_condy() {
56 // The following condy of BSM#8 results in the invocation of bootstrap method bsm4arg with the following
57 // parameters:
58 // bsm4arg(bsm1arg("hello1"),
59 // bsm1arg("hello2"),
60 // bsm3arg(bsm1arg("hello4"), bsm2arg(bsm1arg("hello6"), (circular reference to BSM#8)), bsm1arg("hello5")),
61 // bsm1arg("hello3"));
62 // JVMS 5.4.3.6 Dynamically-Computed Constant and Call Site Resolution
63 // Ensure that calls to bsm1arg("hello5") and bsm1arg("hello3") are never resolved due to the nested condy circularity
64 // which results in a StackOverflowError.
65 //
66 ldc Dynamic BSM#8;
67 }
68 public static void main(String args[]) {
69 CondyNestedResolution.test_condy();
70 }
71 }
72
73 BootstrapMethods:
74 BSM0=invokestatic CondyNestedResolution.bsm1arg("hello1");
75 BSM1=invokestatic CondyNestedResolution.bsm1arg("hello2");
76 BSM2=invokestatic CondyNestedResolution.bsm1arg("hello4");
77 BSM3=invokestatic CondyNestedResolution.bsm1arg("hello6");
78 BSM4=invokestatic CondyNestedResolution.bsm2arg(BSM#3, BSM#8);
79 BSM5=invokestatic CondyNestedResolution.bsm1arg("hello5");
80 BSM6=invokestatic CondyNestedResolution.bsm3arg(BSM#2, BSM#4, BSM#5);
81 BSM7=invokestatic CondyNestedResolution.bsm1arg("hello3");
82 BSM8=invokestatic CondyNestedResolution.bsm4arg(BSM#0, BSM#1, BSM#6, BSM#7);
83
84 Expected output:
85 In bsm1arg
86 hello1
87 In bsm1arg
88 hello2
89 In bsm1arg
90 hello4
91 In bsm1arg
92 hello6
93 Exception in thread "main" java.lang.StackOverflowError
94 at java.base/java.lang.invoke.MethodHandleNatives.copyOutBootstrapArguments(Native Method)
95 */
96
97
98 class CondyNestedResolution {
99 0xCAFEBABE;
100 0; // minor version
101 55; // version
102 [85] { // Constant Pool
103 ; // first element is empty
104 String #22; // #1 at 0x0A
105 String #61; // #2 at 0x0D
106 String #11; // #3 at 0x10
107 Dynamic 8s #12; // #4 at 0x13
108 Method #51 #10; // #5 at 0x18
109 Method #13 #39; // #6 at 0x1D
110 Field #50 #81; // #7 at 0x22
111 Method #84 #45; // #8 at 0x27
112 Utf8 "java/io/PrintStream"; // #9 at 0x2C
113 NameAndType #71 #47; // #10 at 0x42
114 Utf8 "In bsm1arg"; // #11 at 0x47
115 NameAndType #18 #17; // #12 at 0x54
116 class #9; // #13 at 0x59
117 Utf8 "SourceFile"; // #14 at 0x5C
118 Utf8 "bsm3arg"; // #15 at 0x69
119 Utf8 "CondyNestedResolution.jasm"; // #16 at 0x73
120 Utf8 "Ljava/lang/String;"; // #17 at 0x90
121 Utf8 "name"; // #18 at 0xA5
122 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #19 at 0xAC
123 Utf8 "test_condy"; // #20 at 0x0144
124 NameAndType #15 #19; // #21 at 0x0151
125 Utf8 "In bsm2arg"; // #22 at 0x0156
126 Utf8 "Code"; // #23 at 0x0163
127 Utf8 "([Ljava/lang/String;)V"; // #24 at 0x016A
128 Utf8 "bsm4arg"; // #25 at 0x0183
129 Utf8 "out"; // #26 at 0x018D
130 NameAndType #69 #55; // #27 at 0x0193
131 Utf8 "BootstrapMethods"; // #28 at 0x0198
132 MethodHandle 6b #44; // #29 at 0x01AB
133 Method #84 #63; // #30 at 0x01AF
134 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #31 at 0x01B4
135 Method #84 #27; // #32 at 0x0228
136 MethodHandle 6b #30; // #33 at 0x022D
137 MethodHandle 6b #30; // #34 at 0x0231
138 MethodHandle 6b #30; // #35 at 0x0235
139 MethodHandle 6b #30; // #36 at 0x0239
140 MethodHandle 6b #30; // #37 at 0x023D
141 MethodHandle 6b #30; // #38 at 0x0241
142 NameAndType #40 #41; // #39 at 0x0245
143 Utf8 "println"; // #40 at 0x024A
144 Utf8 "(Ljava/lang/Object;)V"; // #41 at 0x0254
145 Utf8 "java/lang/Object"; // #42 at 0x026C
146 Utf8 "java/lang/System"; // #43 at 0x027F
147 Method #84 #21; // #44 at 0x0292
148 NameAndType #20 #47; // #45 at 0x0297
149 MethodHandle 6b #82; // #46 at 0x029C
150 Utf8 "()V"; // #47 at 0x02A0
151 String #62; // #48 at 0x02A6
152 String #64; // #49 at 0x02A9
153 class #43; // #50 at 0x02AC
154 class #42; // #51 at 0x02AF
155 String #65; // #52 at 0x02B2
156 String #66; // #53 at 0x02B5
157 String #67; // #54 at 0x02B8
158 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #55 at 0x02BB
159 Utf8 "main"; // #56 at 0x0341
160 String #68; // #57 at 0x0348
161 MethodHandle 6b #32; // #58 at 0x034B
162 Utf8 "bsm1arg"; // #59 at 0x034F
163 NameAndType #25 #83; // #60 at 0x0359
164 Utf8 "In bsm4arg"; // #61 at 0x035E
165 Utf8 "hello6"; // #62 at 0x036B
166 NameAndType #59 #31; // #63 at 0x0374
167 Utf8 "hello5"; // #64 at 0x0379
168 Utf8 "hello4"; // #65 at 0x0382
169 Utf8 "hello3"; // #66 at 0x038B
170 Utf8 "hello2"; // #67 at 0x0394
171 Utf8 "hello1"; // #68 at 0x039D
172 Utf8 "bsm2arg"; // #69 at 0x03A6
173 Utf8 "Ljava/io/PrintStream;"; // #70 at 0x03B0
174 Utf8 "<init>"; // #71 at 0x03C8
175 Utf8 "CondyNestedResolution"; // #72 at 0x03D1
176 Dynamic 7s #12; // #73 at 0x03E9
177 Dynamic 6s #12; // #74 at 0x03EE
178 Dynamic 5s #12; // #75 at 0x03F3
179 Dynamic 4s #12; // #76 at 0x03F8
180 Dynamic 3s #12; // #77 at 0x03FD
181 Dynamic 0s #12; // #78 at 0x0402
182 Dynamic 1s #12; // #79 at 0x0407
183 Dynamic 2s #12; // #80 at 0x040C
184 NameAndType #26 #70; // #81 at 0x0411
185 Method #84 #60; // #82 at 0x0416
186 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #83 at 0x041B
187 class #72; // #84 at 0x04C5
188 } // Constant Pool
189
190 0x0000; // access [ ]
191 #84;// this_cpx
192 #51;// super_cpx
193
194 [0] { // Interfaces
195 } // Interfaces
196
197 [0] { // fields
198 } // fields
199
200 [7] { // methods
201 { // Member at 0x04D4
202 0x0001; // access
203 #71; // name_cpx
204 #47; // sig_cpx
205 [1] { // Attributes
206 Attr(#23, 17) { // Code at 0x04DC
207 1; // max_stack
208 1; // max_locals
209 Bytes[5]{
210 0x2AB70005B1;
211 }
212 [0] { // Traps
213 } // end Traps
214 [0] { // Attributes
215 } // Attributes
216 } // end Code
217 } // Attributes
218 } // Member
219 ;
220 { // Member at 0x04F3
221 0x0009; // access
222 #59; // name_cpx
223 #31; // sig_cpx
224 [1] { // Attributes
225 Attr(#23, 29) { // Code at 0x04FB
226 4; // max_stack
227 4; // max_locals
228 Bytes[17]{
229 0xB200071203B60006;
230 0xB200072DB600062D;
231 0xB0;
232 }
233 [0] { // Traps
234 } // end Traps
235 [0] { // Attributes
236 } // Attributes
237 } // end Code
238 } // Attributes
239 } // Member
240 ;
241 { // Member at 0x051E
242 0x0009; // access
243 #69; // name_cpx
244 #55; // sig_cpx
245 [1] { // Attributes
246 Attr(#23, 37) { // Code at 0x0526
247 8; // max_stack
248 8; // max_locals
249 Bytes[25]{
250 0xB200071201B60006;
251 0xB200072DB60006B2;
252 0x00071904B600062D;
253 0xB0;
254 }
255 [0] { // Traps
256 } // end Traps
257 [0] { // Attributes
258 } // Attributes
259 } // end Code
260 } // Attributes
261 } // Member
262 ;
263 { // Member at 0x0551
264 0x0009; // access
265 #15; // name_cpx
266 #19; // sig_cpx
267 [1] { // Attributes
268 Attr(#23, 45) { // Code at 0x0559
269 19; // max_stack
270 19; // max_locals
271 Bytes[33]{
272 0xB200071202B60006;
273 0xB200072DB60006B2;
274 0x00071904B60006B2;
275 0x00071905B600062D;
276 0xB0;
277 }
278 [0] { // Traps
279 } // end Traps
280 [0] { // Attributes
281 } // Attributes
282 } // end Code
283 } // Attributes
284 } // Member
285 ;
286 { // Member at 0x058C
287 0x0009; // access
288 #25; // name_cpx
289 #83; // sig_cpx
290 [1] { // Attributes
291 Attr(#23, 53) { // Code at 0x0594
292 19; // max_stack
293 19; // max_locals
294 Bytes[41]{
295 0xB200071202B60006;
296 0xB200072DB60006B2;
297 0x00071904B60006B2;
298 0x00071905B60006B2;
299 0x00071906B600062D;
300 0xB0;
301 }
302 [0] { // Traps
303 } // end Traps
304 [0] { // Attributes
305 } // Attributes
306 } // end Code
307 } // Attributes
308 } // Member
309 ;
310 { // Member at 0x05CF
311 0x0009; // access
312 #20; // name_cpx
313 #47; // sig_cpx
314 [1] { // Attributes
315 Attr(#23, 15) { // Code at 0x05D7
316 12; // max_stack
317 12; // max_locals
318 Bytes[3]{
319 0x1204B1;
320 }
321 [0] { // Traps
322 } // end Traps
323 [0] { // Attributes
324 } // Attributes
325 } // end Code
326 } // Attributes
327 } // Member
328 ;
329 { // Member at 0x05EC
330 0x0009; // access
331 #56; // name_cpx
332 #24; // sig_cpx
333 [1] { // Attributes
334 Attr(#23, 16) { // Code at 0x05F4
335 2; // max_stack
336 2; // max_locals
337 Bytes[4]{
338 0xB80008B1;
339 }
340 [0] { // Traps
341 } // end Traps
342 [0] { // Attributes
343 } // Attributes
344 } // end Code
345 } // Attributes
346 } // Member
347 } // methods
348
349 [2] { // Attributes
350 Attr(#14, 2) { // SourceFile at 0x060C
351 #16;
352 } // end SourceFile
353 ;
354 Attr(#28, 68) { // BootstrapMethods at 0x0614
355 [9] { // bootstrap_methods
356 { // bootstrap_method
357 #36; // bootstrap_method_ref
358 [1] { // bootstrap_arguments
359 #57; // at 0x0622
360 } // bootstrap_arguments
361 } // bootstrap_method
362 ;
363 { // bootstrap_method
364 #37; // bootstrap_method_ref
365 [1] { // bootstrap_arguments
366 #54; // at 0x0628
367 } // bootstrap_arguments
368 } // bootstrap_method
369 ;
370 { // bootstrap_method
371 #38; // bootstrap_method_ref
372 [1] { // bootstrap_arguments
373 #52; // at 0x062E
374 } // bootstrap_arguments
375 } // bootstrap_method
376 ;
377 { // bootstrap_method
378 #35; // bootstrap_method_ref
379 [1] { // bootstrap_arguments
380 #48; // at 0x0634
381 } // bootstrap_arguments
382 } // bootstrap_method
383 ;
384 { // bootstrap_method
385 #58; // bootstrap_method_ref
386 [2] { // bootstrap_arguments
387 #77; // at 0x063A
388 #4; // at 0x063C
389 } // bootstrap_arguments
390 } // bootstrap_method
391 ;
392 { // bootstrap_method
393 #34; // bootstrap_method_ref
394 [1] { // bootstrap_arguments
395 #49; // at 0x0642
396 } // bootstrap_arguments
397 } // bootstrap_method
398 ;
399 { // bootstrap_method
400 #29; // bootstrap_method_ref
401 [3] { // bootstrap_arguments
402 #80; // at 0x0648
403 #76; // at 0x064A
404 #75; // at 0x064C
405 } // bootstrap_arguments
406 } // bootstrap_method
407 ;
408 { // bootstrap_method
409 #33; // bootstrap_method_ref
410 [1] { // bootstrap_arguments
411 #53; // at 0x0652
412 } // bootstrap_arguments
413 } // bootstrap_method
414 ;
415 { // bootstrap_method
416 #46; // bootstrap_method_ref
417 [4] { // bootstrap_arguments
418 #78; // at 0x0658
419 #79; // at 0x065A
420 #74; // at 0x065C
421 #73; // at 0x065E
422 } // bootstrap_arguments
423 } // bootstrap_method
424 }
425 } // end BootstrapMethods
426 } // Attributes
427 } // end class CondyNestedResolution
--- EOF ---