1 /*
   2  * Copyright (c) 2011, 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 /*
  26  * @test
  27  *
  28  * @summary converted from VM Testbase vm/mlvm/indy/func/java/thisAsArgument.
  29  * VM Testbase keywords: [feature_mlvm]
  30  * VM Testbase readme:
  31  * DESCRIPTION
  32  *     The test is written for a CR 6927831:
  33  *     InvokeDynamic throws NoClassDefFoundError in the following test:
  34  *     package test;
  35  *     import java.dyn.InvokeDynamic;
  36  *     import java.dyn.InvokeDynamicBootstrapError;
  37  *     public class Self {
  38  *       public static void main(String[] args) {
  39  *             try {
  40  *                 InvokeDynamic.<void>greet(new Self());
  41  *             } catch ( InvokeDynamicBootstrapError e ) {
  42  *                 System.out.println("TEST PASSED");
  43  *             } catch ( Throwable t ) {
  44  *                 System.err.println("Oops!");
  45  *                 t.printStackTrace();
  46  *             }
  47  *         }
  48  *     }
  49  *     ...when it is launched with -classpath:
  50  *     $ java -classpath bin test.Self
  51  *     Oops!
  52  *     java.lang.NoClassDefFoundError: test/Self
  53  *         at test.Self.main(Self.java:10)
  54  *     If we replace -classpath with -Xbootclasspath:
  55  *     $ java -Xbootclasspath/a:bin test.Self
  56  *     TEST PASSED
  57  *
  58  * @library /vmTestbase
  59  *          /test/lib
  60  * @run driver jdk.test.lib.FileInstaller . .
  61  *
  62  * @comment build test class and indify classes
  63  * @build vm.mlvm.indy.func.java.thisAsArgument.INDIFY_Test
  64  * @run driver vm.mlvm.share.IndifiedClassesBuilder
  65  *
  66  * @run main/othervm vm.mlvm.indy.func.java.thisAsArgument.INDIFY_Test
  67  */
  68 
  69 package vm.mlvm.indy.func.java.thisAsArgument;
  70 
  71 import java.lang.invoke.CallSite;
  72 import java.lang.invoke.MethodHandle;
  73 import java.lang.invoke.MethodHandles;
  74 import java.lang.invoke.MethodType;
  75 import java.util.Arrays;
  76 
  77 import vm.mlvm.share.MlvmTest;
  78 
  79 public class INDIFY_Test extends MlvmTest {
  80 
  81     public static void main(String[] args) { MlvmTest.launch(args); }
  82 
  83     // Indify-specific bootstrap trampoline
  84     private static MethodType MT_bootstrap() {
  85         return MethodType.methodType(Object.class, Object.class, Object.class, Object.class);
  86     }
  87     private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
  88         return MethodHandles.lookup().findStatic(
  89                 INDIFY_Test.class,
  90                 "bootstrap",
  91                 MT_bootstrap());
  92     }
  93 
  94     public static Object bootstrap(Object lookup, Object name, Object type) throws Throwable {
  95         getLog().trace(0, "bootstrap(" +
  96                 Arrays.asList(lookup.getClass(), lookup,
  97                         name.getClass(), name,
  98                         type.getClass(), type) + ") called");
  99 
 100         return new Object();
 101     }
 102 
 103     public static void target(INDIFY_Test arg) {
 104         getLog().trace(0, "target called: arg=" + arg);
 105         new Throwable("Stack trace").printStackTrace(getLog().getOutStream());
 106     }
 107 
 108     // Indify-specific invokedynamic call substitution
 109     private static MethodHandle INDY_call;
 110     private static MethodHandle INDY_call() throws Throwable {
 111         if (INDY_call != null)
 112             return INDY_call;
 113 
 114         CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
 115                 MethodHandles.lookup(),
 116                 "target",
 117                 MethodType.methodType(void.class, INDIFY_Test.class));
 118 
 119         return cs.dynamicInvoker();
 120     }
 121 
 122     @Override
 123     public boolean run() throws Throwable {
 124         try {
 125             // Substitution for:
 126             // InvokeDynamic.target(new INDIFY_Test());
 127             INDIFY_Test test = new INDIFY_Test();
 128             INDY_call().invokeExact(test);
 129             getLog().complain("Target method should not be called");
 130             return false;
 131         } catch ( BootstrapMethodError e ) {
 132             getLog().trace(0, "Caught exception as expected:");
 133             e.printStackTrace(getLog().getOutStream());
 134             return true;
 135         } catch ( Throwable t ) {
 136             getLog().complain("Wrong exception caught!");
 137             t.printStackTrace(getLog().getOutStream());
 138             return false;
 139         }
 140     }
 141 }