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

Maurizio Cimadamore mcimadamore at openjdk.org
Thu Jan 25 14:48:13 UTC 2024


> 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:

  Address review comments

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

Changes:
  - all: https://git.openjdk.org/jextract/pull/194/files
  - new: https://git.openjdk.org/jextract/pull/194/files/a48fb46a..18f18f0e

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jextract&pr=194&range=02
 - incr: https://webrevs.openjdk.org/?repo=jextract&pr=194&range=01-02

  Stats: 3 lines in 2 files changed: 0 ins; 1 del; 2 mod
  Patch: https://git.openjdk.org/jextract/pull/194.diff
  Fetch: git fetch https://git.openjdk.org/jextract.git pull/194/head:pull/194

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


More information about the jextract-dev mailing list