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
that I'm working on, and I've run into a problem that I'm having difficulty

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
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
be an A.

So what I really want to be able to do (I think) is to use a static
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
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
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

Jochen "blackdrag" Theodorou
blog: http://blackdragsview.blogspot.com/

mlvm-dev mailing list

Reply via email to