1 /*
   2  * Copyright (c) 2012, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 import java.lang.invoke.Intrinsics;
  27 import java.lang.invoke.VarHandle;
  28 import java.lang.constant.ClassDesc;
  29 import java.lang.constant.ConstantDescs;
  30 import java.lang.constant.ConstantMethodHandleDesc;
  31 import java.lang.constant.DynamicConstantDesc;
  32 import java.lang.constant.MethodHandleDesc;
  33 import java.util.List;
  34 
  35 import org.testng.annotations.Test;
  36 
  37 import static java.lang.invoke.Intrinsics.ldc;
  38 import static org.testng.Assert.assertEquals;
  39 import static org.testng.Assert.assertNull;
  40 
  41 /**
  42  * @test
  43  * @compile ConstantRefBootstrapsTest.java
  44  * @run testng ConstantRefBootstrapsTest
  45  * @summary integration tests for dynamic constant bootstraps and Intrinsics.ldc()
  46  */
  47 @Test
  48 public class ConstantRefBootstrapsTest {
  49     static final ClassDesc CLASS_CONDY = ClassDesc.of("java.lang.invoke.ConstantBootstraps");
  50 
  51     static final ConstantMethodHandleDesc BSM_NULL_CONSTANT
  52             = ConstantDescs.ofConstantBootstrap(CLASS_CONDY, "nullConstant", ConstantDescs.CR_Object);
  53     static final ConstantMethodHandleDesc BSM_PRIMITIVE_CLASS
  54             = ConstantDescs.ofConstantBootstrap(CLASS_CONDY, "primitiveClass", ConstantDescs.CR_Class);
  55     static final ConstantMethodHandleDesc BSM_ENUM_CONSTANT
  56             = ConstantDescs.ofConstantBootstrap(CLASS_CONDY, "enumConstant", ConstantDescs.CR_Enum);
  57     static final ConstantMethodHandleDesc BSM_GET_STATIC_FINAL_SELF
  58             = ConstantDescs.ofConstantBootstrap(CLASS_CONDY, "getStaticFinal", ConstantDescs.CR_Object);
  59     static final ConstantMethodHandleDesc BSM_GET_STATIC_FINAL_DECL
  60             = ConstantDescs.ofConstantBootstrap(CLASS_CONDY, "getStaticFinal", ConstantDescs.CR_Object, ConstantDescs.CR_Class);
  61     static final ConstantMethodHandleDesc BSM_INVOKE
  62             = ConstantDescs.ofConstantBootstrap(CLASS_CONDY, "invoke", ConstantDescs.CR_Object, ConstantDescs.CR_MethodHandle, ConstantDescs.CR_Object.array());
  63     static final ConstantMethodHandleDesc BSM_VARHANDLE_FIELD
  64             = ConstantDescs.ofConstantBootstrap(CLASS_CONDY, "fieldVarHandle", ConstantDescs.CR_VarHandle, ConstantDescs.CR_Class, ConstantDescs.CR_Class);
  65     static final ConstantMethodHandleDesc BSM_VARHANDLE_STATIC_FIELD
  66             = ConstantDescs.ofConstantBootstrap(CLASS_CONDY, "staticFieldVarHandle", ConstantDescs.CR_VarHandle, ConstantDescs.CR_Class, ConstantDescs.CR_Class);
  67     static final ConstantMethodHandleDesc BSM_VARHANDLE_ARRAY
  68             = ConstantDescs.ofConstantBootstrap(CLASS_CONDY, "arrayVarHandle", ConstantDescs.CR_VarHandle, ConstantDescs.CR_Class);
  69 
  70 
  71     public void testNullConstant() {
  72         Object supposedlyNull = Intrinsics.ldc(DynamicConstantDesc.of(BSM_NULL_CONSTANT, ConstantDescs.CR_Object));
  73         assertNull(supposedlyNull);
  74 
  75         supposedlyNull = Intrinsics.ldc(DynamicConstantDesc.of(BSM_NULL_CONSTANT, ConstantDescs.CR_MethodType));
  76         assertNull(supposedlyNull);
  77     }
  78 
  79 
  80     public void testPrimitiveClass() {
  81         assertEquals(ldc(DynamicConstantDesc.of(BSM_PRIMITIVE_CLASS, ConstantDescs.CR_int.descriptorString())), int.class);
  82         assertEquals(ldc(DynamicConstantDesc.of(BSM_PRIMITIVE_CLASS, ConstantDescs.CR_long.descriptorString())), long.class);
  83         assertEquals(ldc(DynamicConstantDesc.of(BSM_PRIMITIVE_CLASS, ConstantDescs.CR_short.descriptorString())), short.class);
  84         assertEquals(ldc(DynamicConstantDesc.of(BSM_PRIMITIVE_CLASS, ConstantDescs.CR_byte.descriptorString())), byte.class);
  85         assertEquals(ldc(DynamicConstantDesc.of(BSM_PRIMITIVE_CLASS, ConstantDescs.CR_char.descriptorString())), char.class);
  86         assertEquals(ldc(DynamicConstantDesc.of(BSM_PRIMITIVE_CLASS, ConstantDescs.CR_float.descriptorString())), float.class);
  87         assertEquals(ldc(DynamicConstantDesc.of(BSM_PRIMITIVE_CLASS, ConstantDescs.CR_double.descriptorString())), double.class);
  88         assertEquals(ldc(DynamicConstantDesc.of(BSM_PRIMITIVE_CLASS, ConstantDescs.CR_boolean.descriptorString())), boolean.class);
  89         assertEquals(ldc(DynamicConstantDesc.of(BSM_PRIMITIVE_CLASS, ConstantDescs.CR_void.descriptorString())), void.class);
  90     }
  91 
  92 
  93     public void testEnumConstant() {
  94         MethodHandleDesc.Kind k = Intrinsics.ldc(DynamicConstantDesc.of(
  95                 BSM_ENUM_CONSTANT, "STATIC",
  96                 ClassDesc.of("java.lang.constant.MethodHandleRef$Kind")));
  97         assertEquals(k, MethodHandleDesc.Kind.STATIC);
  98     }
  99 
 100 
 101     public void testGetStaticFinalDecl() {
 102         DynamicConstantDesc<Class<Integer>> intClass =
 103                 DynamicConstantDesc.<Class<Integer>>of(BSM_GET_STATIC_FINAL_DECL, "TYPE", ConstantDescs.CR_Class).withArgs(ConstantDescs.CR_Integer);
 104         Class<Integer> c = Intrinsics.ldc(intClass);
 105         assertEquals(c, int.class);
 106     }
 107 
 108     public void testGetStaticFinalSelf() {
 109         DynamicConstantDesc<Integer> integerMaxValue = DynamicConstantDesc.of(BSM_GET_STATIC_FINAL_SELF, "MAX_VALUE", ConstantDescs.CR_int);
 110         int v = Intrinsics.ldc(integerMaxValue);
 111         assertEquals(v, Integer.MAX_VALUE);
 112     }
 113 
 114 
 115     public void testInvoke() {
 116         DynamicConstantDesc<List<Integer>> list
 117                 = DynamicConstantDesc.<List<Integer>>of(BSM_INVOKE, ConstantDescs.CR_List)
 118                 .withArgs(MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, ConstantDescs.CR_List, "of", ConstantDescs.CR_List, ConstantDescs.CR_Object.array()), 1, 2, 3, 4);
 119 
 120         List<Integer> l = ldc(list);
 121         assertEquals(l, List.of(1, 2, 3, 4));
 122     }
 123 
 124     public void testInvokeAsType() {
 125         DynamicConstantDesc<Integer> valueOf = DynamicConstantDesc.<Integer>of(BSM_INVOKE, ConstantDescs.CR_int)
 126                 .withArgs(MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, ConstantDescs.CR_Integer, "valueOf", ConstantDescs.CR_Integer, ConstantDescs.CR_String),
 127                           "42");
 128 
 129         int v = ldc(valueOf);
 130         assertEquals(v, 42);
 131     }
 132 
 133 
 134     public void testVarHandleField() {
 135         VarHandle fh = Intrinsics.ldc(DynamicConstantDesc.<VarHandle>of(BSM_VARHANDLE_FIELD, "f")
 136                                               .withArgs(ClassDesc.of("CondyTestHelper"), ConstantDescs.CR_String));
 137 
 138         CondyTestHelper instance = new CondyTestHelper();
 139         assertEquals(null, fh.get(instance));
 140         fh.set(instance, "42");
 141         assertEquals(fh.get(instance), "42");
 142     }
 143 
 144     public void testVarHandleStaticField() {
 145         VarHandle sfh = Intrinsics.ldc(DynamicConstantDesc.<VarHandle>of(BSM_VARHANDLE_STATIC_FIELD, "sf")
 146                                        .withArgs(ClassDesc.of("CondyTestHelper"), ConstantDescs.CR_String));
 147 
 148         assertEquals(null, sfh.get());
 149         sfh.set("42");
 150         assertEquals(sfh.get(), "42");
 151     }
 152 
 153     public void testVarHandleArray() {
 154         VarHandle ah = Intrinsics.ldc(DynamicConstantDesc.<VarHandle>of(BSM_VARHANDLE_ARRAY).withArgs(ConstantDescs.CR_String.array()));
 155 
 156         String[] sa = { "A" };
 157         assertEquals("A", ah.get(sa, 0));
 158         ah.set(sa, 0, "B");
 159         assertEquals(ah.get(sa, 0), "B");
 160     }
 161 }
 162 
 163 class CondyTestHelper {
 164     public static String sf;
 165     public String f;
 166 }