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/*
25Pseudo Java code:
26
27class 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
73BootstrapMethods:
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
84Expected 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
98class 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
428