- 
    Type:
Bug
 - 
    Resolution: Fixed
 - 
    Priority:
  P3                     
     - 
    None
 - 
    Affects Version/s: None
 - 
    Component/s: 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.
```
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.
- duplicates
 - 
                    
CODETOOLS-7903301 VarargsInvoker should use variadic layouts
-         
     - Closed
 
 -