mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8210031: implementation for JVM Constants API
Co-authored-by: Brian Goetz <brian.goetz@oracle.com> Reviewed-by: jrose, mcimadamore, darcy, mchung, rriggs, dholmes, forax
This commit is contained in:
parent
b80d335354
commit
9846588b31
72 changed files with 6719 additions and 103 deletions
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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 java.lang.constant;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import static java.lang.constant.ConstantDescs.CD_void;
|
||||
import static java.lang.constant.DirectMethodHandleDesc.Kind.CONSTRUCTOR;
|
||||
|
||||
/**
|
||||
* A <a href="package-summary.html#nominal">nominal descriptor</a> for a
|
||||
* {@link MethodHandle} constant.
|
||||
*
|
||||
* @apiNote In the future, if the Java language permits, {@linkplain MethodHandleDesc}
|
||||
* may become a {@code sealed} interface, which would prohibit subclassing except
|
||||
* by explicitly permitted types. Non-platform classes should not implement
|
||||
* {@linkplain MethodHandleDesc} directly.
|
||||
*
|
||||
* @since 12
|
||||
*/
|
||||
public interface MethodHandleDesc
|
||||
extends ConstantDesc {
|
||||
|
||||
/**
|
||||
* Creates a {@linkplain MethodHandleDesc} corresponding to an invocation of a
|
||||
* declared method, invocation of a constructor, or access to a field.
|
||||
*
|
||||
* <p>The lookup descriptor string has the same format as for the various
|
||||
* variants of {@code CONSTANT_MethodHandle_info} and for the lookup
|
||||
* methods on {@link MethodHandles.Lookup}. For a method or constructor
|
||||
* invocation, it is interpreted as a method type descriptor; for field
|
||||
* access, it is interpreted as a field descriptor. If {@code kind} is
|
||||
* {@code CONSTRUCTOR}, the {@code name} parameter is ignored and the return
|
||||
* type of the lookup descriptor must be {@code void}. If {@code kind}
|
||||
* corresponds to a virtual method invocation, the lookup type includes the
|
||||
* method parameters but not the receiver type.
|
||||
*
|
||||
* @param kind The kind of method handle to be described
|
||||
* @param owner a {@link ClassDesc} describing the class containing the
|
||||
* method, constructor, or field
|
||||
* @param name the unqualified name of the method or field (ignored if
|
||||
* {@code kind} is {@code CONSTRUCTOR})
|
||||
* @param lookupDescriptor a method descriptor string the lookup type,
|
||||
* if the request is for a method invocation, or
|
||||
* describing the invocation type, if the request is
|
||||
* for a field or constructor
|
||||
* @return the {@linkplain MethodHandleDesc}
|
||||
* @throws NullPointerException if any of the non-ignored arguments are null
|
||||
* @jvms 4.4.8 The CONSTANT_MethodHandle_info Structure
|
||||
* @jvms 4.2.2 Unqualified Names
|
||||
* @jvms 4.3.2 Field Descriptors
|
||||
* @jvms 4.3.3 Method Descriptors
|
||||
*/
|
||||
static DirectMethodHandleDesc of(DirectMethodHandleDesc.Kind kind,
|
||||
ClassDesc owner,
|
||||
String name,
|
||||
String lookupDescriptor) {
|
||||
switch (kind) {
|
||||
case GETTER:
|
||||
case SETTER:
|
||||
case STATIC_GETTER:
|
||||
case STATIC_SETTER:
|
||||
return ofField(kind, owner, name, ClassDesc.ofDescriptor(lookupDescriptor));
|
||||
default:
|
||||
return new DirectMethodHandleDescImpl(kind, owner, name, MethodTypeDesc.ofDescriptor(lookupDescriptor));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@linkplain MethodHandleDesc} corresponding to an invocation of a
|
||||
* declared method or constructor.
|
||||
*
|
||||
* <p>The lookup descriptor string has the same format as for the lookup
|
||||
* methods on {@link MethodHandles.Lookup}. If {@code kind} is
|
||||
* {@code CONSTRUCTOR}, the name is ignored and the return type of the lookup
|
||||
* type must be {@code void}. If {@code kind} corresponds to a virtual method
|
||||
* invocation, the lookup type includes the method parameters but not the
|
||||
* receiver type.
|
||||
*
|
||||
* @param kind The kind of method handle to be described; must be one of
|
||||
* {@code SPECIAL, VIRTUAL, STATIC, INTERFACE_SPECIAL,
|
||||
* INTERFACE_VIRTUAL, INTERFACE_STATIC, CONSTRUCTOR}
|
||||
* @param owner a {@link ClassDesc} describing the class containing the
|
||||
* method or constructor
|
||||
* @param name the unqualified name of the method (ignored if {@code kind}
|
||||
* is {@code CONSTRUCTOR})
|
||||
* @param lookupMethodType a {@link MethodTypeDesc} describing the lookup type
|
||||
* @return the {@linkplain MethodHandleDesc}
|
||||
* @throws NullPointerException if any non-ignored arguments are null
|
||||
* @throws IllegalArgumentException if the {@code name} has the incorrect
|
||||
* format, or the kind is invalid
|
||||
* @jvms 4.2.2 Unqualified Names
|
||||
*/
|
||||
static DirectMethodHandleDesc ofMethod(DirectMethodHandleDesc.Kind kind,
|
||||
ClassDesc owner,
|
||||
String name,
|
||||
MethodTypeDesc lookupMethodType) {
|
||||
switch (kind) {
|
||||
case GETTER:
|
||||
case SETTER:
|
||||
case STATIC_GETTER:
|
||||
case STATIC_SETTER:
|
||||
throw new IllegalArgumentException(kind.toString());
|
||||
case VIRTUAL:
|
||||
case SPECIAL:
|
||||
case INTERFACE_VIRTUAL:
|
||||
case INTERFACE_SPECIAL:
|
||||
case INTERFACE_STATIC:
|
||||
case STATIC:
|
||||
case CONSTRUCTOR:
|
||||
return new DirectMethodHandleDescImpl(kind, owner, name, lookupMethodType);
|
||||
default:
|
||||
throw new IllegalArgumentException(kind.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@linkplain MethodHandleDesc} corresponding to a method handle
|
||||
* that accesses a field.
|
||||
*
|
||||
* @param kind the kind of the method handle to be described; must be one of {@code GETTER},
|
||||
* {@code SETTER}, {@code STATIC_GETTER}, or {@code STATIC_SETTER}
|
||||
* @param owner a {@link ClassDesc} describing the class containing the field
|
||||
* @param fieldName the unqualified name of the field
|
||||
* @param fieldType a {@link ClassDesc} describing the type of the field
|
||||
* @return the {@linkplain MethodHandleDesc}
|
||||
* @throws NullPointerException if any of the arguments are null
|
||||
* @throws IllegalArgumentException if the {@code kind} is not one of the
|
||||
* valid values or if the field name is not valid
|
||||
* @jvms 4.2.2 Unqualified Names
|
||||
*/
|
||||
static DirectMethodHandleDesc ofField(DirectMethodHandleDesc.Kind kind,
|
||||
ClassDesc owner,
|
||||
String fieldName,
|
||||
ClassDesc fieldType) {
|
||||
MethodTypeDesc mtr;
|
||||
switch (kind) {
|
||||
case GETTER: mtr = MethodTypeDesc.of(fieldType, owner); break;
|
||||
case SETTER: mtr = MethodTypeDesc.of(CD_void, owner, fieldType); break;
|
||||
case STATIC_GETTER: mtr = MethodTypeDesc.of(fieldType); break;
|
||||
case STATIC_SETTER: mtr = MethodTypeDesc.of(CD_void, fieldType); break;
|
||||
default:
|
||||
throw new IllegalArgumentException(kind.toString());
|
||||
}
|
||||
return new DirectMethodHandleDescImpl(kind, owner, fieldName, mtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@linkplain MethodHandleDesc} corresponding to invocation of a constructor
|
||||
*
|
||||
* @param owner a {@link ClassDesc} describing the class containing the
|
||||
* constructor
|
||||
* @param paramTypes {@link ClassDesc}s describing the parameter types of
|
||||
* the constructor
|
||||
* @return the {@linkplain MethodHandleDesc}
|
||||
* @throws NullPointerException if any of the arguments are null
|
||||
*/
|
||||
static DirectMethodHandleDesc ofConstructor(ClassDesc owner,
|
||||
ClassDesc... paramTypes) {
|
||||
return MethodHandleDesc.ofMethod(CONSTRUCTOR, owner, ConstantDescs.DEFAULT_NAME,
|
||||
MethodTypeDesc.of(CD_void, paramTypes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@linkplain MethodHandleDesc} that describes this method handle
|
||||
* adapted to a different type, as if by {@link MethodHandle#asType(MethodType)}.
|
||||
*
|
||||
* @param type a {@link MethodHandleDesc} describing the new method type
|
||||
* @return a {@linkplain MethodHandleDesc} for the adapted method handle
|
||||
*/
|
||||
default MethodHandleDesc asType(MethodTypeDesc type) {
|
||||
return (invocationType().equals(type)) ? this : new AsTypeMethodHandleDesc(this, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link MethodTypeDesc} describing the invocation type of the
|
||||
* method handle described by this nominal descriptor. The invocation type
|
||||
* describes the full set of stack values that are consumed by the invocation
|
||||
* (including the receiver, if any).
|
||||
*
|
||||
* @return a {@linkplain MethodHandleDesc} describing the method handle type
|
||||
*/
|
||||
MethodTypeDesc invocationType();
|
||||
|
||||
/**
|
||||
* Compares the specified object with this descriptor for equality. Returns
|
||||
* {@code true} if and only if the specified object is also a
|
||||
* {@linkplain MethodHandleDesc}, and both encode the same nominal description
|
||||
* of a method handle.
|
||||
*
|
||||
* @param o the other object
|
||||
* @return whether this descriptor is equal to the other object
|
||||
*/
|
||||
boolean equals(Object o);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue