1 /*
   2  * Copyright (c) 2017, 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 import jdk.incubator.mvt.ValueType;
  24 import jdk.incubator.mvt.ValueCapableClass;
  25 import org.testng.annotations.Test;
  26 
  27 import java.lang.invoke.MethodHandle;
  28 import java.lang.invoke.MethodHandles;
  29 
  30 import static java.lang.invoke.MethodType.methodType;
  31 import static org.testng.Assert.*;
  32 
  33 /*
  34  * @test
  35  * @run testng/othervm -XX:+EnableMVT -Dvalhalla.enablePoolPatches=true MethodHandlesTest
  36  */
  37 
  38 @Test
  39 public class MethodHandlesTest {
  40     @ValueCapableClass
  41     final class ValueCapable {}
  42 
  43     static final ValueType<?> VT = ValueType.forClass(Point.class);
  44     static final Class<?> VCC = Point.class;
  45     static final Class<?> DVT = VT.valueClass();
  46 
  47     static final MethodHandle ID_DVT_MH = MethodHandles.identity(DVT);            // (DVT)DVT
  48     static final MethodHandle ID_VCC_MH = ID_DVT_MH.asType(methodType(VCC, VCC)); // (VCC)VCC
  49 
  50     static final Object ARG = new Point(0, (short)1, (short)2);
  51 
  52     @Test
  53     void testInsertArgumentDVT() throws Throwable {
  54         {
  55             MethodHandle mh = MethodHandles.insertArguments(ID_DVT_MH, 0, ARG);
  56             assertEquals(mh.invokeWithArguments(), ARG);
  57         }
  58 
  59         assertThrows(ClassCastException.class,
  60                 () -> MethodHandles.insertArguments(ID_DVT_MH, 0, new ValueCapable()));
  61 
  62         assertThrows(NullPointerException.class,
  63                 () -> MethodHandles.insertArguments(ID_DVT_MH, 0, new Object[] { null }));
  64     }
  65 
  66     @Test
  67     void testInsertArgumentVCC() throws Throwable {
  68         assertEquals(MethodHandles.insertArguments(ID_VCC_MH, 0, ARG).invokeWithArguments(), ARG);
  69 
  70         assertThrows(ClassCastException.class,
  71                 () -> MethodHandles.insertArguments(ID_VCC_MH, 0, new ValueCapable()));
  72 
  73         {
  74             MethodHandle mh = MethodHandles.insertArguments(ID_VCC_MH, 0, new Object[]{null});
  75             assertThrows(NullPointerException.class, () -> mh.invokeWithArguments());
  76         }
  77     }
  78 
  79     @Test
  80     void testConstantDVT() throws Throwable {
  81         assertEquals(MethodHandles.constant(DVT, ARG).type(), methodType(DVT));
  82 
  83         assertEquals(MethodHandles.constant(DVT, ARG).invokeWithArguments(), ARG);
  84 
  85         assertThrows(ClassCastException.class,
  86                 () -> MethodHandles.constant(DVT, new Object()));
  87 
  88         assertThrows(NullPointerException.class,
  89                 () -> MethodHandles.constant(DVT, null));
  90     }
  91 
  92     @Test
  93     void testBindToDVT() {
  94         assertThrows(IllegalArgumentException.class,
  95                 () -> ID_DVT_MH.bindTo(ARG));
  96     }
  97 }