RFR: 7903642: Code generation for variadic function emits redundant casts [v2]

Maurizio Cimadamore mcimadamore at openjdk.org
Thu Jan 25 11:18:06 UTC 2024


On Thu, 25 Jan 2024 11:15:39 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> This PR slightly changes the code generation scheme for variadic calls.
>> 
>> Given a variadic function like this:
>> 
>> 
>> int foo(int count, ...);
>> 
>> 
>> We now generate the following:
>> 
>> 
>>     /**
>>      * Variadic invoker interface for:
>>      * {@snippet lang=c :
>>      * int foo(int count, ...)
>>      * }
>>      */
>>     public interface foo {
>>         int apply(int count, Object... x1);
>> 
>>         /**
>>          * Invoke the variadic function with the given parameters. Layouts for variadic arguments are inferred.
>>          */
>>         static int invoke(int count, Object... x1) {
>>             MemoryLayout[] inferredLayouts$ = foo_h.inferVariadicLayouts(x1);
>>             return foo(inferredLayouts$).apply(count, x1);
>>         }
>>     }
>> 
>>     /**
>>      * {@snippet lang=c :
>>      * int foo(int count, ...)
>>      * }
>>      */
>>     public static foo foo(MemoryLayout... layouts) {
>>         FunctionDescriptor baseDesc$ = FunctionDescriptor.of(
>>                 foo_h.C_INT,
>>                 foo_h.C_INT
>>             );
>>         var mh$ = foo_h.downcallHandleVariadic("foo", baseDesc$, layouts);
>>         return (int count, Object... x1) -> {
>>             try {
>>                 if (TRACE_DOWNCALLS) {
>>                     traceDowncall("foo", count, x1);
>>                 }
>>                 return (int) mh$.invokeExact(count, x1);
>>             } catch(IllegalArgumentException ex$)  {
>>                 throw ex$; // rethrow IAE from passing wrong number/type of args
>>             } catch (Throwable ex$) {
>>                throw new AssertionError("should not reach here", ex$);
>>             }
>>         };
>>     }
>> 
>> 
>> Main changes:
>> 
>> * the invoker interface now has the same name as the variadic function (as opposed to `foo$invoker`)
>> * the header class only has one static method, with same name as variadic function (`foo`); this is a factory for the invoker class with same name
>> * the handy Java varargs method that takes objects and infers layout is now moved inside the invoker class (see static `invoke` method)
>> * the main invoker method name has been changed to `apply`
>> * a bug has been fixed where a redundant case was emitted in the static `invoke` method
>> 
>> Example of invoker form (see changes to `TestPrintf`):
>> 
>> 
>> my_sprintf(layouts).apply(s, arena.allocateFrom(fmt), args.length, args);
>> 
>> 
>> Example of static invoke:
>> 
>> 
>> my_sprintf.invoke(s, arena.allocateFrom(fmt), args.length, args);
>
> Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Cleanup code

test/testng/org/openjdk/jextract/test/toolprovider/JextractToolProviderTest.java line 120:

> 118:     }
> 119: 
> 120:     private static void checkHeaderMembers(Class<?> header) {

Since this code was duplicated across 3 test methods, I've pulled it out here

-------------

PR Review Comment: https://git.openjdk.org/jextract/pull/194#discussion_r1466217670


More information about the jextract-dev mailing list