6379f91c00
Additional of circular nested dynamic constant test. Reviewed-by: acorn, psandoz
428 lines
14 KiB
Plaintext
428 lines
14 KiB
Plaintext
/*
|
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/*
|
|
Pseudo Java code:
|
|
|
|
class CondyNestedResolution {
|
|
public static Object bsm1arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4) {
|
|
System.out.println("In bsm1arg");
|
|
System.out.println(p4);
|
|
return p4;
|
|
}
|
|
public static Object bsm2arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4, Object p5) {
|
|
System.out.println("In bsm2arg");
|
|
System.out.println(p4);
|
|
System.out.println(p5);
|
|
return p4;
|
|
}
|
|
public static Object bsm3arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4, Object p5, Object p6) {
|
|
System.out.println("In bsm3arg");
|
|
System.out.println(p4);
|
|
System.out.println(p5);
|
|
System.out.println(p6);
|
|
return p4;
|
|
}
|
|
public static Object bsm4arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4, Object p5, Object p6, Object p7) {
|
|
System.out.println("In bsm4arg");
|
|
System.out.println(p4);
|
|
System.out.println(p5);
|
|
System.out.println(p6);
|
|
System.out.println(p7);
|
|
return p4;
|
|
}
|
|
|
|
public static void test_condy() {
|
|
// The following condy of BSM#8 results in the invocation of bootstrap method bsm4arg with the following
|
|
// parameters:
|
|
// bsm4arg(bsm1arg("hello1"),
|
|
// bsm1arg("hello2"),
|
|
// bsm3arg(bsm1arg("hello4"), bsm2arg(bsm1arg("hello6"), (circular reference to BSM#8)), bsm1arg("hello5")),
|
|
// bsm1arg("hello3"));
|
|
// JVMS 5.4.3.6 Dynamically-Computed Constant and Call Site Resolution
|
|
// Ensure that calls to bsm1arg("hello5") and bsm1arg("hello3") are never resolved due to the nested condy circularity
|
|
// which results in a StackOverflowError.
|
|
//
|
|
ldc Dynamic BSM#8;
|
|
}
|
|
public static void main(String args[]) {
|
|
CondyNestedResolution.test_condy();
|
|
}
|
|
}
|
|
|
|
BootstrapMethods:
|
|
BSM0=invokestatic CondyNestedResolution.bsm1arg("hello1");
|
|
BSM1=invokestatic CondyNestedResolution.bsm1arg("hello2");
|
|
BSM2=invokestatic CondyNestedResolution.bsm1arg("hello4");
|
|
BSM3=invokestatic CondyNestedResolution.bsm1arg("hello6");
|
|
BSM4=invokestatic CondyNestedResolution.bsm2arg(BSM#3, BSM#8);
|
|
BSM5=invokestatic CondyNestedResolution.bsm1arg("hello5");
|
|
BSM6=invokestatic CondyNestedResolution.bsm3arg(BSM#2, BSM#4, BSM#5);
|
|
BSM7=invokestatic CondyNestedResolution.bsm1arg("hello3");
|
|
BSM8=invokestatic CondyNestedResolution.bsm4arg(BSM#0, BSM#1, BSM#6, BSM#7);
|
|
|
|
Expected output:
|
|
In bsm1arg
|
|
hello1
|
|
In bsm1arg
|
|
hello2
|
|
In bsm1arg
|
|
hello4
|
|
In bsm1arg
|
|
hello6
|
|
Exception in thread "main" java.lang.StackOverflowError
|
|
at java.base/java.lang.invoke.MethodHandleNatives.copyOutBootstrapArguments(Native Method)
|
|
*/
|
|
|
|
|
|
class CondyNestedResolution {
|
|
0xCAFEBABE;
|
|
0; // minor version
|
|
55; // version
|
|
[85] { // Constant Pool
|
|
; // first element is empty
|
|
String #22; // #1 at 0x0A
|
|
String #61; // #2 at 0x0D
|
|
String #11; // #3 at 0x10
|
|
Dynamic 8s #12; // #4 at 0x13
|
|
Method #51 #10; // #5 at 0x18
|
|
Method #13 #39; // #6 at 0x1D
|
|
Field #50 #81; // #7 at 0x22
|
|
Method #84 #45; // #8 at 0x27
|
|
Utf8 "java/io/PrintStream"; // #9 at 0x2C
|
|
NameAndType #71 #47; // #10 at 0x42
|
|
Utf8 "In bsm1arg"; // #11 at 0x47
|
|
NameAndType #18 #17; // #12 at 0x54
|
|
class #9; // #13 at 0x59
|
|
Utf8 "SourceFile"; // #14 at 0x5C
|
|
Utf8 "bsm3arg"; // #15 at 0x69
|
|
Utf8 "CondyNestedResolution.jasm"; // #16 at 0x73
|
|
Utf8 "Ljava/lang/String;"; // #17 at 0x90
|
|
Utf8 "name"; // #18 at 0xA5
|
|
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
|
|
Utf8 "test_condy"; // #20 at 0x0144
|
|
NameAndType #15 #19; // #21 at 0x0151
|
|
Utf8 "In bsm2arg"; // #22 at 0x0156
|
|
Utf8 "Code"; // #23 at 0x0163
|
|
Utf8 "([Ljava/lang/String;)V"; // #24 at 0x016A
|
|
Utf8 "bsm4arg"; // #25 at 0x0183
|
|
Utf8 "out"; // #26 at 0x018D
|
|
NameAndType #69 #55; // #27 at 0x0193
|
|
Utf8 "BootstrapMethods"; // #28 at 0x0198
|
|
MethodHandle 6b #44; // #29 at 0x01AB
|
|
Method #84 #63; // #30 at 0x01AF
|
|
Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #31 at 0x01B4
|
|
Method #84 #27; // #32 at 0x0228
|
|
MethodHandle 6b #30; // #33 at 0x022D
|
|
MethodHandle 6b #30; // #34 at 0x0231
|
|
MethodHandle 6b #30; // #35 at 0x0235
|
|
MethodHandle 6b #30; // #36 at 0x0239
|
|
MethodHandle 6b #30; // #37 at 0x023D
|
|
MethodHandle 6b #30; // #38 at 0x0241
|
|
NameAndType #40 #41; // #39 at 0x0245
|
|
Utf8 "println"; // #40 at 0x024A
|
|
Utf8 "(Ljava/lang/Object;)V"; // #41 at 0x0254
|
|
Utf8 "java/lang/Object"; // #42 at 0x026C
|
|
Utf8 "java/lang/System"; // #43 at 0x027F
|
|
Method #84 #21; // #44 at 0x0292
|
|
NameAndType #20 #47; // #45 at 0x0297
|
|
MethodHandle 6b #82; // #46 at 0x029C
|
|
Utf8 "()V"; // #47 at 0x02A0
|
|
String #62; // #48 at 0x02A6
|
|
String #64; // #49 at 0x02A9
|
|
class #43; // #50 at 0x02AC
|
|
class #42; // #51 at 0x02AF
|
|
String #65; // #52 at 0x02B2
|
|
String #66; // #53 at 0x02B5
|
|
String #67; // #54 at 0x02B8
|
|
Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #55 at 0x02BB
|
|
Utf8 "main"; // #56 at 0x0341
|
|
String #68; // #57 at 0x0348
|
|
MethodHandle 6b #32; // #58 at 0x034B
|
|
Utf8 "bsm1arg"; // #59 at 0x034F
|
|
NameAndType #25 #83; // #60 at 0x0359
|
|
Utf8 "In bsm4arg"; // #61 at 0x035E
|
|
Utf8 "hello6"; // #62 at 0x036B
|
|
NameAndType #59 #31; // #63 at 0x0374
|
|
Utf8 "hello5"; // #64 at 0x0379
|
|
Utf8 "hello4"; // #65 at 0x0382
|
|
Utf8 "hello3"; // #66 at 0x038B
|
|
Utf8 "hello2"; // #67 at 0x0394
|
|
Utf8 "hello1"; // #68 at 0x039D
|
|
Utf8 "bsm2arg"; // #69 at 0x03A6
|
|
Utf8 "Ljava/io/PrintStream;"; // #70 at 0x03B0
|
|
Utf8 "<init>"; // #71 at 0x03C8
|
|
Utf8 "CondyNestedResolution"; // #72 at 0x03D1
|
|
Dynamic 7s #12; // #73 at 0x03E9
|
|
Dynamic 6s #12; // #74 at 0x03EE
|
|
Dynamic 5s #12; // #75 at 0x03F3
|
|
Dynamic 4s #12; // #76 at 0x03F8
|
|
Dynamic 3s #12; // #77 at 0x03FD
|
|
Dynamic 0s #12; // #78 at 0x0402
|
|
Dynamic 1s #12; // #79 at 0x0407
|
|
Dynamic 2s #12; // #80 at 0x040C
|
|
NameAndType #26 #70; // #81 at 0x0411
|
|
Method #84 #60; // #82 at 0x0416
|
|
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
|
|
class #72; // #84 at 0x04C5
|
|
} // Constant Pool
|
|
|
|
0x0000; // access [ ]
|
|
#84;// this_cpx
|
|
#51;// super_cpx
|
|
|
|
[0] { // Interfaces
|
|
} // Interfaces
|
|
|
|
[0] { // fields
|
|
} // fields
|
|
|
|
[7] { // methods
|
|
{ // Member at 0x04D4
|
|
0x0001; // access
|
|
#71; // name_cpx
|
|
#47; // sig_cpx
|
|
[1] { // Attributes
|
|
Attr(#23, 17) { // Code at 0x04DC
|
|
1; // max_stack
|
|
1; // max_locals
|
|
Bytes[5]{
|
|
0x2AB70005B1;
|
|
}
|
|
[0] { // Traps
|
|
} // end Traps
|
|
[0] { // Attributes
|
|
} // Attributes
|
|
} // end Code
|
|
} // Attributes
|
|
} // Member
|
|
;
|
|
{ // Member at 0x04F3
|
|
0x0009; // access
|
|
#59; // name_cpx
|
|
#31; // sig_cpx
|
|
[1] { // Attributes
|
|
Attr(#23, 29) { // Code at 0x04FB
|
|
4; // max_stack
|
|
4; // max_locals
|
|
Bytes[17]{
|
|
0xB200071203B60006;
|
|
0xB200072DB600062D;
|
|
0xB0;
|
|
}
|
|
[0] { // Traps
|
|
} // end Traps
|
|
[0] { // Attributes
|
|
} // Attributes
|
|
} // end Code
|
|
} // Attributes
|
|
} // Member
|
|
;
|
|
{ // Member at 0x051E
|
|
0x0009; // access
|
|
#69; // name_cpx
|
|
#55; // sig_cpx
|
|
[1] { // Attributes
|
|
Attr(#23, 37) { // Code at 0x0526
|
|
8; // max_stack
|
|
8; // max_locals
|
|
Bytes[25]{
|
|
0xB200071201B60006;
|
|
0xB200072DB60006B2;
|
|
0x00071904B600062D;
|
|
0xB0;
|
|
}
|
|
[0] { // Traps
|
|
} // end Traps
|
|
[0] { // Attributes
|
|
} // Attributes
|
|
} // end Code
|
|
} // Attributes
|
|
} // Member
|
|
;
|
|
{ // Member at 0x0551
|
|
0x0009; // access
|
|
#15; // name_cpx
|
|
#19; // sig_cpx
|
|
[1] { // Attributes
|
|
Attr(#23, 45) { // Code at 0x0559
|
|
19; // max_stack
|
|
19; // max_locals
|
|
Bytes[33]{
|
|
0xB200071202B60006;
|
|
0xB200072DB60006B2;
|
|
0x00071904B60006B2;
|
|
0x00071905B600062D;
|
|
0xB0;
|
|
}
|
|
[0] { // Traps
|
|
} // end Traps
|
|
[0] { // Attributes
|
|
} // Attributes
|
|
} // end Code
|
|
} // Attributes
|
|
} // Member
|
|
;
|
|
{ // Member at 0x058C
|
|
0x0009; // access
|
|
#25; // name_cpx
|
|
#83; // sig_cpx
|
|
[1] { // Attributes
|
|
Attr(#23, 53) { // Code at 0x0594
|
|
19; // max_stack
|
|
19; // max_locals
|
|
Bytes[41]{
|
|
0xB200071202B60006;
|
|
0xB200072DB60006B2;
|
|
0x00071904B60006B2;
|
|
0x00071905B60006B2;
|
|
0x00071906B600062D;
|
|
0xB0;
|
|
}
|
|
[0] { // Traps
|
|
} // end Traps
|
|
[0] { // Attributes
|
|
} // Attributes
|
|
} // end Code
|
|
} // Attributes
|
|
} // Member
|
|
;
|
|
{ // Member at 0x05CF
|
|
0x0009; // access
|
|
#20; // name_cpx
|
|
#47; // sig_cpx
|
|
[1] { // Attributes
|
|
Attr(#23, 15) { // Code at 0x05D7
|
|
12; // max_stack
|
|
12; // max_locals
|
|
Bytes[3]{
|
|
0x1204B1;
|
|
}
|
|
[0] { // Traps
|
|
} // end Traps
|
|
[0] { // Attributes
|
|
} // Attributes
|
|
} // end Code
|
|
} // Attributes
|
|
} // Member
|
|
;
|
|
{ // Member at 0x05EC
|
|
0x0009; // access
|
|
#56; // name_cpx
|
|
#24; // sig_cpx
|
|
[1] { // Attributes
|
|
Attr(#23, 16) { // Code at 0x05F4
|
|
2; // max_stack
|
|
2; // max_locals
|
|
Bytes[4]{
|
|
0xB80008B1;
|
|
}
|
|
[0] { // Traps
|
|
} // end Traps
|
|
[0] { // Attributes
|
|
} // Attributes
|
|
} // end Code
|
|
} // Attributes
|
|
} // Member
|
|
} // methods
|
|
|
|
[2] { // Attributes
|
|
Attr(#14, 2) { // SourceFile at 0x060C
|
|
#16;
|
|
} // end SourceFile
|
|
;
|
|
Attr(#28, 68) { // BootstrapMethods at 0x0614
|
|
[9] { // bootstrap_methods
|
|
{ // bootstrap_method
|
|
#36; // bootstrap_method_ref
|
|
[1] { // bootstrap_arguments
|
|
#57; // at 0x0622
|
|
} // bootstrap_arguments
|
|
} // bootstrap_method
|
|
;
|
|
{ // bootstrap_method
|
|
#37; // bootstrap_method_ref
|
|
[1] { // bootstrap_arguments
|
|
#54; // at 0x0628
|
|
} // bootstrap_arguments
|
|
} // bootstrap_method
|
|
;
|
|
{ // bootstrap_method
|
|
#38; // bootstrap_method_ref
|
|
[1] { // bootstrap_arguments
|
|
#52; // at 0x062E
|
|
} // bootstrap_arguments
|
|
} // bootstrap_method
|
|
;
|
|
{ // bootstrap_method
|
|
#35; // bootstrap_method_ref
|
|
[1] { // bootstrap_arguments
|
|
#48; // at 0x0634
|
|
} // bootstrap_arguments
|
|
} // bootstrap_method
|
|
;
|
|
{ // bootstrap_method
|
|
#58; // bootstrap_method_ref
|
|
[2] { // bootstrap_arguments
|
|
#77; // at 0x063A
|
|
#4; // at 0x063C
|
|
} // bootstrap_arguments
|
|
} // bootstrap_method
|
|
;
|
|
{ // bootstrap_method
|
|
#34; // bootstrap_method_ref
|
|
[1] { // bootstrap_arguments
|
|
#49; // at 0x0642
|
|
} // bootstrap_arguments
|
|
} // bootstrap_method
|
|
;
|
|
{ // bootstrap_method
|
|
#29; // bootstrap_method_ref
|
|
[3] { // bootstrap_arguments
|
|
#80; // at 0x0648
|
|
#76; // at 0x064A
|
|
#75; // at 0x064C
|
|
} // bootstrap_arguments
|
|
} // bootstrap_method
|
|
;
|
|
{ // bootstrap_method
|
|
#33; // bootstrap_method_ref
|
|
[1] { // bootstrap_arguments
|
|
#53; // at 0x0652
|
|
} // bootstrap_arguments
|
|
} // bootstrap_method
|
|
;
|
|
{ // bootstrap_method
|
|
#46; // bootstrap_method_ref
|
|
[4] { // bootstrap_arguments
|
|
#78; // at 0x0658
|
|
#79; // at 0x065A
|
|
#74; // at 0x065C
|
|
#73; // at 0x065E
|
|
} // bootstrap_arguments
|
|
} // bootstrap_method
|
|
}
|
|
} // end BootstrapMethods
|
|
} // Attributes
|
|
} // end class CondyNestedResolution
|