Varargs bindings do not work in java 19 on the macbook pro M1 MAX
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Oct 24 16:23:21 UTC 2022
Thanks for confirming. Then the API works as expected. This is described
in the Linker javadoc - e.g. support for variadic calls require the
method handle to be specialized manually (by creating a function
descriptor featuring the desired arity). The ABI needs to know specific
information re. variadic calls, as in some platforms variadic arguments
are dealt with specially.
Jextract works around this problem by using a method handle which
accepts an Object... and then specializes a new downcall method handle
on each new call. This can probably be optimized by using invokedynamic
+ mutable call site, so that an impl can reuse an existing specialized
variadic downcall method handle.
Another option for you (if specialization is not possible) would be to
just support VaList (which is similar to what Swift does [1]).
Maurizio
[1] - https://developer.apple.com/documentation/swift/cvararg
On 24/10/2022 16:24, Mark Hammons wrote:
> Hi Jorn, Maurizio,
>
> When I make the change suggested by Jorn, the bindings work as expected.
>
> Thanks,
> Mark
>
> On Mon, Oct 24, 2022 at 5:10 PM Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com> wrote:
>
> Do you get the error even if you add the asVariadic call, as noted
> by Jorn?
>
> Maurizio
>
> On 24/10/2022 15:38, Mark Hammons wrote:
>> Sorry, yes there's an error there. However, this was not the
>> first place I noticed the error. Rather, I noticed that my
>> binding to sprintf was returning halfway malformed strings like
>> `1810529328 hello: �_�����{���\���^��@xA�!$@�!@����@Q@ 922798592`
>> when the following test code was run:
>> ```
>> valformat= Ptr.copy("%i hello: %s %i")
>> valbuffer= Ptr.blankArray[Byte](256)
>> assertEquals(format.copyIntoString(200), "%i hello: %s %i")
>> Cstd.sprintf(buffer, format, 1, Ptr.copy("hello"), 2)
>> assertEquals(buffer.copyIntoString(256), "1 hello: hello 2")
>> ```
>>
>> With the fixed code above, I get the following result from add_var:
>>
>> -1884714972
>>
>> ~Mark
>>
>> On Mon, Oct 24, 2022 at 3:23 PM Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com> wrote:
>>
>> Hi Mark,
>> interesting. On M1 we have currently few issues - see also this:
>>
>> https://bugs.openjdk.org/browse/JDK-8275584
>>
>> Stack spilling doesn't always occur correctly, however I note
>> that your example should not spill on the stack, so it should
>> be immune.
>>
>> Is your C code correct? I see you do _two_ va_arg per loop
>> iteration, which surely would leave you accessing invalid
>> data. E.g. in this case n = 2, so the loop would do two
>> iterations, and va_arg will be called _four_ times? Am I
>> missing something?
>>
>> I'd rewrite it as:
>>
>> ```
>> for(int i = 0; i < n; i++) {
>> int i = va_arg(ptr, int);
>> printf("lala %d", i);
>> Sum += i;
>> }
>> ```
>>
>> And test again.
>>
>> Maurizio
>>
>> On 24/10/2022 13:40, Mark Hammons wrote:
>>> Hi all,
>>>
>>> I was testing panama on java 19 with my work issued macbook
>>> pro, and my varargs method bindings were returning invalid data.
>>>
>>> I thought that maybe it was a failure in my own code, but I
>>> couldn't work around it so I created a test instance using
>>> manually written code:
>>>
>>> test("manual varargs") {
>>> vallinker= Linker.nativeLinker().nn
>>> valsl= SymbolLookup.loaderLookup().nn
>>> valmh= linker
>>> .downcallHandle(
>>> sl.lookup("add_var").nn.orElseThrow(),
>>> FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT)
>>> )
>>> .nn;
>>> valres= MethodHandleFacade.callVariadic(mh, 2, 1,
>>> 2).asInstanceOf[Int]
>>> assertEquals(res, 3)
>>> }
>>> #include<stdarg.h>
>>> #include<stdio.h>
>>> intadd_var(intn, ...) {
>>> intSum = 0;
>>> va_list ptr;
>>> va_start(ptr, n);
>>> for(inti = 0; i < n; i++) {
>>> inti = va_arg(ptr, int);
>>> printf("lala %d", i);
>>> Sum += va_arg(ptr, int);
>>> }
>>> va_end(ptr);
>>> returnSum;
>>> } The output of the test code is consistent with my
>>> autogenerated code,
>>> the Ints are not reaching the add_var function in a proper
>>> state, and therefore
>>> add_var is returning something like 840370212 instead of 3.
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20221024/235658d2/attachment-0001.htm>
More information about the panama-dev
mailing list