-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Emit method reference lambdas without helper method #9022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
lrytz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add some tests around serialization, ensure that the generated $deserializeLambda$ works as intended?
src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
Outdated
Show resolved
Hide resolved
src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
Outdated
Show resolved
Hide resolved
a8890ff to
75667a5
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
lrytz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
I guess t8549.scala failing is OK / expected?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Under -Ydelambdafy:method-ref, when a lambda is just invoking a method (i.e. is "just a method reference"), such as `foo()` or `x => bar(x)`, then rather than emit an `invokedynamic` to a helper method that invokes the target method, emit an `invokedynamic` to the target method directly.
| val lambdaTarget = originalTarget.attachments.get[JustMethodReference].map(_.lambdaTarget).getOrElse(originalTarget) | ||
| def asmType(sym: Symbol) = classBTypeFromSymbol(sym).toASMType | ||
|
|
||
| val isInterface = lambdaTarget.owner.isTrait |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dwijnand This needs to be generalized to isTraitOrInterface now that lambda implementation methods may be owned by Java interfaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Removing the release-notes label as this is still experimental and not something that most users would need. |
Under -Ydelambdafy:method-ref, when a lambda is just invoking a method
(i.e. is "just a method reference"), such as
foo()orx => bar(x),(and other caveats around specialisation, boxing concerns for primitives
and its value classes, arrays, etc) then rather than emit an
invokedynamicto a helper method that invokes the target method, emitan
invokedynamicto the target method directly.$deserializeLambda$works as intendedExplanation
Note that this is opt-in, with
-Ydelambdafy:method-ref. The reason it's opt-in is because there's an assumption (an "invariant") in serialisation: if you serialise the lambda from one version of some code (v1) then deserialising it in a later version (v2) should run the new (v2) behaviour.For example, if you serialise the lambda
(x => x.toString())then deserialise it when the code is(x => x.toString().toUpperCase()), then the result should be upper-cased. Under-Ydelambdafy:method-refthe deserialised lambda will continue to just be a reference to Object'stoStringmethod. Also worth mentioning that in the same example, but with the versions swapped, the lambda will be a reference an$anonfun$...method that no longer exists in v2... which means that it will throw aLinkageErrorat runtime.