Panama unresolved error when instantiating wayland struct...
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Feb 15 10:22:44 UTC 2019
On 15/02/2019 01:33, Mark Hammons wrote:
> I was wrong in my previous email. The issue is still fixed for me, but
> the fix was not because of a change in jextract usage, but rather the
> inclusion of this in my code:
>
> val lib = Libraries.bind(MethodHandles.lookup,
> classOf[wayland.wayland_server_core])
I was just about to suggest doing that (I came upon the same trick
overnight) - but I wanted to try with your specific case first!
I'm super happy that this trick works for you.
Binding the library gives a couple of kicks to the resolution logic, so
that it performs as it should.
In other words, in the current state, if you want to allocate a struct
defined in some library, it's always better to bind the whole library
first (even if one doesn't plan to use it).
I'll add this workaround to the JBS entry.
Thanks again for the report - and, yes, we'll fix this in the next EA,
as this is very frustrating/confusing (sorry!).
Maurizio
>
> I never use lib, but if I remove that line the allocation of
> wl_listener starts failing again.
>
> Mark
>
> On 2/15/19 2:14 AM, Maurizio Cimadamore wrote:
>> Thanks Jorn - clever approach; I'll give this some though to make
>> sure it covers all the bases.
>>
>> Maurizio
>>
>> On 15/02/2019 01:06, Jorn Vernee wrote:
>>> FWIW, I've previously used the following fix to work around a
>>> similar issue (also involving a linked lists).
>>>
>>> (Rough) Webrev:
>>> http://cr.openjdk.java.net/~jvernee/panama/webrevs/8219042/webrev.00/
>>>
>>> Cheers,
>>> Jorn
>>>
>>> Maurizio Cimadamore schreef op 2019-02-15 01:14:
>>>> Here's the bug reference I've created:
>>>>
>>>> https://bugs.openjdk.java.net/browse/JDK-8219042
>>>>
>>>> unfortunately, I tried allocating the structs in different order and
>>>> the problem cannot be resolved at the client side.
>>>>
>>>> Maurizio
>>>>
>>>> On 15/02/2019 00:06, Mark Hammons wrote:
>>>>> I previously allocated a wl_list in my code. I'm still new to the
>>>>> foreign interfaces, so I'm not aware if there's a way to allocate
>>>>> the wl_listener using a pre-allocated wl_list.
>>>>>
>>>>> Mark
>>>>>
>>>>> On 2/15/19 12:49 AM, Maurizio Cimadamore wrote:
>>>>>>
>>>>>> On 14/02/2019 23:38, Mark Hammons wrote:
>>>>>>> Hi Maurizio,
>>>>>>>
>>>>>>> No, wl_list is defined in wayland_utils.h while wl_listener is
>>>>>>> in wayland_server_core.h. I am currently looking through the
>>>>>>> issues on the openjdk tracker and seeing if there's a mitigation
>>>>>>> for this.
>>>>>>
>>>>>> Right - you beat me to this:
>>>>>>
>>>>>> https://people.freedesktop.org/~whot/wayland-doxygen/wayland/Server/structwl__listener.html
>>>>>> and
>>>>>>
>>>>>> https://people.freedesktop.org/~whot/wayland-doxygen/wayland/Server/structwl__list.html
>>>>>> Unfortunately this issue is not easy to workaround. I'll make
>>>>>> sure to create a JBS entry for it (we do have one, but it's
>>>>>> probably not visible outside).
>>>>>>
>>>>>> I'll also try to play with this a bit to see what can be done -
>>>>>> with this issue sometimes it helps to allocate the inner struct
>>>>>> first (e.g. wl_list), and then the one that depends on it (e.g.
>>>>>> wl_listener).
>>>>>>
>>>>>> Maurizio
>>>>>>
>>>>>>>
>>>>>>> ~Mark
>>>>>>>
>>>>>>> On 2/15/19 12:30 AM, Maurizio Cimadamore wrote:
>>>>>>>> Hi Mark,
>>>>>>>> thanks for the report - from the looks of it, it seems an issue
>>>>>>>> with cross-header layout resolution, which is listed in the
>>>>>>>> 'known issues' in the EA page:
>>>>>>>>
>>>>>>>> "Dynamic layout resolution doesn't work across multiple headers."
>>>>>>>>
>>>>>>>> I will check in more details tomorrow, and confirm, one way or
>>>>>>>> another.
>>>>>>>>
>>>>>>>> Quick check: are wl_list and wl_listener defined in the same
>>>>>>>> header file? If not that's likely the issue here.
>>>>>>>>
>>>>>>>> I think Pointer<?> is the correct type - jextract tries to
>>>>>>>> insert as more general types as possible when inserting Pointer
>>>>>>>> in argument position; if it generated Pointer<Void>, and that
>>>>>>>> was an ordinary function call, you could only call it with
>>>>>>>> another Pointer<Void> - if the argument type is Pointer<?> you
>>>>>>>> can pass _any_ pointer - e.g. Pointer<Byte>, Pointer<Integer>
>>>>>>>> which is kind of close to what you can do in C.
>>>>>>>>
>>>>>>>> Maurizio
>>>>>>>>
>>>>>>>> On 14/02/2019 22:23, Mark Hammons wrote:
>>>>>>>>> Hi all,
>>>>>>>>>
>>>>>>>>> I decided to try to take the dive on project panama, starting
>>>>>>>>> with making a binding to linux's wayland server. I used the
>>>>>>>>> following command: ~/bin/jdk-13/bin/jextract
>>>>>>>>> /usr/include/wayland/wayland-server-core.h
>>>>>>>>> /usr/include/wayland/wayland-server.h
>>>>>>>>> /usr/include/wayland/wayland-util.h
>>>>>>>>> /usr/include/wayland/wayland-version.h
>>>>>>>>> /usr/include/wayland/wayland-server-protocol.h -I
>>>>>>>>> /usr/include/wayland -L /usr/lib64/ --record-library-path -l
>>>>>>>>> wayland-server -t wayland -o wayland_server.jar
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> When I try to allocate a wl_listener struct, I get the
>>>>>>>>> following error:
>>>>>>>>>
>>>>>>>>> [error] Exception in thread "main"
>>>>>>>>> java.lang.UnsupportedOperationException: bitsSize on Unresolved
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.foreign.layout.Unresolved.bitsSize(Unresolved.java:76)
>>>>>>>>>
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.util.stream.ReferencePipeline$5$1.accept(ReferencePipeline.java:229)
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.util.stream.LongPipeline.reduce(LongPipeline.java:474)
>>>>>>>>>
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.util.stream.LongPipeline.sum(LongPipeline.java:432)
>>>>>>>>>
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.foreign.layout.Group.bitsSize(Group.java:119)
>>>>>>>>> [error] at
>>>>>>>>> java.base/java.foreign.memory.LayoutType.bytesSize(LayoutType.java:49)
>>>>>>>>> [error] at
>>>>>>>>> java.base/jdk.internal.foreign.ScopeImpl.allocateInternal(ScopeImpl.java:66)
>>>>>>>>> [error] at
>>>>>>>>> java.base/jdk.internal.foreign.ScopeImpl.allocate(ScopeImpl.java:92)
>>>>>>>>>
>>>>>>>>> [error] at
>>>>>>>>> java.base/jdk.internal.foreign.ScopeImpl.allocateStruct(ScopeImpl.java:98)
>>>>>>>>> [error] at
>>>>>>>>> TestApp$.delayedEndpoint$TestApp$1(TestApp.scala:22)
>>>>>>>>> [error] at TestApp$delayedInit$body.apply(TestApp.scala:13)
>>>>>>>>> [error] at scala.Function0.apply$mcV$sp(Function0.scala:39)
>>>>>>>>> [error] at scala.Function0.apply$mcV$sp$(Function0.scala:39)
>>>>>>>>> [error] at
>>>>>>>>> scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
>>>>>>>>> [error] at scala.App.$anonfun$main$1$adapted(App.scala:80)
>>>>>>>>> [error] at
>>>>>>>>> scala.collection.immutable.List.foreach(List.scala:392)
>>>>>>>>> [error] at scala.App.main(App.scala:80)
>>>>>>>>> [error] at scala.App.main$(App.scala:78)
>>>>>>>>> [error] at TestApp$.main(TestApp.scala:13)
>>>>>>>>> [error] at TestApp.main(TestApp.scala)
>>>>>>>>>
>>>>>>>>> Looking at other bugs involving this kind of error message, it
>>>>>>>>> appears that unresolved is a type for when there's not enough
>>>>>>>>> layout information? In any case, here's the struct in question:
>>>>>>>>>
>>>>>>>>> struct wl_listener {
>>>>>>>>> struct wl_list link;
>>>>>>>>> wl_notify_func_t notify;
>>>>>>>>> };
>>>>>>>>>
>>>>>>>>> and the definition of the elements:
>>>>>>>>>
>>>>>>>>> typedef void (*wl_notify_func_t)(struct wl_listener *listener,
>>>>>>>>> void *data);
>>>>>>>>>
>>>>>>>>> struct wl_list {
>>>>>>>>> /** Previous list element */
>>>>>>>>> struct wl_list *prev;
>>>>>>>>> /** Next list element */
>>>>>>>>> struct wl_list *next;
>>>>>>>>> };
>>>>>>>>>
>>>>>>>>> I'm fairly certain the issue lies with the function pointer
>>>>>>>>> notify. When I looked at the decompiled source,
>>>>>>>>> wl_notify_func_t is defined as:
>>>>>>>>>
>>>>>>>>> @FunctionalInterface
>>>>>>>>> @NativeCallback("(u64:${wl_listener}u64:v)v")
>>>>>>>>> public interface FI5 {
>>>>>>>>> void fn(Pointer<wayland_server_core.wl_listener> var1,
>>>>>>>>> Pointer<?> var2);
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> which seems suspicious to me. var2 should be a Pointer<Void> I
>>>>>>>>> would think. It's a type I see elsewhere in the source for
>>>>>>>>> this file, so it seems suspect that var2 is a Pointer<?>.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Is this a bug? Am I just using jextract wrong?
>>>>>>>>>
>>>>>>>>> Thanks for your help,
>>>>>>>>>
>>>>>>>>> Mark Hammons
>>>>>>>>>
More information about the panama-dev
mailing list