Path: blob/master/jcl/src/java.base/share/classes/java/lang/invoke/ConstantCallSite.java
12520 views
/*[INCLUDE-IF Sidecar17 & !OPENJDK_METHODHANDLES]*/1/*******************************************************************************2* Copyright (c) 2011, 2020 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception21*******************************************************************************/22package java.lang.invoke;2324/**25* A ConstantCallSite is permanently bound to its initial target MethodHandle.26* Any call to {@link #setTarget(MethodHandle)} will result in an UnsupportedOperationException.27*28* @since 1.729*/30public class ConstantCallSite extends CallSite {31private final MethodHandle target;3233/**34* Create a ConstantCallSite with a target MethodHandle that cannot change.35*36* @param permanentTarget - the target MethodHandle to permanently associate with this CallSite.37*/38public ConstantCallSite(MethodHandle permanentTarget) {39super(permanentTarget.type());40// .type() call ensures non-null41target = permanentTarget;42}4344/**45* Create a ConstantCallSite and assign the hook MethodHandle's result to its permanent target.46* The hook MethodHandle is invoked as though by (@link MethodHandle#invoke(this)) and must return a MethodHandle that will be installed47* as the ConstantCallSite's target.48* <p>49* The hook MethodHandle is required if the ConstantCallSite's target needs to have access to the ConstantCallSite instance. This is an50* action that user code cannot perform on its own.51* <p>52* The hook must return a MethodHandle that is exactly of type <i>targetType</i>.53* <p>54* Until the result of the hook has been installed in the ConstantCallSite, any call to getTarget() or dynamicInvoker() will throw an55* IllegalStateException. It is always valid to call type().56*57* @param targetType - the type of the ConstantCallSite's target58* @param hook - the hook handle, with signature (ConstantCallSite)MethodHandle59* @throws Throwable anything thrown by the hook.60* @throws WrongMethodTypeException if the hook has the wrong signature or returns a MethodHandle with the wrong signature61* @throws NullPointerException if the hook is null or returns null62* @throws ClassCastException if the result of the hook is not a MethodHandle63*/64protected ConstantCallSite(MethodType targetType, MethodHandle hook) throws Throwable, WrongMethodTypeException, NullPointerException, ClassCastException {65super(targetType);66MethodHandle handle = null;67if (hook != null) {68handle = (MethodHandle) hook.invoke(this);69}70handle.getClass(); // Throw NPE if null71if (handle.type != targetType) {72throw WrongMethodTypeException.newWrongMethodTypeException(targetType, handle.type);73}74target = handle;75}7677/**78* Return the target MethodHandle of this CallSite.79* @throws IllegalStateException - if the target has not yet been assigned in the ConstantCallSite constructor80*/81@Override82public final MethodHandle dynamicInvoker() throws IllegalStateException {83return getTarget();84}8586/**87* Return the target MethodHandle of this CallSite.88* The target is defined as though it where a final field.89*90* @throws IllegalStateException - if the target has not yet been assigned in the ConstantCallSite constructor91*/92@Override93public final MethodHandle getTarget() throws IllegalStateException {94if (target == null) {95throw new IllegalStateException();96}97return target;98}99100/**101* Throws UnsupportedOperationException as a ConstantCallSite is permanently102* bound to its initial target MethodHandle.103*/104@Override105public final void setTarget(MethodHandle newTarget) {106throw new UnsupportedOperationException();107}108}109110111112