Integrated: 7903642: Code generation for variadic function emits redundant casts

Maurizio Cimadamore mcimadamore at openjdk.org
Thu Jan 25 14:55:59 UTC 2024


On Thu, 25 Jan 2024 11:08:26 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);

This pull request has now been integrated.

Changeset: 7497eee7
Author:    Maurizio Cimadamore <mcimadamore at openjdk.org>
URL:       https://git.openjdk.org/jextract/commit/7497eee7b761fb475ee1401b12dec8899745962c
Stats:     76 lines in 4 files changed: 23 ins; 33 del; 20 mod

7903642: Code generation for variadic function emits redundant casts

Reviewed-by: jvernee

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

PR: https://git.openjdk.org/jextract/pull/194


More information about the jextract-dev mailing list