--- /dev/null 2017-09-15 12:06:07.000000000 -0700 +++ new/jdk/src/jdk.incubator.mvt/share/classes/jdk/incubator/mvt/ValueType.java 2017-09-15 12:06:07.000000000 -0700 @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.mvt; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; +import java.lang.reflect.Field; + +import valhalla.shady.MinimalValueTypes_1_0; +import valhalla.shady.ValueTypeHolder; + +/** + * Value type reflection support. + */ +public class ValueType { + /** + * Returns a {@code ValueType} object representing the specified + * value-capable class. + * + * @param vcc Value-capable class + * @param Value type + * @return a {@code ValueType} object representing the specified + * value-capable class. + * + * @throws IllegalArgumentException if the specified {@code vcc} + * is not a value-capable class. + */ + public static ValueType forClass(Class vcc) { + return new ValueType<>(MinimalValueTypes_1_0.getValueFor(vcc)); + } + + /** + * Returns {@code true} if the specified class is value-capable class. + * + * @param c a Class + * @return true if the specified class is a value-capable class. + */ + public static boolean classHasValueType(Class c) { + if (!MinimalValueTypes_1_0.isValueCapable(c)) { + return false; + } + return MinimalValueTypes_1_0.getValueTypeClass(c) != null; + } + + private final ValueTypeHolder valueTypeHolder; + private ValueType(ValueTypeHolder vt) { + this.valueTypeHolder = vt; + } + + /** + * Returns the value-capable class of this value type. + * + * @return the value-capable class of this value type. + */ + public Class boxClass() { + return valueTypeHolder.boxClass(); + } + + /** + * Returns the derived value type of this value type. + * + * @return the derived value type of this value type. + */ + public Class valueClass() { + return valueTypeHolder.valueClass(); + } + + /** + * Returns an array class of this value type. + * + * @return an array class of this value type. + */ + public Class arrayValueClass() { + return arrayValueClass(1); + } + + /** + * Returns an array class of the specified dimension for this value type. + * + * @return an array class of the specified dimension for this value type. + */ + public Class arrayValueClass(int dims) { + String dimsStr = "[[[[[[[[[[[[[[[["; + if (dims < 1 || dims > 16) { + throw new IllegalArgumentException("cannot create array class for dimension > 16"); + } + String cn = dimsStr.substring(0, dims) + "Q" + valueClass().getName() + ";"; + return MinimalValueTypes_1_0.loadValueTypeClass(boxClass(), cn); + } + + /** + * Returns a string representation of this value type. + * + * @return a string representation of this value type. + */ + public String toString() { + return valueTypeHolder.toString(); + } + + public static ValueType make(Lookup lookup, + String name, + String[] fieldNames, + Class... fieldTypes) + throws ReflectiveOperationException + { + if (fieldNames.length != fieldTypes.length) { + throw new IllegalArgumentException("Field names length and field types length must match"); + } + if (!(fieldNames.length > 0)) { + throw new IllegalArgumentException("Field length must be greater than zero"); + } + Class vtClass = ValueTypeHolder.makeValueTypeClass(lookup, name, fieldNames, fieldTypes); + return forClass(vtClass); + } + + // ()Q + public MethodHandle findConstructor(Lookup lookup, MethodType type) + throws NoSuchMethodException, IllegalAccessException { + return valueTypeHolder.findConstructor(lookup, type); + } + + // (F1, ..., Fn)Q, fromDefault == true + // (Q, F1, ..., Fn)Q, fromDefault == false + public MethodHandle unreflectWithers(Lookup lookup, + boolean fromDefault, + Field... fields) + throws NoSuchFieldException, IllegalAccessException { + return valueTypeHolder.unreflectWithers(lookup, fromDefault, fields); + } + + // (Q, T)Q + public MethodHandle findWither(Lookup lookup, String name, Class type) + throws NoSuchFieldException, IllegalAccessException { + return valueTypeHolder.findWither(lookup, name, type); + } + + public MethodHandle unbox() { + return valueTypeHolder.unbox(); + } + + public MethodHandle box() { + return valueTypeHolder.box(); + } + + public MethodHandle newArray() { + return valueTypeHolder.newArray(); + } + + public MethodHandle arrayGetter() { + return valueTypeHolder.arrayGetter(); + } + + public MethodHandle arraySetter() { + return valueTypeHolder.arraySetter(); + } + + public MethodHandle newMultiArray(int dims) { + return valueTypeHolder.newMultiArray(dims); + } + + public MethodHandle arrayLength() { + return valueTypeHolder.arrayLength(); + } + + public MethodHandle identity() { + return valueTypeHolder.identity(); + } + + public MethodHandle findGetter(Lookup lookup, String name, Class type) + throws NoSuchFieldException, IllegalAccessException { + return valueTypeHolder.findGetter(lookup, name, type); + } + + public MethodHandle substitutabilityTest() { + return valueTypeHolder.substitutabilityTest(); + } + + public MethodHandle substitutabilityHashCode() { + return valueTypeHolder.substitutabilityHashCode(); + } + + public MethodHandle defaultValueConstant() { + return valueTypeHolder.defaultValueConstant(); + } + + public Field[] valueFields() { + return valueTypeHolder.valueFields(); + } +}