Skip to content

Illegal arguments for bootstrap method for invokedynamic #15736

Closed
@ddtthh

Description

@ddtthh

Compiler version

3.1.3

Description

When compiling a lambda, the arguments to the generated bootstrap method in the generated class file violate the rules given in the JDK documentation. While this does not seem to cause any issues on OpenJDK, the Android Dexer d8 cannot handle this.

According to https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/invoke/LambdaMetafactory.html interfaceMethodType and dynamicMethodType have to fullfill the following constraints:

  • Same arity
  • Argument types and return types are either the same as in the interface, or in case of reference may be subtypes.
    There is no type conversion between primitive types and reference types

In the following example, the scala compiler generates a bootstrap method call to LambdaMetafactory.altMetafactory with
interfaceMethodType: (Ljava/lang/Object;)Ljava/lang/Object;
dynamicMethodType: (Ljava/lang/Object;)Z

This clearly violates the specifiaction of LambdaMetafactory.
The dynamicMethodeType should be (Ljava/lang/Object;)Ljava/lang/Boolean;

It is ok for the MethodHandle supplied as implementation to have a MethodType of (Ljava/lang/Object;)Z, LambdaMetafactory will handle boxing, but the dynamicMethodType has to specify the boxed types.

Minimized code

class Foo[T]():
  val f = (x: T) => true

Output

Taken from javap -private -c -v

BootstrapMethods:
  0: #29 REF_invokeStatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #14 (Ljava/lang/Object;)Ljava/lang/Object;
      #19 REF_invokeStatic Foo.$init$$$anonfun$1:(Ljava/lang/Object;)Z
      #20 (Ljava/lang/Object;)Z
      #21 5
      #22 1
      #20 (Ljava/lang/Object;)Z

Expectation

Taken from javap -private -c -v

BootstrapMethods:
  0: #29 REF_invokeStatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #14 (Ljava/lang/Object;)Ljava/lang/Object;
      #19 REF_invokeStatic Foo.$init$$$anonfun$1:(Ljava/lang/Object;)Z
      #20 (Ljava/lang/Object;)Ljava/lang/Boolean;
      #21 5
      #22 1
      #20 (Ljava/lang/Object;)Z

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions