invokedynamic and subclasses
Douglas Campos
qmx at qmx.me
Wed Jun 24 14:40:18 UTC 2015
JRuby also chains the bootstraps, you might find inspiration here:
https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/invokedynamic/InvokeDynamicSupport.java
On Wed, Jun 24, 2015 at 11:25 AM, Mike Jarmy <mjarmy at gmail.com> wrote:
> Jochen -- that comes tantalizingly close to making sense to me :-). I
> don't quite follow all of the terminology yet, but the basic idea that you
> describe of chaining bootstrap calls is sort of like what I had vaguely
> designed in my head. Once I am doing learning how all this works I should
> be able to make my language work just the way I hoped it would.
>
> On Wed, Jun 24, 2015 at 10:16 AM, Jochen Theodorou <blackdrag at gmx.org>
> wrote:
>
>> Hi Mike,
>>
>> First of all, the bootstrap method does not have to be in the same class.
>> In Groovy we have for example one bootstrap method for all classes only. It
>> is part of the runtime then you could say.
>>
>>
>> We do it like this. We have two bootstrap methods in the Groovy runtime
>> (you don't need to have them in the class). The first one is normally
>> called and will produce a handle to call the second one. I tend to call the
>> first one the static bootstrapper and the second one the dynamic
>> bootstrapper. The dynamic bootstrapper will be called like a method (takes
>> an Object[]), thus I will have all the arguments of the call as well as the
>> receiver. This I can use to identify runtime classes and produce a new
>> handle that fits my needs and replaces the first one. This method also is a
>> fallback. The installed handle usually has to be guarded (like first call
>> with B, second with C), and we use the dynamic bootstrapper as fallback. Of
>> course you can easily check more cases and implement a polymorphic inline
>> cache.
>>
>> Of course that implies, that if the dynamic bootstrapper is called it
>> will also have to do the first execution of the target (like getting the
>> value of the field foo). We use (part of) the produced method handle for
>> this. And of course the callsite will have to be mutable then
>>
>> Does this help you out? It works quite good for Groovy.
>>
>> bye blackdrag
>>
>>
>> Am 24.06.2015 14:19, schrieb Mike Jarmy:
>>
>>> I've been experimenting with invokedynamic in a compiler for a dynamic
>>> language
>>> that I'm working on, and I've run into a problem that I'm having
>>> difficulty
>>> solving.
>>>
>>> Let's say I have a class called A (Java syntax used for clarity):
>>>
>>> public class A {
>>> }
>>>
>>> And another called B, that is a subclass of A:
>>>
>>> public class B extends A {
>>> public Value foo;
>>> public Value bar;
>>> }
>>>
>>> There will be lots of other subclasses of A as well (let's call them C,
>>> D, E,
>>> etc), some of which will have a field called foo, and some of which
>>> won't. The
>>> class A will never have any fields -- its sole purpose is to be the base
>>> class
>>> of everything else.
>>>
>>> I have been able to successfully use a static bootstrap method in B, so
>>> that I
>>> can compile a call to invokedynamic on the imaginary method get_foo() of
>>> an
>>> instance of B, and then reroute the call inside B's bootstrap method via
>>> MethodHandles.Lookup.findGetter(), and finally return the current value
>>> of foo.
>>> So far, so good.
>>>
>>> However, at the place where I am compiling the invokedynamic
>>> instruction, I
>>> have no idea if the target is a B, C, D, or what. All I know is that it
>>> must
>>> be an A.
>>>
>>> So what I really want to be able to do (I think) is to use a static
>>> bootstrap
>>> method in A. I want get_foo() to succeed for every invokedynamic call to
>>> an
>>> instance of A who's *subclass* really does have a field called foo.
>>>
>>> Unfortunately there doesn't seem to be a way to make A do what I want. I
>>> understand why that is -- foo doesn't exist in A, so there is no way to
>>> create
>>> a findGetter() call. But I'm hoping there might be some clever way to
>>> do it
>>> anyway. I've tried all kinds of different approaches (making yet another
>>> invokedynamic call from inside A, etc, etc) but I can't come up with
>>> anything
>>> that works.
>>>
>>> Any ideas?
>>>
>>> By the way, I've figured out how to do this the "old" way, by generating
>>> interfaces for each class that has e.g. a foo field, and casting to that
>>> interface every time I compile a get_foo() invocation. This works, and
>>> its
>>> reasonably performant, but using invokedynamic seems like it would be a
>>> more
>>> elegant and flexible solution.
>>>
>>>
>>>
>>> _______________________________________________
>>> mlvm-dev mailing list
>>> mlvm-dev at openjdk.java.net
>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>>>
>>>
>>
>> --
>> Jochen "blackdrag" Theodorou
>> blog: http://blackdragsview.blogspot.com/
>>
>>
>> _______________________________________________
>> mlvm-dev mailing list
>> mlvm-dev at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>>
>
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20150624/d9230709/attachment.html>
More information about the mlvm-dev
mailing list