<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>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.<br>
    </p>
    <p>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.</p>
    <p>Another option for you (if specialization is not possible) would
      be to just support VaList (which is similar to what Swift does
      [1]).<br>
    </p>
    <p>Maurizio<br>
      <br>
      [1] - <a class="moz-txt-link-freetext" href="https://developer.apple.com/documentation/swift/cvararg">https://developer.apple.com/documentation/swift/cvararg</a><br>
    </p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 24/10/2022 16:24, Mark Hammons
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CA+Qhaypk0tPoJjKbsvAMPbUp3K5T0p2ZMR=Phs3Bh3tLw09b_Q@mail.gmail.com">
      
      <div dir="ltr">
        <div>Hi Jorn, Maurizio, <br>
        </div>
        <div><br>
        </div>
        <div>When I make the change suggested by Jorn, the bindings work
          as expected. <br>
        </div>
        <div><br>
        </div>
        <div>Thanks,</div>
        <div>Mark<br>
        </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Mon, Oct 24, 2022 at 5:10
          PM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">maurizio.cimadamore@oracle.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
          0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div>
            <p>Do you get the error even if you add the asVariadic call,
              as noted by Jorn?</p>
            <p>Maurizio<br>
            </p>
            <div>On 24/10/2022 15:38, Mark Hammons wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="ltr">
                <div>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: <br>
                  ```</div>
                <div>
                  <div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Menlo,Monaco,"Courier New",monospace;font-weight:normal;font-size:12px;line-height:18px;white-space:pre-wrap"><div><span style="color:rgb(212,212,212)">      </span><span style="color:rgb(86,156,214)">val</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">format</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(78,201,176)">Ptr</span><span style="color:rgb(212,212,212)">.copy(</span><span style="color:rgb(206,145,120)">"%i hello: %s %i"</span><span style="color:rgb(212,212,212)">)</span></div><div><span style="color:rgb(212,212,212)">      </span><span style="color:rgb(86,156,214)">val</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">buffer</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(78,201,176)">Ptr</span><span style="color:rgb(212,212,212)">.blankArray[</span><span style="color:rgb(78,201,176)">Byte</span><span style="color:rgb(212,212,212)">](</span><span style="color:rgb(181,206,168)">256</span><span style="color:rgb(212,212,212)">)</span></div>
<div><span style="color:rgb(212,212,212)">      </span></div><div><span style="color:rgb(212,212,212)">      assertEquals(format.copyIntoString(</span><span style="color:rgb(181,206,168)">200</span><span style="color:rgb(212,212,212)">), </span><span style="color:rgb(206,145,120)">"%i hello: %s %i"</span><span style="color:rgb(212,212,212)">)</span></div><div><span style="color:rgb(212,212,212)">      </span><span style="color:rgb(78,201,176)">Cstd</span><span style="color:rgb(212,212,212)">.sprintf(buffer, format, </span><span style="color:rgb(181,206,168)">1</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(78,201,176)">Ptr</span><span style="color:rgb(212,212,212)">.copy(</span><span style="color:rgb(206,145,120)">"hello"</span><span style="color:rgb(212,212,212)">), </span><span style="color:rgb(181,206,168)">2</span><span style="color:rgb(212,212,212)">)</span></div><div><span style="color:rgb(212,212,212)">      assertEquals(buffer.copyIntoString(</span><span style="color:rgb(181,206,168)">256</span><span style="color:rgb(212,212,212)">), </span><span style="color:rgb(206,145,120)">"1 hello: hello 2"</span><span style="color:rgb(212,212,212)">)</span></div><div><span style="color:rgb(212,212,212)">```
</span></div></div>
                </div>
                <div><br>
                </div>
                <div>With the fixed code above, I get the following
                  result from add_var: <br>
                </div>
                <div><br>
                </div>
                <div>-1884714972</div>
                <div><br>
                </div>
                <div>~Mark<br>
                </div>
              </div>
              <br>
              <div class="gmail_quote">
                <div dir="ltr" class="gmail_attr">On Mon, Oct 24, 2022
                  at 3:23 PM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">maurizio.cimadamore@oracle.com</a>>
                  wrote:<br>
                </div>
                <blockquote class="gmail_quote" style="margin:0px 0px
                  0px 0.8ex;border-left:1px solid
                  rgb(204,204,204);padding-left:1ex">
                  <div>
                    <p>Hi Mark,<br>
                      interesting. On M1 we have currently few issues -
                      see also this:</p>
                    <p><a href="https://bugs.openjdk.org/browse/JDK-8275584" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://bugs.openjdk.org/browse/JDK-8275584</a></p>
                    <p>Stack spilling doesn't always occur correctly,
                      however I note that your example should not spill
                      on the stack, so it should be immune.</p>
                    <p>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?</p>
                    <p>I'd rewrite it as:</p>
                    <p>```<br>
                          for(int i = 0; i < n; i++) { <br>
                              int i = va_arg(ptr, int);<br>
                              printf("lala %d", i);<br>
                              Sum += i;<br>
                          }<br>
                      ```</p>
                    <p>And test again.<br>
                    </p>
                    <p>Maurizio<br>
                    </p>
                    <div>On 24/10/2022 13:40, Mark Hammons wrote:<br>
                    </div>
                    <blockquote type="cite">
                      <div dir="ltr">
                        <div>Hi all,  <br>
                        </div>
                        <div><br>
                        </div>
                        <div>I was testing panama on java 19 with my
                          work issued macbook pro, and my varargs method
                          bindings were returning invalid data.</div>
                        <div><br>
                        </div>
                        <div>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: <br>
                        </div>
                        <div><br>
                        </div>
                        <div>
                          <div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Menlo,Monaco,"Courier New",monospace;font-weight:normal;font-size:12px;line-height:18px;white-space:pre-wrap"><div><span style="color:rgb(212,212,212)">  test(</span><span style="color:rgb(206,145,120)">"manual varargs"</span><span style="color:rgb(212,212,212)">) {</span></div><div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(86,156,214)">val</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">linker</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(78,201,176)">Linker</span><span style="color:rgb(212,212,212)">.nativeLinker().nn</span></div><div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(86,156,214)">val</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">sl</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(78,201,176)">SymbolLookup</span><span style="color:rgb(212,212,212)">.loaderLookup().nn</span></div>
