-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
None
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
Currently, when one needs to create a `PoolEntry` (or `BootstrapMethodEntry`) without having access to a `ConstantPoolBuilder`, one has to either use shenanigans¹ to get the `TemporaryConstantPool` or create a new heavy‑weight `SplitConstantPool` using `ConstantPoolBuilder.of()`, neither of which is ideal.
I propose to add static factory methods to the individual `PoolEntry` subtypes of the form:
```java
public static ${EntryName} of(${ArgDecls}) {
return TemporaryConstantPool.INSTANCE.${methodName}(${argNames});
}
```
e.g.:
For `Utf8Entry`:
```java
public static Utf8Entry of(String s) {
return TemporaryConstantPool.INSTANCE.utf8Entry(s);
}
public static Utf8Entry of(ClassDesc desc) {
return TemporaryConstantPool.INSTANCE.utf8Entry(desc);
}
public static Utf8Entry of(MethodTypeDesc desc) {
return TemporaryConstantPool.INSTANCE.utf8Entry(desc);
}
```
For `MethodTypeEntry`:
```java
public static MethodTypeEntry of(Utf8Entry descriptor) {
return TemporaryConstantPool.INSTANCE.methodTypeEntry(descriptor);
}
public static MethodTypeEntry of(MethodTypeDesc descriptor) {
return TemporaryConstantPool.INSTANCE.methodTypeEntry(descriptor);
}
```
etc. for all the other leaf `PoolEntry` subtypes and `BootstrapMethodEntry`.
--------------------------------------------------------------------------------
¹ The shenanigans to obtain the `TemporaryConstantPool` instance:
```java
/*
* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/
*/
public final class TempConstantPoolAccess {
private TempConstantPoolAccess() {}
private static final ConstantPoolBuilder INSTANCE;
static {
ConstantPoolBuilder builder = null;
try {
builder = (ConstantPoolBuilder) AnnotationValue.ofString("").constant().constantPool();
} catch (ClassCastException _) {
}
INSTANCE = builder;
}
/**
* {@return the JDK internal {@link jdk.internal.classfile.impl.TemporaryConstantPool
* TemporaryConstantPool} instance} Care must be taken to only call methods
* which are actually implemented by the internal builder.
*
* @see https://bugs.openjdk.org/browse/JI-9077894
*/
public static final ConstantPoolBuilder tempConstantPool() {
if (INSTANCE != null) {
return INSTANCE;
}
// fallback to heavy-weight SplitConstantPool:
return SplitConstantPool.of();
}
}
```
--------------------------------------------------------------------------------
Depends on:
- https://bugs.openjdk.org/browse/JI-9077894
Currently, when one needs to create a `PoolEntry` (or `BootstrapMethodEntry`) without having access to a `ConstantPoolBuilder`, one has to either use shenanigans¹ to get the `TemporaryConstantPool` or create a new heavy‑weight `SplitConstantPool` using `ConstantPoolBuilder.of()`, neither of which is ideal.
I propose to add static factory methods to the individual `PoolEntry` subtypes of the form:
```java
public static ${EntryName} of(${ArgDecls}) {
return TemporaryConstantPool.INSTANCE.${methodName}(${argNames});
}
```
e.g.:
For `Utf8Entry`:
```java
public static Utf8Entry of(String s) {
return TemporaryConstantPool.INSTANCE.utf8Entry(s);
}
public static Utf8Entry of(ClassDesc desc) {
return TemporaryConstantPool.INSTANCE.utf8Entry(desc);
}
public static Utf8Entry of(MethodTypeDesc desc) {
return TemporaryConstantPool.INSTANCE.utf8Entry(desc);
}
```
For `MethodTypeEntry`:
```java
public static MethodTypeEntry of(Utf8Entry descriptor) {
return TemporaryConstantPool.INSTANCE.methodTypeEntry(descriptor);
}
public static MethodTypeEntry of(MethodTypeDesc descriptor) {
return TemporaryConstantPool.INSTANCE.methodTypeEntry(descriptor);
}
```
etc. for all the other leaf `PoolEntry` subtypes and `BootstrapMethodEntry`.
--------------------------------------------------------------------------------
¹ The shenanigans to obtain the `TemporaryConstantPool` instance:
```java
/*
* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/
*/
public final class TempConstantPoolAccess {
private TempConstantPoolAccess() {}
private static final ConstantPoolBuilder INSTANCE;
static {
ConstantPoolBuilder builder = null;
try {
builder = (ConstantPoolBuilder) AnnotationValue.ofString("").constant().constantPool();
} catch (ClassCastException _) {
}
INSTANCE = builder;
}
/**
* {@return the JDK internal {@link jdk.internal.classfile.impl.TemporaryConstantPool
* TemporaryConstantPool} instance} Care must be taken to only call methods
* which are actually implemented by the internal builder.
*
* @see https://bugs.openjdk.org/browse/JI-9077894
*/
public static final ConstantPoolBuilder tempConstantPool() {
if (INSTANCE != null) {
return INSTANCE;
}
// fallback to heavy-weight SplitConstantPool:
return SplitConstantPool.of();
}
}
```
--------------------------------------------------------------------------------
Depends on:
- https://bugs.openjdk.org/browse/JI-9077894