Constant descriptor resolved too soon during constant resolution?
Jorn Vernee
jbvernee at xs4all.nl
Thu Aug 2 15:36:29 UTC 2018
Hello,
I think I have stumbled upon a bug in the condy-folding branch (tip).
This is the code to reproduce:
```
import java.lang.constant.*;
import static java.lang.constant.ConstantDescs.*;
public class Main {
static final DirectMethodHandleDesc MHR_CONCAT =
MethodHandleDesc.of(
DirectMethodHandleDesc.Kind.VIRTUAL,
CR_String,
"concat",
CR_String,
CR_String
);
public static void main(String[] args) throws Throwable {
ConstantDesc<String> d =
DynamicConstantDesc.<String>of(BSM_INVOKE).withArgs(MHR_CONCAT, "Hello,
", "world!");
System.out.println(d); // <---- exception thrown here, on
resolution of `d2`
}
}
```
I'm wrapping a call to `ConstantBootstraps.invoke` together with a
method handle for `String.concat` and 2 constant arguments (a toy
example). The resolution should effectively call `"Hello,
".concat("world!")`. Please note that I'm not resolving the result
string here though, but I'm resolving the descriptor itself. While
resolving the descriptor `d` an exception is thrown:
```
Exception in thread "main" java.lang.BootstrapMethodError: bootstrap
method initialization exception
at
java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:253)
at
java.base/java.lang.invoke.ConstantBootstraps.makeConstant(ConstantBootstraps.java:71)
at
java.base/java.lang.invoke.MethodHandleNatives.linkDynamicConstantImpl(MethodHandleNatives.java:314)
at
java.base/java.lang.invoke.MethodHandleNatives.linkDynamicConstant(MethodHandleNatives.java:306)
at Main.main(Main.java:18)
Caused by: java.lang.ClassCastException: Cannot cast
java.lang.invoke.DirectMethodHandle to java.lang.constant.ConstantDesc
at java.base/java.lang.Class.cast(Class.java:3613)
at
java.base/java.lang.invoke.BootstrapMethodInvoker.invokeWithManyArguments(BootstrapMethodInvoker.java:350)
at
java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:195)
... 4 more
```
This puzzled me for a while, but I _think_ the cause is that the
`MHR_CONCAT` descriptor is being resolved into a `DirectMethodHandle`
too early during resolution? Oddly enough, when using
`Intrinsics.ldc(d)` to resolve the result string, the program completes
successfully, and I can print the resulting string. The following
version also works as expected:
```
ConstantDesc<String> d = DynamicConstantDesc.of(
BSM_INVOKE, DEFAULT_NAME, CR_Object, new
ConstantDesc<?>[]{MHR_CONCAT, "Hello, ", "world!"}); // No folding here,
because the array is not a constant (?)
System.out.println(d); // This one is OK
```
And it prints:
`DynamicConstantDesc[ConstantBootstraps::invoke(MethodHandleDesc[VIRTUAL/String::concat(String)String],Hello,
,world!)Object]`. As far as I can tell these 2 snippets should behave
the same (the generated bytecode is quite different though), so I think
this is a bug?
Is there a flag to temporarily turn off folding? I'm not aware of any
javac equivalent of `-XX:+PrintFlagsFinal`, so I don't have a way to
find out about experimental flags.
Also, I hope this is the right place to post bug reports, JBS doesn't
seem to cover amber, and I've seen a few people reporting bugs on other
mailing lists, but I'd expect more people to be doing that, so maybe I'm
in the wrong place?
Best regards,
Jorn Vernee
More information about the amber-dev
mailing list