mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8241100: Make Boolean, Character, Byte, and Short implement Constable
Reviewed-by: jrose, briangoetz, psandoz
This commit is contained in:
parent
2d8bea8c1d
commit
31041d406a
8 changed files with 330 additions and 14 deletions
|
@ -27,6 +27,15 @@ package java.lang;
|
|||
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
|
||||
import java.lang.constant.Constable;
|
||||
import java.lang.constant.ConstantDesc;
|
||||
import java.lang.constant.ConstantDescs;
|
||||
import java.lang.constant.DynamicConstantDesc;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.lang.constant.ConstantDescs.BSM_GET_STATIC_FINAL;
|
||||
import static java.lang.constant.ConstantDescs.CD_Boolean;
|
||||
|
||||
/**
|
||||
* The Boolean class wraps a value of the primitive type
|
||||
* {@code boolean} in an object. An object of type
|
||||
|
@ -43,7 +52,7 @@ import jdk.internal.HotSpotIntrinsicCandidate;
|
|||
* @since 1.0
|
||||
*/
|
||||
public final class Boolean implements java.io.Serializable,
|
||||
Comparable<Boolean>
|
||||
Comparable<Boolean>, Constable
|
||||
{
|
||||
/**
|
||||
* The {@code Boolean} object corresponding to the primitive
|
||||
|
@ -344,4 +353,16 @@ public final class Boolean implements java.io.Serializable,
|
|||
public static boolean logicalXor(boolean a, boolean b) {
|
||||
return a ^ b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link Optional} containing the nominal descriptor for this
|
||||
* instance.
|
||||
*
|
||||
* @return an {@link Optional} describing the {@linkplain Boolean} instance
|
||||
* @since 15
|
||||
*/
|
||||
@Override
|
||||
public Optional<DynamicConstantDesc<Boolean>> describeConstable() {
|
||||
return Optional.of(value ? ConstantDescs.TRUE : ConstantDescs.FALSE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2020, 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
|
||||
|
@ -28,6 +28,15 @@ package java.lang;
|
|||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.misc.VM;
|
||||
|
||||
import java.lang.constant.Constable;
|
||||
import java.lang.constant.DynamicConstantDesc;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.lang.constant.ConstantDescs.BSM_EXPLICIT_CAST;
|
||||
import static java.lang.constant.ConstantDescs.CD_byte;
|
||||
import static java.lang.constant.ConstantDescs.CD_int;
|
||||
import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
|
||||
|
||||
/**
|
||||
*
|
||||
* The {@code Byte} class wraps a value of primitive type {@code byte}
|
||||
|
@ -44,7 +53,7 @@ import jdk.internal.misc.VM;
|
|||
* @see java.lang.Number
|
||||
* @since 1.1
|
||||
*/
|
||||
public final class Byte extends Number implements Comparable<Byte> {
|
||||
public final class Byte extends Number implements Comparable<Byte>, Constable {
|
||||
|
||||
/**
|
||||
* A constant holding the minimum value a {@code byte} can
|
||||
|
@ -77,6 +86,18 @@ public final class Byte extends Number implements Comparable<Byte> {
|
|||
return Integer.toString((int)b, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link Optional} containing the nominal descriptor for this
|
||||
* instance.
|
||||
*
|
||||
* @return an {@link Optional} describing the {@linkplain Byte} instance
|
||||
* @since 15
|
||||
*/
|
||||
@Override
|
||||
public Optional<DynamicConstantDesc<Byte>> describeConstable() {
|
||||
return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_byte, intValue()));
|
||||
}
|
||||
|
||||
private static class ByteCache {
|
||||
private ByteCache() {}
|
||||
|
||||
|
|
|
@ -25,14 +25,22 @@
|
|||
|
||||
package java.lang;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.misc.VM;
|
||||
|
||||
import java.lang.constant.Constable;
|
||||
import java.lang.constant.DynamicConstantDesc;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.lang.constant.ConstantDescs.BSM_EXPLICIT_CAST;
|
||||
import static java.lang.constant.ConstantDescs.CD_char;
|
||||
import static java.lang.constant.ConstantDescs.CD_int;
|
||||
import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
|
||||
|
||||
/**
|
||||
* The {@code Character} class wraps a value of the primitive
|
||||
* type {@code char} in an object. An object of class
|
||||
|
@ -122,7 +130,7 @@ import jdk.internal.misc.VM;
|
|||
* @since 1.0
|
||||
*/
|
||||
public final
|
||||
class Character implements java.io.Serializable, Comparable<Character> {
|
||||
class Character implements java.io.Serializable, Comparable<Character>, Constable {
|
||||
/**
|
||||
* The minimum radix available for conversion to and from strings.
|
||||
* The constant value of this field is the smallest value permitted
|
||||
|
@ -602,6 +610,17 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
|||
*/
|
||||
public static final int MAX_CODE_POINT = 0X10FFFF;
|
||||
|
||||
/**
|
||||
* Returns an {@link Optional} containing the nominal descriptor for this
|
||||
* instance.
|
||||
*
|
||||
* @return an {@link Optional} describing the {@linkplain Character} instance
|
||||
* @since 15
|
||||
*/
|
||||
@Override
|
||||
public Optional<DynamicConstantDesc<Character>> describeConstable() {
|
||||
return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_char, (int) value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instances of this class represent particular subsets of the Unicode
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2020, 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
|
||||
|
@ -28,6 +28,15 @@ package java.lang;
|
|||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.misc.VM;
|
||||
|
||||
import java.lang.constant.Constable;
|
||||
import java.lang.constant.DynamicConstantDesc;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.lang.constant.ConstantDescs.BSM_EXPLICIT_CAST;
|
||||
import static java.lang.constant.ConstantDescs.CD_int;
|
||||
import static java.lang.constant.ConstantDescs.CD_short;
|
||||
import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
|
||||
|
||||
/**
|
||||
* The {@code Short} class wraps a value of primitive type {@code
|
||||
* short} in an object. An object of type {@code Short} contains a
|
||||
|
@ -43,7 +52,7 @@ import jdk.internal.misc.VM;
|
|||
* @see java.lang.Number
|
||||
* @since 1.1
|
||||
*/
|
||||
public final class Short extends Number implements Comparable<Short> {
|
||||
public final class Short extends Number implements Comparable<Short>, Constable {
|
||||
|
||||
/**
|
||||
* A constant holding the minimum value a {@code short} can
|
||||
|
@ -203,6 +212,18 @@ public final class Short extends Number implements Comparable<Short> {
|
|||
return valueOf(s, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link Optional} containing the nominal descriptor for this
|
||||
* instance.
|
||||
*
|
||||
* @return an {@link Optional} describing the {@linkplain Short} instance
|
||||
* @since 15
|
||||
*/
|
||||
@Override
|
||||
public Optional<DynamicConstantDesc<Short>> describeConstable() {
|
||||
return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_short, intValue()));
|
||||
}
|
||||
|
||||
private static class ShortCache {
|
||||
private ShortCache() {}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2020, 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
|
||||
|
@ -194,10 +194,18 @@ public final class ConstantDescs {
|
|||
= ofConstantBootstrap(CD_ConstantBootstraps, "enumConstant",
|
||||
CD_Enum);
|
||||
|
||||
/**
|
||||
* {@link MethodHandleDesc} representing {@link ConstantBootstraps#getStaticFinal(Lookup, String, Class, Class) ConstantBootstraps.getStaticFinal}
|
||||
* @since 15
|
||||
*/
|
||||
public static final DirectMethodHandleDesc BSM_GET_STATIC_FINAL
|
||||
= ofConstantBootstrap(CD_ConstantBootstraps, "getStaticFinal",
|
||||
CD_Object, CD_Class);
|
||||
|
||||
/** {@link MethodHandleDesc} representing {@link ConstantBootstraps#nullConstant(Lookup, String, Class) ConstantBootstraps.nullConstant} */
|
||||
public static final DirectMethodHandleDesc BSM_NULL_CONSTANT
|
||||
= ofConstantBootstrap(CD_ConstantBootstraps, "nullConstant",
|
||||
ConstantDescs.CD_Object);
|
||||
CD_Object);
|
||||
|
||||
/** {@link MethodHandleDesc} representing {@link ConstantBootstraps#fieldVarHandle(Lookup, String, Class, Class, Class) ConstantBootstraps.fieldVarHandle} */
|
||||
public static final DirectMethodHandleDesc BSM_VARHANDLE_FIELD
|
||||
|
@ -219,6 +227,14 @@ public final class ConstantDescs {
|
|||
= ofConstantBootstrap(CD_ConstantBootstraps, "invoke",
|
||||
CD_Object, CD_MethodHandle, CD_Object.arrayType());
|
||||
|
||||
/**
|
||||
* {@link MethodHandleDesc} representing {@link ConstantBootstraps#explicitCast(Lookup, String, Class, Object)} ConstantBootstraps.explicitCast}
|
||||
* @since 15
|
||||
*/
|
||||
public static final DirectMethodHandleDesc BSM_EXPLICIT_CAST
|
||||
= ofConstantBootstrap(CD_ConstantBootstraps, "explicitCast",
|
||||
CD_Object, CD_Object);
|
||||
|
||||
/** {@link ClassDesc} representing the primitive type {@code int} */
|
||||
public static final ClassDesc CD_int = ClassDesc.ofDescriptor("I");
|
||||
|
||||
|
@ -251,6 +267,22 @@ public final class ConstantDescs {
|
|||
= DynamicConstantDesc.ofNamed(ConstantDescs.BSM_NULL_CONSTANT,
|
||||
DEFAULT_NAME, ConstantDescs.CD_Object);
|
||||
|
||||
/**
|
||||
* Nominal descriptor representing the constant {@linkplain Boolean#TRUE}
|
||||
* @since 15
|
||||
*/
|
||||
public static final DynamicConstantDesc<Boolean> TRUE
|
||||
= DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL,
|
||||
"TRUE", CD_Boolean, CD_Boolean);
|
||||
|
||||
/**
|
||||
* Nominal descriptor representing the constant {@linkplain Boolean#TRUE}
|
||||
* @since 15
|
||||
*/
|
||||
public static final DynamicConstantDesc<Boolean> FALSE
|
||||
= DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL,
|
||||
"FALSE", CD_Boolean, CD_Boolean);
|
||||
|
||||
static final DirectMethodHandleDesc MHD_METHODHANDLE_ASTYPE
|
||||
= MethodHandleDesc.ofMethod(Kind.VIRTUAL, CD_MethodHandle, "asType",
|
||||
MethodTypeDesc.of(CD_MethodHandle, CD_MethodType));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2020, 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
|
||||
|
@ -355,6 +355,71 @@ public final class ConstantBootstraps {
|
|||
return MethodHandles.arrayElementVarHandle(validateClassAccess(lookup, arrayClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a conversion from a source type to a destination type.
|
||||
* <p>
|
||||
* Given a destination type {@code dstType} and an input
|
||||
* value {@code value}, one of the following will happen:
|
||||
* <ul>
|
||||
* <li>If {@code dstType} is {@code void.class},
|
||||
* a {@link ClassCastException} is thrown.
|
||||
* <li>If {@code dstType} is {@code Object.class}, {@code value} is returned as is.
|
||||
* </ul>
|
||||
* <p>
|
||||
* Otherwise one of the following conversions is applied to {@code value}:
|
||||
* <ol>
|
||||
* <li>If {@code dstType} is a reference type, a reference cast
|
||||
* is applied to {@code value} as if by calling {@code dstType.cast(value)}.
|
||||
* <li>If {@code dstType} is a primitive type, then, if the runtime type
|
||||
* of {@code value} is a primitive wrapper type (such as {@link Integer}),
|
||||
* a Java unboxing conversion is applied {@jls 5.1.8} followed by a
|
||||
* Java casting conversion {@jls 5.5} converting either directly to
|
||||
* {@code dstType}, or, if {@code dstType} is {@code boolean},
|
||||
* to {@code int}, which is then converted to either {@code true}
|
||||
* or {@code false} depending on whether the least-significant-bit
|
||||
* is 1 or 0 respectively. If the runtime type of {@code value} is
|
||||
* not a primitive wrapper type a {@link ClassCastException} is thrown.
|
||||
* </ol>
|
||||
* <p>
|
||||
* The result is the same as when using the following code:
|
||||
* <blockquote><pre>{@code
|
||||
* MethodHandle id = MethodHandles.identity(dstType);
|
||||
* MethodType mt = MethodType.methodType(dstType, Object.class);
|
||||
* MethodHandle conv = MethodHandles.explicitCastArguments(id, mt);
|
||||
* return conv.invoke(value);
|
||||
* }</pre></blockquote>
|
||||
*
|
||||
* @param lookup unused
|
||||
* @param name unused
|
||||
* @param dstType the destination type of the conversion
|
||||
* @param value the value to be converted
|
||||
* @return the converted value
|
||||
* @throws ClassCastException when {@code dstType} is {@code void},
|
||||
* when a cast per (1) fails, or when {@code dstType} is a primitive type
|
||||
* and the runtime type of {@code value} is not a primitive wrapper type
|
||||
* (such as {@link Integer})
|
||||
*
|
||||
* @since 15
|
||||
*/
|
||||
public static Object explicitCast(MethodHandles.Lookup lookup, String name, Class<?> dstType, Object value)
|
||||
throws ClassCastException {
|
||||
if (dstType == void.class)
|
||||
throw new ClassCastException("Can not convert to void");
|
||||
if (dstType == Object.class)
|
||||
return value;
|
||||
|
||||
MethodHandle id = MethodHandles.identity(dstType);
|
||||
MethodType mt = MethodType.methodType(dstType, Object.class);
|
||||
MethodHandle conv = MethodHandles.explicitCastArguments(id, mt);
|
||||
try {
|
||||
return conv.invoke(value);
|
||||
} catch (ClassCastException e) {
|
||||
throw e; // specified, let CCE through
|
||||
} catch (Throwable throwable) {
|
||||
throw new InternalError(throwable); // Not specified, throw InternalError
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> Class<T> validateClassAccess(MethodHandles.Lookup lookup, Class<T> type) {
|
||||
try {
|
||||
lookup.accessClass(type);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue