MethodHandler out of a non-static method
Giuseppe Barbieri
elect86 at gmail.com
Mon Jun 14 11:46:08 UTC 2021
Ok, I'm giving a try and use `::findVirtual` instead
MethodHandle displayHandle =
MethodHandles.lookup().findVirtual(teapot.getClass(), "display",
MethodType.methodType(void.class));
MemoryAddress displayStub =
CLinker.getInstance().upcallStub(displayHandle,
FunctionDescriptor.ofVoid(), scope);
this fires:
Exception in thread "main" java.lang.IllegalArgumentException: Arity
mismatch: (Teapot)void != ()v
at
jdk.incubator.foreign/jdk.internal.foreign.abi.SharedUtils.checkFunctionTypes(SharedUtils.java:237)
at
jdk.incubator.foreign/jdk.internal.foreign.abi.x64.sysv.CallArranger.getBindings(CallArranger.java:89)
at
jdk.incubator.foreign/jdk.internal.foreign.abi.x64.sysv.CallArranger.arrangeUpcall(CallArranger.java:138)
at
jdk.incubator.foreign/jdk.internal.foreign.abi.x64.sysv.SysVx64Linker.upcallStub(SysVx64Linker.java:111)
at Teapot.main(Teapot.java:61)
I can see the signature coherent with what you said. `::findVirtual` does
return signature of (Teapot)void
So the problems seems to be inside
FunctionDescriptor.ofVoid()
or?
Just for context, this is the signature of the function expecting
`displayStub`
glutDisplayFunc(Addressable var0)
And I also have
MethodHandle glutDisplayFunc$MH()
but I have no idea if this might play a role in this
Il giorno mar 8 giu 2021 alle ore 10:34 Remi Forax <forax at univ-mlv.fr> ha
scritto:
> >
> > Another question, I'm trying to setup a test project with Gradle, but I'm
> > having a lot of issues, mainly because Gradle supports only up to jdk 16.
>
> Don't use Gradle with a not yet released JDK.
> Gradle is very smart in the way it incrementally compile things, but it
> has the price of not working with unreleased JDK.
> A plain old Maven pom file is usually enough.
>
This is quite a pity, because other than I'm used to relying on Gradle, it
actually can automate a lot and make the lives of us devs much nicer.
I'm actually working in this sense on the existing jextract plugin,
enhancing it.
Also, just to say, Gradle actually works with the latest panama 17 build on
the website, I managed to get the opengl example running under Java (with
the modification above regarding callbacks)
The only problem I got so far, it's that I can't get it to work with
Kotlin, I keep getting errors on the imports, such as
import jdk.incubator.ResourceScope
I wonder if anyone here had success with it
Giuseppe
Il giorno mar 8 giu 2021 alle ore 10:34 Remi Forax <forax at univ-mlv.fr> ha
scritto:
> ----- Mail original -----
> > De: "Giuseppe Barbieri" <elect86 at gmail.com>
> > À: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> > Cc: "panama-dev at openjdk.java.net'" <panama-dev at openjdk.java.net>
> > Envoyé: Mardi 8 Juin 2021 09:26:15
> > Objet: Re: MethodHandler out of a non-static method
>
> > Thanks Maurizio and Remi, that helped
> >
> > Playing around I also got it working by using `bind`
> >
> > var displayHandle = MethodHandles.lookup().bind(teapot, "display",
> > MethodType.methodType(void.class));
> > var displayStub = CLinker.getInstance().upcallStub(displayHandle,
> > FunctionDescriptor.ofVoid(), scope);
> >
> >
> > What's the difference? Because I'd expect for `findVirtual` to be used
> only
> > on methods in implementation classes of abstract classes
>
> A method handle unlike its name suggest is a function pointer, not a
> method pointer.
> So when you take a method and ask for a function pointer to it, you have a
> supplementary first parameter, the one corresponding to this.
>
> By example, for
> class A {
> void foo(int i) { ... }
> }
>
> findVirtual returns a method handle with the signature: void foo(A this,
> int i)
>
> if you want to call a method handle always on the same instance, you can
> use bindTo() (or insertArguments),
> to say that the first argument is always that same
>
> var a = new A();
> var mh = ...
> var boundMH = mh.bindTo(a);
>
> Here, boundMH is "void foo(A this, int i)" with this = a
> so it's a function with only one parameter, i of type int.
>
> Now what bind() does is findVirtual(getClass(), ...) + bindTo,
> on your example
> var mh = lookup.findVirtual(teapot.getClass(), "display",
> MethodType.methodType(void.class));
> mh = mh.bindTo(teapot);
>
> This idea that when you want to see a method as a function, you can pass
> the receiver (the value of 'this') as first argument is something very
> common in programming language,
> you have it with method handle but you also have it when using method
> reference in Java or bound method in Python [1], the method bind in
> JavaScript [2], etc.
>
> Using method reference:
> // method reference seen as a function
> BiConsumer<PrintStream, Object> consumer = PrintStream::println;
>
> // bound method reference
> PrintStream out = System.out;
> Consumer<Object> consumer = out::println;
>
>
> >
> > Another question, I'm trying to setup a test project with Gradle, but I'm
> > having a lot of issues, mainly because Gradle supports only up to jdk 16.
>
> Don't use Gradle with a not yet released JDK.
> Gradle is very smart in the way it incrementally compile things, but it
> has the price of not working with unreleased JDK.
> A plain old Maven pom file is usually enough.
>
> >
> > Is possible to run your application with a separate jdk (toolchain) but
> > then you need to use the `application` plugin and cannot rely anymore on
> > the comfortable Idea UI.
> > Unless you switch and run your code using the IDE instead of Gradle, but
> > then I get into some other exceptions. Moreover, some imports remain
> still
> > unresolved.
> >
> > So, I'd like to skip this trainwreck all at once and ask directly if
> > anybody here has a working base scenario with the latest EA jdk 17 and
> > Gradle
> >
> >
> > Thanks in advance
>
> regards,
> Rémi
>
> [1] https://www.quora.com/What-is-a-bound-method-in-Python
> [2]
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
>
> >
> >
> >
> > Il giorno gio 3 giu 2021 alle ore 11:33 Maurizio Cimadamore <
> > maurizio.cimadamore at oracle.com> ha scritto:
> >
> >> Hi Giuseppe
> >>
> >> On 02/06/2021 23:52, Giuseppe Barbieri wrote:
> >> > Hi,
> >> >
> >> > excited from the last development, I came back giving a try to the
> latest
> >> > jdk build (the partial 17 available on the site) and I'm trying to
> >> > update/fix the opengl sample
> >> >
> >> > First of all, it looks like `jextract` doesn't accept anymore the
> option
> >> to
> >> > produce an output jar. I had to manually compress the resulting
> folder to
> >> > zip and rename, before importing in the target project.
> >>
> >> We decided to simplify jextract and focus on source code generation,
> >> which seems to be the mode that most people want to work with, and it's
> >> also the "more primitive": you can derive classes (and jars) from it.
> >>
> >> If you are using it in a project, you might consider directly checking
> >> in the extracted sources in your project. If you are using an IDE, it is
> >> going to improve your experience a little bit (the classfiles generated
> >> by the old jextract were poorly understood by some of the IDEs out
> >> there, which led to issues in indexing).
> >>
> >
> >
> >
> >
> >
> >>
> >> >
> >> > It'd be cool if jextract could output directly the jar (and the
> sources)
> >> >
> >> > Coming back to my issue, how can I retrieve the MethodHandler out of a
> >> > non-static method?
> >>
> >> You mean you want to create a MethodHandle for an instance method?
> >>
> >> Let's see (I'll use jshell to make sure my code doesn't have any typos
> >> :-) ):
> >>
> >> ```
> >> jshell> class Foo {
> >> ...> void greet(String msg) { System.out.println(msg); }
> >> ...> }
> >> | created class Foo
> >>
> >> jshell> import java.lang.invoke.*;
> >>
> >> jshell> MethodHandle greetMH =
> >> MethodHandles.lookup().findVirtual(Foo.class, "greet",
> >> MethodType.methodType(void.class, String.class));
> >> greetMH ==> MethodHandle(Foo,String)void
> >>
> >> jshell> greetMH.invoke(new Foo(), "Panama");
> >> Panama
> >> ```
> >>
> >> Is this what you were looking for?
> >>
> >> Cheers
> >> Maurizio
> >>
> >> >
> >> >
> >> > Thanks in advance
>
More information about the panama-dev
mailing list