Uploaded image for project: 'Code Tools'
  1. Code Tools
  2. CODETOOLS-7903585

Revisit variadic support

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • None
    • None
    • tools

      Consider the following function:

      ```
      int printf(const char *format, ...);
      ```

      For this function, jextract generates this:

      ```
      public static int printf(MemorySegment format, Object... x1) { ... }
      ```

      That is a method with a varargs parameter list. Internally, this is supported using RuntimeHelper's VarargsInvoker machinery:

      https://github.com/openjdk/jextract/blob/master/src/main/resources/org/openjdk/jextract/impl/resources/RuntimeHelper.java.template#L101

      This class is used to create a method handle which is re-linked on each invocation, based on the types of the actual arguments provided by the caller.

      This approach has two issues:
      * performance-wise, it is not optimal: if the same call shape is invoked multiple times, there will still be an expensive re-linking process;
      * there is no way for the varargs invoker machinery to fully disambiguate between structs and pointers. And, even if there was a way, it would still be not possible, given a struct instance, to infer its layout. For this reason, varargs invoker only really can pass segments by reference.

      A possible improvement on this strategy would be to emit the following:

      ```
      interface printfInvoker {
              void apply(MemorySegment format, Object... args);
          }

          static printfInvoker printf(MemoryLayout... variadicLayouts) { ... } // new primitive

          static void printf(MemorySegment segment, Object... args) { ... }
      ```

      That is, for each variadic method, jextract could generate an "invoker" interface, plus a factory that takes a bunch of variadic layouts and creates an invoker for that specialized shape.

      Then, we could also generate a friendly wrapper which still infers layouts from variadic arguments (using same limited approach as today), which is then used to create a new invoker, and call it on the spot.

            jvernee Jorn Vernee
            mcimadamore Maurizio Cimadamore
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: