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 package vm.mlvm.indy.func.java.rawRetypes;
  25 
  26 import java.lang.invoke.CallSite;
  27 import java.lang.invoke.ConstantCallSite;
  28 import java.lang.invoke.MethodHandle;
  29 import java.lang.invoke.MethodHandles;
  30 import java.lang.invoke.MethodType;
  31 
  32  public class INDIFY_Test6998541 {
  33      private static final int N = 100000;
  34 
  35 #
  36 # String[] types = new String[] { "void", "boolean", "byte", "char", "short", "int", "long", "float", "double" };
  37 #
  38 # String[][] primTypes = new String[][] {
  39 # new String[] { "boolean", "Boolean", "false" },
  40 # new String[] { "byte", "Byte", "0" },
  41 # new String[] { "char", "Character", "0" },
  42 # new String[] { "short", "Short", "0" },
  43 # new String[] { "int", "Integer", "0" },
  44 # new String[] { "long", "Long", "0L" },
  45 # new String[] { "float", "Float", "0f" },
  46 # new String[] { "double", "Double", "0d" }
  47 # };
  48 #
  49 
  50      public static void main(String[] args) throws Throwable {
  51 #
  52 # for ( String[] t : primTypes ) {
  53 #
  54          @("do" + t[0]) ();
  55 #
  56 # }
  57 #
  58      }
  59 
  60 #
  61 # for ( String[] t : primTypes ) {
  62 #
  63      private static void @("do" + t[0]) () throws Throwable {
  64          System.out.println(@("\"do" + t[0] + "\""));
  65 
  66 #     if ( t[0].equals("boolean") ) {
  67 #
  68          for (int i = 0; i < N; i++ ) {
  69              @(t[0])2prim(false);
  70              @(t[0])2prim(true);
  71 #
  72 #     } else {
  73 #
  74          @(t[0]) x = @(t[1]).MIN_VALUE;
  75          @(t[0]) D = @(t[1]).MAX_VALUE / (N / 2);
  76          for (int i = 0; i < N; i++, x += D) {
  77 #
  78              @(t[0])2prim(x);
  79 
  80 #         if ( t[0].equals("int") ) {
  81              void2prim(x);
  82              prim2void(x);
  83              prim2prim(x);
  84 #         }
  85 #     }
  86 
  87 #
  88          }
  89      }
  90 # }
  91 #
  92 
  93      private static void void2prim(int i) throws Throwable {
  94 #
  95 # for ( String[] t : primTypes ) {
  96 #
  97          assertEquals(        @(t[2]), (@(t[0])) INDY_@(t[0])_foo_void().invokeExact());  // void -> @(t[0])
  98 #
  99 # }
 100 #
 101      }
 102 
 103 #
 104 # for ( String[] f : primTypes ) {
 105 #
 106      private static void @(f[0])2prim(@(f[0]) x) throws Throwable {
 107 #        if ( f[0].equals("boolean") ) {
 108          int i = x ? 1 : 0;
 109 #        } else {
 110          @(f[0]) i = x;
 111 #        }
 112 #
 113 #     for ( String[] t : primTypes ) {
 114 #        if ( t[0].equals("boolean") ) {
 115 #        if ( f[0].equals("boolean") ) {
 116              boolean z = x;
 117 #        } else {
 118              boolean z = (x != 0);
 119 #        }
 120          assertEquals(z, (@(t[0])) INDY_@(t[0])_foo_@(f[0])().invokeExact(x));  // @(f[0]) -> @(t[0])
 121 #          } else {
 122          assertEquals((@(t[0])) i, (@(t[0])) INDY_@(t[0])_foo_@(f[0])().invokeExact(x));  // @(f[0]) -> @(t[0])
 123 #          }
 124 #     }
 125 #
 126      }
 127 #
 128 # }
 129 #
 130 
 131      private static void prim2void(int x) throws Throwable {
 132 #
 133 # for ( String[] f : primTypes ) {
 134 #        if ( f[0].equals("boolean") ) {
 135              boolean z = (x != 0);
 136               INDY_void_foo_@(f[0])().invokeExact(z);  // @(f[0]) -> void
 137 #        } else {
 138               INDY_void_foo_@(f[0])().invokeExact((@(f[0])) x);  // @(f[0]) -> void
 139 #        }
 140 # }
 141 #
 142      }
 143 
 144      private static void void2void() throws Throwable {
 145          INDY_void_foo_void().invokeExact();  // void  -> void
 146      }
 147 
 148      private static void prim2prim(int x) throws Throwable {
 149 #
 150 # for ( String[] f : primTypes ) {
 151 #        if ( f[0].equals("boolean") ) {
 152          boolean z = (x != 0);
 153          assertEquals(         z, (@(f[0])) INDY_@(f[0])_spread_@(f[0])().invokeExact(z));  // spread: @(f[0]) -> @(f[0])
 154 #        } else {
 155          assertEquals((@(f[0])) x, (@(f[0])) INDY_@(f[0])_spread_@(f[0])().invokeExact((@(f[0])) x));  // spread: @(f[0]) -> @(f[0])
 156 #        }
 157 # }
 158      }
 159 
 160      private static void assertEquals(Object o, Object o2) {
 161          if (!o.equals(o2))
 162              throw new AssertionError("expected: " + o + ", found: " + o2);
 163      }
 164 
 165 #
 166 # String[] names = new String[] { "foo", "spread" };
 167 #
 168 # for ( String ret : types ) {
 169 #     for ( String arg : types ) {
 170 #
 171 #          String argParam, argTypeParam, methodTypeArg;
 172 #          if ( ! arg.equals("void") ) {
 173 #              argParam = "x";
 174 #              argTypeParam = arg + " x";
 175 #              methodTypeArg = ", " + arg + ".class";
 176 #          } else {
 177 #              argTypeParam = argParam = methodTypeArg = "";
 178 #          }
 179 #
 180 #          for ( String name : names ) {
 181 #             String methodName = "INDY_" + ret + "_" + name + "_"  + arg;
 182 #             String wrapperName = "indyWrapper_" + ret + "_" + name;
 183 
 184     private static MethodHandle @methodName;
 185     private static MethodHandle @methodName () throws Throwable {
 186         if ( @methodName != null ) return @methodName;
 187         return ((CallSite) MH_bootstrap().invokeWithArguments(
 188                     MethodHandles.lookup(),
 189                     @("\"" + name + "\""),
 190                     MethodType.methodType(@ret .class @methodTypeArg))).dynamicInvoker();
 191     }
 192 
 193 #
 194 #           }
 195 #       }
 196 # }
 197 #
 198 
 199 
 200     private static MethodType MT_bootstrap () { return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); }
 201 
 202     private static MethodHandle MH_bootstrap () throws Throwable {
 203         return MethodHandles.lookup().findStatic(INDIFY_Test6998541.class, "bootstrap", MT_bootstrap());
 204     }
 205 
 206      private static CallSite bootstrap(MethodHandles.Lookup declaring, String name, MethodType methodType) throws Throwable {
 207          MethodHandles.Lookup lookup = MethodHandles.lookup();
 208          MethodHandle mh;
 209          if (methodType.parameterCount() == 0) {
 210              mh = lookup.findStatic(INDIFY_Test6998541.class, "identity", MethodType.methodType(void.class));
 211          } else {
 212              Class<?> type = methodType.parameterType(0);
 213              mh = lookup.findStatic(INDIFY_Test6998541.class, "identity", MethodType.methodType(type, type));
 214 
 215              if ("spread".equals(name)) {
 216                  int paramCount = mh.type().parameterCount();
 217                  mh = mh.asSpreader(Object[].class, paramCount).asCollector(Object[].class, paramCount);
 218              }
 219          }
 220          mh = mh.asType(methodType);
 221          return new ConstantCallSite(mh);
 222      }
 223 
 224 # for ( String t : types ) {
 225 #    if ( t.equals("void") ) continue;
 226      private static @t identity(@t v) { return v; }
 227 # }
 228      private static void identity() {}
 229 }