Add capturing method references#18818
Merged
rmuir merged 3 commits intoelastic:masterfrom Jun 10, 2016
Merged
Conversation
18 tasks
| import java.lang.invoke.LambdaMetafactory; | ||
|
|
||
| /** | ||
| * Represents a capturing function reference. |
Contributor
There was a problem hiding this comment.
Please add this to the package-info as well.
Contributor
|
LGTM! Thanks for tackling this, I realize it's quite complicated. (Added one important comment after the fact.) |
| if (defInterface && captured.type.sort == Definition.Sort.DEF) { | ||
| // dynamic interface, dynamic implementation | ||
| writer.push("D" + type + "." + call + ",1"); | ||
| writer.loadLocal(captured.slot); |
Contributor
There was a problem hiding this comment.
I don't think you can use this method because it won't necessarily store the type correctly since we do the slots ourself to avoid trash being on the stack with variables scopes and such. Instead you'll have to use writer.visitVarInsn(asmtype.getOpcode(Opcodes.ILOAD), slot);
Contributor
Author
|
@jdconrad I pushed some commits and merged master. |
Contributor
|
+1. Merge it! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#18748 added non-capturing method references of the forms (
Class::virtualMethod,Class::staticMethod,Class::new).This PR adds support for capturing references such as
instance::virtualMethod. The main benefit is enhancing our lambda support, especially on the dynamic side. I also cleaned up DefBootstrap to be less confusing, it takes varargs (depending onflavor), and has error checks around this.For any lambda we have two main parts: the interface type of the parameter, and the implementation method. For this to work, we add a new flavor to DefBootstrap called
REFERENCE. Its basically just a dynamicLambdaMetaFactory, taking expected interface type as a parameter, but it resolves the implementation method with a dynamic lookup based on receiver's class. Then it calls LambdaMetaFactory. Its cached on receiver's class just like anything else.There are 4 cases, based on what we know at compile time.
type.foo(anothertype::bar)type.foo(def::bar)def.foo(type::bar)def.foo(def::bar)cases 4 and 3 are just like 2 and 1, respectively, except deferred. The placeholder signature on the stack was extended, to support the number of capture arguments.
case 1 is completely static. We just call
LambdaMetaFactorylike java would, only we capture the reference of the instance.case 2 is very similar, except instead of calling
LambdaMetaFactory, we use the newREFERENCEDefBootstrap.case 3 defers the call to LambdaMetaFactory until the interface type is resolved.
case 4 defers the call to
DefBootstrapuntil the interface is resolved.case 4 does mean we nest a cache inside a cache, but its what we need: the two things are really independent. Our scripts are small, its contained and does not recurse, and we don't want bad performance.