Path: blob/master/jcl/src/java.base/share/classes/java/lang/invoke/ConstantHandle.java
12521 views
/*[INCLUDE-IF Sidecar17 & !OPENJDK_METHODHANDLES]*/1/*******************************************************************************2* Copyright (c) 2009, 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;2324import static java.lang.invoke.MethodType.*;2526/*[IF JAVA_SPEC_VERSION >= 15]*/27import java.util.List;28/*[ENDIF] JAVA_SPEC_VERSION >= 15 */2930/*31* MethodHandle subclass responsible for dealing with constant values.32* The dispatch targets pop the MethodHandle and then push the constant value.33*/34abstract class ConstantHandle extends MethodHandle {3536ConstantHandle(MethodType type, byte kind) {37super(type, kind, null);38}3940ConstantHandle(ConstantHandle originalHandle, MethodType newType) {41super(originalHandle, newType);42}4344private static final ThunkTable _thunkTable = new ThunkTable();45private static final ConstantHandle constantHandleInt_0 = new ConstantIntHandle(methodType(int.class), 0);46private static final ConstantHandle constantHandleInt_1 = new ConstantIntHandle(methodType(int.class), 1);47private static final ConstantHandle constantHandleDouble_0 = new ConstantDoubleHandle(methodType(double.class), 0.0);48private static final ConstantHandle constantHandleDouble_1 = new ConstantDoubleHandle(methodType(double.class), 1.0);49private static final ConstantHandle constantHandleLong_0 = new ConstantLongHandle(methodType(long.class), 0L);50private static final ConstantHandle constantHandleLong_1 = new ConstantLongHandle(methodType(long.class), 1L);5152/*53* This is a single shared thunkTable across all ConstantHandle subclasses54* as each subclass only deals with a single signature.55*/56@Override57protected final ThunkTable thunkTable() {58return _thunkTable;59}6061public static ConstantHandle get(Class<?> constantType, Object constantValue) {62MethodType methodType = methodType(constantType);63if (!constantType.isPrimitive()) {64if (null != constantValue) {65return new ConstantObjectHandle(methodType, constantValue);66}67MethodHandleCache methodHandleCache = MethodHandleCache.getCache(constantType);68return (ConstantHandle)methodHandleCache.getNullConstantObjectHandle();69}7071char charValue = 0;72if (constantValue instanceof Character) {73charValue = ((Character)constantValue).charValue();74}7576if (constantType == double.class) {77double value;78if (constantValue instanceof Number) {79value = ((Number)constantValue).doubleValue();80} else {81value = charValue;82}83if (0.0 == value) {84return constantHandleDouble_0;85} else if (1.0 == value) {86return constantHandleDouble_1;87}88return new ConstantDoubleHandle(methodType, value);89} else if (constantType == long.class) {90long value;91if (constantValue instanceof Number) {92value = ((Number)constantValue).longValue();93} else {94value = charValue;95}96if (0L == value) {97return constantHandleLong_0;98} else if (1L == value) {99return constantHandleLong_1;100}101return new ConstantLongHandle(methodType, value);102} else if (constantType == float.class) {103float value;104if (constantValue instanceof Number) {105value = ((Number)constantValue).floatValue();106} else {107value = charValue;108}109return new ConstantFloatHandle(methodType, value);110} else {111// int, short, byte, char, boolean112int value;113if (constantValue instanceof Number) {114value = ((Number)constantValue).intValue();115} else if (constantValue instanceof Boolean) {116value = ((Boolean)constantValue).booleanValue() ? 1 : 0;117} else {118value = charValue;119}120if (int.class == constantType) {121if (0 == value) {122return constantHandleInt_0;123} else if (1 == value) {124return constantHandleInt_1;125}126}127return new ConstantIntHandle(methodType, value);128}129}130131/*[IF JAVA_SPEC_VERSION >= 15]*/132@Override133boolean addRelatedMHs(List<MethodHandle> relatedMHs) {134return false;135}136/*[ENDIF] JAVA_SPEC_VERSION >= 15 */137}138139final class ConstantObjectHandle extends ConstantHandle {140141final Object value;142143ConstantObjectHandle(MethodType type, Object value) {144super(type, KIND_CONSTANTOBJECT); //$NON-NLS-1$145this.value = value;146}147148ConstantObjectHandle(ConstantObjectHandle originalHandle, MethodType newType) {149super(originalHandle, newType);150this.value = originalHandle.value;151}152153@FrameIteratorSkip154private final Object invokeExact_thunkArchetype_L(int placeholder) {155return value;156}157158@Override159MethodHandle cloneWithNewType(MethodType newType) {160return new ConstantObjectHandle(this, newType);161}162163@Override164MethodHandle permuteArguments(MethodType permuteType, int... permute) {165/* Do not use cloneWithNewType() as incoming signatures may be different */166return new ConstantObjectHandle(permuteType, this.value);167}168169@Override170MethodHandle insertArguments(MethodHandle equivalent, MethodHandle unboxingHandle, int location, Object... values) {171return new ConstantObjectHandle(equivalent.type, this.value);172}173174final void compareWith(MethodHandle right, Comparator c) {175if (right instanceof ConstantObjectHandle) {176((ConstantObjectHandle)right).compareWithConstantObject(this, c);177} else {178c.fail();179}180}181182final void compareWithConstantObject(ConstantObjectHandle left, Comparator c) {183c.compareUserSuppliedParameter(left.value, this.value);184}185}186187final class ConstantIntHandle extends ConstantHandle {188189final int value;190191ConstantIntHandle(MethodType type, int value) {192super(type, KIND_CONSTANTINT); //$NON-NLS-1$193this.value = value;194}195196ConstantIntHandle(ConstantIntHandle originalHandle, MethodType newType) {197super(originalHandle, newType);198this.value = originalHandle.value;199}200201@FrameIteratorSkip202private final int invokeExact_thunkArchetype_I(int placeholder) {203return value;204}205206@FrameIteratorSkip207private final byte invokeExact_thunkArchetype_B(int placeholder) {208return (byte)value;209}210211@FrameIteratorSkip212private final char invokeExact_thunkArchetype_C(int placeholder) {213return (char)value;214}215216@FrameIteratorSkip217private final short invokeExact_thunkArchetype_S(int placeholder) {218return (short)value;219}220221@FrameIteratorSkip222private final boolean invokeExact_thunkArchetype_Z(int placeholder) {223return value != 0;224}225226@Override227MethodHandle cloneWithNewType(MethodType newType) {228return new ConstantIntHandle(this, newType);229}230231@Override232MethodHandle permuteArguments(MethodType permuteType, int... permute) {233/* Do not use cloneWithNewType() as incoming signatures may be different */234return new ConstantIntHandle(permuteType, this.value);235}236237@Override238MethodHandle insertArguments(MethodHandle equivalent, MethodHandle unboxingHandle, int location, Object... values) {239return new ConstantIntHandle(equivalent.type, this.value);240}241242final void compareWith(MethodHandle right, Comparator c) {243if (right instanceof ConstantIntHandle) {244((ConstantIntHandle)right).compareWithConstantInt(this, c);245} else {246c.fail();247}248}249250final void compareWithConstantInt(ConstantIntHandle left, Comparator c) {251c.compareStructuralParameter(left.value, this.value);252}253}254255final class ConstantFloatHandle extends ConstantHandle {256257final float value;258259ConstantFloatHandle(MethodType type, float value) {260super(type, KIND_CONSTANTFLOAT); //$NON-NLS-1$261this.value = value;262}263264ConstantFloatHandle(ConstantFloatHandle originalHandle, MethodType newType) {265super(originalHandle, newType);266this.value = originalHandle.value;267}268269@FrameIteratorSkip270private final float invokeExact_thunkArchetype_F(int placeholder) {271return value;272}273274@Override275MethodHandle cloneWithNewType(MethodType newType) {276return new ConstantFloatHandle(this, newType);277}278279@Override280MethodHandle permuteArguments(MethodType permuteType, int... permute) {281/* Do not use cloneWithNewType() as incoming signatures may be different */282return new ConstantFloatHandle(permuteType, this.value);283}284285@Override286MethodHandle insertArguments(MethodHandle equivalent, MethodHandle unboxingHandle, int location, Object... values) {287return new ConstantFloatHandle(equivalent.type, this.value);288}289290final void compareWith(MethodHandle right, Comparator c) {291if (right instanceof ConstantFloatHandle) {292((ConstantFloatHandle)right).compareWithConstantFloat(this, c);293} else {294c.fail();295}296}297298final void compareWithConstantFloat(ConstantFloatHandle left, Comparator c) {299c.compareStructuralParameter(left.value, this.value);300}301}302303final class ConstantLongHandle extends ConstantHandle {304305final long value;306307ConstantLongHandle(MethodType type, long value) {308super(type, KIND_CONSTANTLONG); //$NON-NLS-1$309this.value = value;310}311312ConstantLongHandle(ConstantLongHandle originalHandle, MethodType newType) {313super(originalHandle, newType);314this.value = originalHandle.value;315}316317@FrameIteratorSkip318private final long invokeExact_thunkArchetype_J(int placeholder) {319return value;320}321322@Override323MethodHandle cloneWithNewType(MethodType newType) {324return new ConstantLongHandle(this, newType);325}326327@Override328MethodHandle permuteArguments(MethodType permuteType, int... permute) {329/* Do not use cloneWithNewType() as incoming signatures may be different */330return new ConstantLongHandle(permuteType, this.value);331}332333@Override334MethodHandle insertArguments(MethodHandle equivalent, MethodHandle unboxingHandle, int location, Object... values) {335return new ConstantLongHandle(equivalent.type, this.value);336}337338final void compareWith(MethodHandle right, Comparator c) {339if (right instanceof ConstantLongHandle) {340((ConstantLongHandle)right).compareWithConstantLong(this, c);341} else {342c.fail();343}344}345346final void compareWithConstantLong(ConstantLongHandle left, Comparator c) {347c.compareStructuralParameter(left.value, this.value);348}349}350351final class ConstantDoubleHandle extends ConstantHandle {352353final double value;354355ConstantDoubleHandle(MethodType type, double value) {356super(type, KIND_CONSTANTDOUBLE); //$NON-NLS-1$357this.value = value;358}359360ConstantDoubleHandle(ConstantDoubleHandle originalHandle, MethodType newType) {361super(originalHandle, newType);362this.value = originalHandle.value;363}364365@FrameIteratorSkip366private final double invokeExact_thunkArchetype_D(int placeholder) {367return value;368}369370@Override371MethodHandle cloneWithNewType(MethodType newType) {372return new ConstantDoubleHandle(this, newType);373}374375@Override376MethodHandle permuteArguments(MethodType permuteType, int... permute) {377/* Do not use cloneWithNewType() as incoming signatures may be different */378return new ConstantDoubleHandle(permuteType, this.value);379}380381@Override382MethodHandle insertArguments(MethodHandle equivalent, MethodHandle unboxingHandle, int location, Object... values) {383return new ConstantDoubleHandle(equivalent.type, this.value);384}385386final void compareWith(MethodHandle right, Comparator c) {387if (right instanceof ConstantDoubleHandle) {388((ConstantDoubleHandle)right).compareWithConstantDouble(this, c);389} else {390c.fail();391}392}393394final void compareWithConstantDouble(ConstantDoubleHandle left, Comparator c) {395c.compareStructuralParameter(left.value, this.value);396}397}398399400