> De: "mandy chung" <mandy.ch...@oracle.com>
> À: "Remi Forax" <fo...@univ-mlv.fr>, "core-libs-dev"
> <core-libs-dev@openjdk.java.net>
> Envoyé: Lundi 30 Novembre 2020 19:16:25
> Objet: Re: Lookup.defineAnonymousClass() vs indy

> 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 ?
Here the parameter of the lambda bridge is a captured local variable, it feels 
wrong to me to have s special case if the first captured local variable as the 
same type as the owning/enclosing class. 
And when you compile a class and generate the lambda bridge method, the 
compiler has no idea if the class will be used as an hidden class or not. 

The real question is why the descriptor is not rewritten to replace the owning 
class by the hidden class when lookup.defineHiddenClass is called, i believe 
this is the behavior of unsafe.defineAnonymousClass. 

> Mandy
Rémi 

> 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