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