<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, Dec 18, 2024 at 4:39 AM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com">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"><u></u>

  
  <div>
    <p>Hi David (and Yasumasa).</p>
    <p>What you are proposing makes some sense -- although I think I see
      different things being discussed which can be a little confusing.
      David seems to want to call FFM using a plain native method.
      Yasumasa showed an example of registering a "code segment" as an
      implementation of a native method, using the existing
      RegisterNatives functionality. The latter can be done (and has
      been done!) outside the JDK -- after all, RegisterNatives just
      wants a function pointer that points to a function whose calling
      convention respects the JNI one.</p>
    <p>But the former -- calling a native function using FFM through a
      native method -- is not as straightforward as it seems<span class="gmail_default" style="font-family:arial,helvetica,sans-serif">.</span></p></div></blockquote><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">I definitely understand what you're saying here. However, you misunderstand what I'm proposing. I'm not suggesting being able to call FFM directly using a plain native method. I'm suggesting being able to *bind* a native method to any arbitrary `MethodHandle` that matches its exact shape. Getting a matching `MethodHandle` from FFM would be the user's job, not the FFM API's job. Technically it wouldn't even be limited to FFM.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Say I'm writing a library, and that library uses the POSIX `read` syscall. The `read` syscall is pretty simple; it takes a file descriptor, a pointer, and a size, and returns a result and/or sets `errno`. The file descriptor is a (C) `int`, the pointer is, well, a pointer, and the size is specified as `size_t`.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">As you correctly surmised, what I want to be able to do is have a native method that I know is adequate for *all* platforms. For example: `static native long read(MemorySegment callState, int fd, MemorySegment ptr, long size)` - and call that from my main code for all POSIX OSes.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Unfortunately, `size_t` - and even `int` - might vary by size per platform. So, the *actual* layouts for the different platforms are of course all different. This means that the method handles for all the different platforms have different types and have to be adapted in many cases. But, it is much easier for a project to use a single set of static methods, and to keep a table of layouts and some back-pocket adapter methods, which are used one time during class init for example, than to manage a large number of mostly-redundant classes. A very clever user might even maintain a database of such things.</div></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><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>Popping back a level, I think you raise two important points:</p>
    <p>* it would be nice if downcall method handles could be called
      "more safely" w/o using method handles directly.<br>
      * it would be nice if warmup costs associated with downcall method
      handles could be improved/eliminated</p>
    <p>I think both are ideas worth exploring (and both are indeed on
      our radar). In the former case, I think a road that is not given
      enough attention is that it is quite easy, in fact, to create an
      instance of a functional interface using a downcall method handle,
      via the MethodHandleProxy::asInterfaceInstance method [2]. And the
      latter problem is bigger than downcall method handles -- a similar
      warmup problem also exists for FFM's memory access var handles, so
      I think a deeper exploration in coordination with Leyden would
      yield better outcomes for FFM as a whole (and, likely, also for
      _all_ Java code using method/var handles).</p></div></blockquote><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Sure, MethodHandleProxy does a similar job, though you have to define a whole interface per method shape, which seems unnecessarily heavy conceptually and computationally. I actually have an experimental project called `ffm-autolinker` [1] which lets you define a whole interface that gets implemented by a class which uses indy to dynamically link each implementation method on demand using FFM plus known runtime platform information, adapting the arguments and returns as needed. I think this is more ergonomic than `jextract` and lighter (in many ways) than MethodHandleProxy, though it is still a little immature.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">But it would be nice to take the idea a step farther and get rid of the interface altogether.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><div class="gmail_default"><br></div><div class="gmail_default">[1] <a href="https://github.com/dmlloyd/ffm-autolinker">https://github.com/dmlloyd/ffm-autolinker</a></div></div></div></div><div><br></div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr">- DML • he/him<br></div></div></div>