<div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(86,156,214)">val</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">mh</span><span style="color:rgb(212,212,212)"> = linker</span></div><div><span style="color:rgb(212,212,212)">      .downcallHandle(</span></div><div><span style="color:rgb(212,212,212)">        sl.lookup(</span><span style="color:rgb(206,145,120)">"add_var"</span><span style="color:rgb(212,212,212)">).nn.orElseThrow(),</span></div><div><span style="color:rgb(212,212,212)">        </span><span style="color:rgb(78,201,176)">FunctionDescriptor</span><span style="color:rgb(212,212,212)">.of(</span><span style="color:rgb(78,201,176)">JAVA_INT</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(78,201,176)">JAVA_INT</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(78,201,176)">JAVA_INT</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(78,201,176)">JAVA_INT</span><span style="color:rgb(212,212,212)">)</span></div><div><span style="color:rgb(212,212,212)">      )</span></div><div><span style="color:rgb(212,212,212)">      .nn;</span></div>
<div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(86,156,214)">val</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">res</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(78,201,176)">MethodHandleFacade</span><span style="color:rgb(212,212,212)">.callVariadic(mh, </span><span style="color:rgb(181,206,168)">2</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(181,206,168)">1</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(181,206,168)">2</span><span style="color:rgb(212,212,212)">).</span><span style="color:rgb(220,220,170)">asInstanceOf</span><span style="color:rgb(212,212,212)">[</span><span style="color:rgb(78,201,176)">Int</span><span style="color:rgb(212,212,212)">]</span></div><div><span style="color:rgb(212,212,212)">    assertEquals(res, </span><span style="color:rgb(181,206,168)">3</span><span style="color:rgb(212,212,212)">)</span></div><div><span style="color:rgb(212,212,212)">  }</span></div>
<div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Menlo,Monaco,"Courier New",monospace;font-weight:normal;font-size:12px;line-height:18px;white-space:pre-wrap"><div><span style="color:rgb(197,134,192)">#include</span><span style="color:rgb(86,156,214)"> </span><span style="color:rgb(206,145,120)"><stdarg.h></span></div><div><span style="color:rgb(197,134,192)">#include</span><span style="color:rgb(86,156,214)"> </span><span style="color:rgb(206,145,120)"><stdio.h></span></div>
<div><span style="color:rgb(86,156,214)">int</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(220,220,170)">add_var</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(86,156,214)">int</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">n</span><span style="color:rgb(212,212,212)">, ...) {</span></div><div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(86,156,214)">int</span><span style="color:rgb(212,212,212)"> Sum = </span><span style="color:rgb(181,206,168)">0</span><span style="color:rgb(212,212,212)">;</span></div>
<div><span style="color:rgb(212,212,212)">    va_list ptr;</span></div>
<div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(220,220,170)">va_start</span><span style="color:rgb(212,212,212)">(ptr, n);</span></div>
<div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(197,134,192)">for</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(86,156,214)">int</span><span style="color:rgb(212,212,212)"> i = </span><span style="color:rgb(181,206,168)">0</span><span style="color:rgb(212,212,212)">; i < n; i++) { </span></div><div><span style="color:rgb(212,212,212)">        </span><span style="color:rgb(86,156,214)">int</span><span style="color:rgb(212,212,212)"> i = </span><span style="color:rgb(220,220,170)">va_arg</span><span style="color:rgb(212,212,212)">(ptr, </span><span style="color:rgb(86,156,214)">int</span><span style="color:rgb(212,212,212)">);</span></div><div><span style="color:rgb(212,212,212)">        </span><span style="color:rgb(220,220,170)">printf</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(206,145,120)">"lala </span><span style="color:rgb(156,220,254)">%d</span><span style="color:rgb(206,145,120)">"</span><span style="color:rgb(212,212,212)">, i);</span></div><div><span style="color:rgb(212,212,212)">        Sum += </span><span style="color:rgb(220,220,170)">va_arg</span><span style="color:rgb(212,212,212)">(ptr, </span><span style="color:rgb(86,156,214)">int</span><span style="color:rgb(212,212,212)">);</span></div><div><span style="color:rgb(212,212,212)">    }</span></div></div><div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Menlo,Monaco,"Courier New",monospace;font-weight:normal;font-size:12px;line-height:18px;white-space:pre-wrap">
<div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(220,220,170)">va_end</span><span style="color:rgb(212,212,212)">(ptr);</span></div>
<div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(197,134,192)">return</span><span style="color:rgb(212,212,212)"> Sum;</span></div>}

<span style="color:rgb(0,0,0)"><span style="background-color:rgb(255,255,255)">The output of the test code is consistent with my autogenerated code, </span></span></div><div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Menlo,Monaco,"Courier New",monospace;font-weight:normal;font-size:12px;line-height:18px;white-space:pre-wrap"><span style="color:rgb(0,0,0)"><span style="background-color:rgb(255,255,255)">the Ints are not reaching the add_var function in a proper state, and therefore </span></span></div><div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Menlo,Monaco,"Courier New",monospace;font-weight:normal;font-size:12px;line-height:18px;white-space:pre-wrap"><span style="color:rgb(0,0,0)"><span style="background-color:rgb(255,255,255)">add_var is returning something like 840370212 instead of 3. 
</span></span></div></div>
                        </div>
                      </div>
                    </blockquote>
                  </div>
                </blockquote>
              </div>
            </blockquote>
          </div>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>