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

Maurizio Cimadamore mcimadamore at openjdk.org
Thu Jan 25 11:13:05 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);

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

Commit messages:
 - Initial push

Changes: https://git.openjdk.org/jextract/pull/194/files
 Webrev: https://webrevs.openjdk.org/?repo=jextract&pr=194&range=00
  Issue: https://bugs.openjdk.org/browse/CODETOOLS-7903642
  Stats: 67 lines in 4 files changed: 23 ins; 31 del; 13 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