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 * This test contains a CONSTANT_Dynamic_info structure whose bootstrap_method_attr_index 26 * points to a BSM for an invokedynamic. Both the condy & indy point at element 0 in the 27 * bootstrap methods array. BootstrapMethodError expected. 28 */ 29 30 /* 31 class CondyUsesIndyBSM { 32 CondyUsesIndyBSM() { } 33 public static Object Condybsm(java.lang.invoke.MethodHandles$Lookup, java.lang.String, java.lang.Class) { 34 System.out.println("In Condybsm"); 35 return String(0); 36 } 37 public static int foo() { 38 System.out.println("In Indybsm target CallSite method foo"); 39 return 100; 40 } 41 public static MethodHandle MH_foo() { 42 // Constructs a MethodHandle for foo 43 Lookup lookup = MethodHandles.lookup(); 44 MethodType mt = MethodType.methodType(int.class); 45 return lookup.findStatic(CondyUsesIndyBSM.class, "foo", mt); 46 } 47 public static CallSite Indybsm(java.lang.invoke.MethodHandles$Lookup, java.lang.String, java.lang.invoke.MethodType) { 48 return new CallSite(CondyUsesIndyBSM.MH_foo()); 49 } 50 public static Object m() { 51 // invokedynamic where the BSM = slot #0 in the BootstrapMethods array is CondyUsesIndyBSM.Indybsm() -> succeeds 52 // ldc_w dynamic where the BSM = slot #0 in the BootstrapMethods array is CondyUsesIndyBSM.Indybsm() -> receives a BootstrapMethodError 53 return of ldc's Object; 54 } 55 public static void main(String[] args) { 56 CondyUsesIndyBSM.m(); 57 return; 58 } 59 60 BootstrapMethods: 61 0: #70 REF_invokeStatic CondyUsesIndyBSM.Indybsm:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; 62 Method arguments: 63 1: #75 REF_invokeStatic CondyUsesIndyBSM.Condybsm:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object; 64 Method arguments: 65 } 66 */ 67 68 class CondyUsesIndyBSM { 69 0xCAFEBABE; 70 0; // minor version 71 55; // version 72 [] { // Constant Pool 73 ; // first element is empty 74 Utf8 "java/lang/Object"; // #1 75 class #1; // #2 76 Utf8 "<init>"; // #3 77 Utf8 "()V"; // #4 78 NameAndType #3 #4; // #5 79 Method #2 #5; // #6 80 Utf8 "Code"; // #7 81 Utf8 "java/lang/System"; // #8 82 class #8; // #9 83 Utf8 "out"; // #10 84 Utf8 "Ljava/io/PrintStream;"; // #11 85 NameAndType #10 #11; // #12 86 Field #9 #12; // #13 87 Utf8 "In Condybsm"; // #14 88 String #14; // #15 89 Utf8 "java/io/PrintStream"; // #16 90 class #16; // #17 91 Utf8 "println"; // #18 92 Utf8 "(Ljava/lang/String;)V"; // #19 93 NameAndType #18 #19; // #20 94 Method #17 #20; // #21 95 Utf8 "0"; // #22 96 String #22; // #23 97 Utf8 "Condybsm"; // #24 98 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"; // #25 99 Utf8 "In Indybsm target CallSite method foo"; // #26 100 String #26; // #27 101 Utf8 "foo"; // #28 102 Utf8 "()I"; // #29 103 Utf8 "java/lang/invoke/MethodHandles"; // #30 104 class #30; // #31 105 Utf8 "lookup"; // #32 106 Utf8 "()Ljava/lang/invoke/MethodHandles$Lookup;"; // #33 107 NameAndType #32 #33; // #34 108 Method #31 #34; // #35 109 Utf8 "CondyUsesIndyBSM"; // #36 110 class #36; // #37 111 String #28; // #38 112 Utf8 "java/lang/Integer"; // #39 113 class #39; // #40 114 Utf8 "TYPE"; // #41 115 Utf8 "Ljava/lang/Class;"; // #42 116 NameAndType #41 #42; // #43 117 Field #40 #43; // #44 118 Utf8 "java/lang/invoke/MethodType"; // #45 119 class #45; // #46 120 Utf8 "methodType"; // #47 121 Utf8 "(Ljava/lang/Class;)Ljava/lang/invoke/MethodType;"; // #48 122 NameAndType #47 #48; // #49 123 Method #46 #49; // #50 124 Utf8 "java/lang/invoke/MethodHandles$Lookup"; // #51 125 class #51; // #52 126 Utf8 "findStatic"; // #53 127 Utf8 "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;"; // #54 128 NameAndType #53 #54; // #55 129 Method #52 #55; // #56 130 Utf8 "MH_foo"; // #57 131 Utf8 "()Ljava/lang/invoke/MethodHandle;"; // #58 132 Utf8 "java/lang/invoke/ConstantCallSite"; // #59 133 class #59; // #60 134 NameAndType #57 #58; // #61 135 Method #37 #61; // #62 136 Utf8 "(Ljava/lang/invoke/MethodHandle;)V"; // #63 137 NameAndType #3 #63; // #64 138 Method #60 #64; // #65 139 Utf8 "Indybsm"; // #66 140 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"; // #67 141 NameAndType #66 #67; // #68 142 Method #37 #68; // #69 143 MethodHandle 6b #69; // #70 144 NameAndType #28 #29; // #71 145 InvokeDynamic 0s #71; // #72 146 NameAndType #24 #25; // #73 147 Method #37 #73; // #74 148 MethodHandle 6b #74; // #75 149 Utf8 "name"; // #76 150 Utf8 "Ljava/lang/Object;"; // #77 151 NameAndType #76 #77; // #78 152 Dynamic 0s #78; // #79 153 Utf8 "m"; // #80 154 Utf8 "()Ljava/lang/Object;"; // #81 155 NameAndType #80 #81; // #82 156 Method #37 #82; // #83 157 Utf8 "main"; // #84 158 Utf8 "([Ljava/lang/String;)V"; // #85 159 Utf8 "BootstrapMethods"; // #86 160 Utf8 "CondyUsesIndyBSM"; // #87 161 class #87; // #88 162 } // Constant Pool 163 164 0x0000; // access 165 #88;// this_cpx 166 #2;// super_cpx 167 168 [] { // Interfaces 169 } // Interfaces 170 171 [] { // fields 172 } // fields 173 174 [] { // methods 175 { // Member 176 0x0001; // access 177 #3; // name_cpx 178 #4; // sig_cpx 179 [] { // Attributes 180 Attr(#7) { // Code 181 1; // max_stack 182 1; // max_locals 183 Bytes[]{ 184 0x2AB70006B1; 185 } 186 [] { // Traps 187 } // end Traps 188 [] { // Attributes 189 } // Attributes 190 } // end Code 191 } // Attributes 192 } // Member 193 ; 194 { // Member 195 0x0009; // access 196 #24; // name_cpx 197 #25; // sig_cpx 198 [] { // Attributes 199 Attr(#7) { // Code 200 2; // max_stack 201 3; // max_locals 202 Bytes[]{ 203 0xB2000D120FB60015; 204 0x1217B0; 205 } 206 [] { // Traps 207 } // end Traps 208 [] { // Attributes 209 } // Attributes 210 } // end Code 211 } // Attributes 212 } // Member 213 ; 214 { // Member 215 0x0009; // access 216 #28; // name_cpx 217 #29; // sig_cpx 218 [] { // Attributes 219 Attr(#7) { // Code 220 2; // max_stack 221 0; // max_locals 222 Bytes[]{ 223 0xB2000D121BB60015; 224 0x1064AC; 225 } 226 [] { // Traps 227 } // end Traps 228 [] { // Attributes 229 } // Attributes 230 } // end Code 231 } // Attributes 232 } // Member 233 ; 234 { // Member 235 0x0009; // access 236 #57; // name_cpx 237 #58; // sig_cpx 238 [] { // Attributes 239 Attr(#7) { // Code 240 4; // max_stack 241 0; // max_locals 242 Bytes[]{ 243 0xB8002312251226B2; 244 0x002CB80032B60038; 245 0xB0; 246 } 247 [] { // Traps 248 } // end Traps 249 [] { // Attributes 250 } // Attributes 251 } // end Code 252 } // Attributes 253 } // Member 254 ; 255 { // Member 256 0x0009; // access 257 #66; // name_cpx 258 #67; // sig_cpx 259 [] { // Attributes 260 Attr(#7) { // Code 261 3; // max_stack 262 3; // max_locals 263 Bytes[]{ 264 0xBB003C59B8003EB7; 265 0x0041B0; 266 } 267 [] { // Traps 268 } // end Traps 269 [] { // Attributes 270 } // Attributes 271 } // end Code 272 } // Attributes 273 } // Member 274 ; 275 { // Member 276 0x0009; // access 277 #80; // name_cpx 278 #81; // sig_cpx 279 [] { // Attributes 280 Attr(#7) { // Code 281 2; // max_stack 282 0; // max_locals 283 Bytes[]{ 284 0xBA0048000013004F; 285 0xB0; 286 } 287 [] { // Traps 288 } // end Traps 289 [] { // Attributes 290 } // Attributes 291 } // end Code 292 } // Attributes 293 } // Member 294 ; 295 { // Member 296 0x0009; // access 297 #84; // name_cpx 298 #85; // sig_cpx 299 [] { // Attributes 300 Attr(#7) { // Code 301 1; // max_stack 302 1; // max_locals 303 Bytes[]{ 304 0xB80053B1; 305 } 306 [] { // Traps 307 } // end Traps 308 [] { // Attributes 309 } // Attributes 310 } // end Code 311 } // Attributes 312 } // Member 313 } // methods 314 315 [] { // Attributes 316 Attr(#86) { // BootstrapMethods 317 [] { // bootstrap_methods 318 { // bootstrap_method 319 #70; // bootstrap_method_ref 320 [] { // bootstrap_arguments 321 } // bootstrap_arguments 322 } // bootstrap_method 323 ; 324 { // bootstrap_method 325 #75; // bootstrap_method_ref 326 [] { // bootstrap_arguments 327 } // bootstrap_arguments 328 } // bootstrap_method 329 } 330 } // end BootstrapMethods 331 } // Attributes 332 } // end class CondyUsesIndyBSM