The implementation method to be invoked for this lambda is a static bridge 
method
taking this hidden class's instance as the parameter, i.e. a descriptor 
referencing
a hidden class, which will fail to resolve.


 0: #104 REF_invokeStatic 
java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #111 ()V
      #112 REF_invokeStatic 
HiddenClassWithIndy.lambda$test$0:(LHiddenClassWithIndy;)V
      #111 ()V


Now that a hidden class is a nestmate, should/can this bridge method be an instance method if this class is defined as a hidden class?

Mandy

On 11/29/20 7:34 AM, Remi Forax wrote:
Hi Mandy, hi all,
it seems that when defineAnonymousClass rewrites the currentClass, it doesn't 
work if there is an invokedynamic in the classfile, so defineHiddenClass fails 
with a VerifyError when the hidden class is verified.

Here is an example showing the issue
---
import java.io.IOException;
import java.lang.invoke.MethodHandles;

public class HiddenClassWithIndy {
   public void test() {
     var a = new HiddenClassWithIndy();
     Runnable r = () -> System.out.println(a);
   }

   public static void main(String[] args) throws IOException, 
IllegalAccessException {
     byte[] bytecode;
     try(var input = 
HiddenClassWithIndy.class.getClassLoader().getResourceAsStream(HiddenClassWithIndy.class.getName().replace('.',
 '/') + ".class")) {
       if (input == null) {
         throw new AssertionError();
       }
       bytecode = input.readAllBytes();
     }
     var hiddenLookup = MethodHandles.lookup().defineHiddenClass(bytecode, 
true);
   }
}

---
The error message:
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
   Location:
     fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400.test()V @9: 
invokedynamic
   Reason:
     Type 'fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400' (current 
frame, stack[0]) is not assignable to 'fr/umlv/transmogrif/HiddenClassWithIndy'
   Current Frame:
     bci: @9
     flags: { }
     locals: { 'fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400', 
'fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400' }
     stack: { 'fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400' }
   Bytecode:
     0000000: bb00 0759 b700 094c 2bba 000a 0000 4db1
     0000010:

        at java.base/java.lang.ClassLoader.defineClass0(Native Method)
        at java.base/java.lang.System$2.defineClass(System.java:2193)
        at 
java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(MethodHandles.java:2235)
        at 
java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClassAsLookup(MethodHandles.java:2216)
        at 
java.base/java.lang.invoke.MethodHandles$Lookup.defineHiddenClass(MethodHandles.java:1952)
        at 
fr.umlv.transmogrif.HiddenClassWithIndy.main(HiddenClassWithIndy.java:20)

regards,
Rémi

Reply via email to