A few considerations (mostly) on jextract

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri May 28 14:59:19 UTC 2021

> The other way is using jextract only for the "low level" stuff and
> adding comfort features
> with other tools. This doesn't work currently because the generated
> code exposes not
> enough information, I've mentioned the FunctionDescriptor already.
Yes, as I said, that one is going to be addressed.
> Another piece I miss is the type information of struct * parameter. It
> would be nice
> to have a way to get to the information, for example through an
> annotation on the parameter.
> An example would be:
> struct fuse *fuse_new(struct fuse_args *args, const struct fuse_operations *op,
>                size_t op_size, void *private_data);
> would result in:
> public static @Struct(name = "fuse") MemoryAddress fuse_new(
>      @Struct(name = "fuse_args", type = fuse_args.class) Addressable args,
>      @Struct(name = "fuse_operations", type = fuse_operations.class)
> Addressable op,
>      @Type(name = "size_t") long op_size,
>      @TypePtr(name = "void") Addressable private_data
> )
> (the return value has no type because "fuse" is a opaque type)
> with this, a code generator could generate a wrapper that adds
> typesafety, and anyone using
> the jextract generated code could also use the type names without
> having to always look into
> the source header file. This is especially useful for headers that
> don't expose parameter names.
> For example, the fuse read upcall
>      int (*read) (const char *, char *, size_t, off_t, struct fuse_file_info *);
> looks like this:
> int apply(MemoryAddress x0, MemoryAddress x1, long x2, long x3,
> MemoryAddress x4);

We used to have a @C type annotation to attach the C type name to the 
various entities generated by jextract. We abandoned that approach 
because type annotation are not uniformly supported by IDEs, we plan to 
come back and add javadoc comments which contain the full description of 
the C signature. So, I think that covers the "using jextract generated 
code" use case well (better than annotations).

But your idea of attaching more stringy type info in the function (for 
other tools) is good, I believe, and one which I believe we can get to 
by adding layout attributes to the function descriptor (instead of using 
Java annotations):

      C_POINTER.withAttribute(C_TYPE, "fuse*")
"fuse_args*").withAttribute(JAVA_TYPE, fuse_args.class)

That way the function descriptor will be fully inspectable - although 
not statically so - which might or might not be enough.

> I've now also found the time to port my tests to the new preview
> (after a lot of meetings about
> how much code needs a rewrite because of JEP411) and I love a lot of
> the changes.
> Two questions:
> What is now the recommended way to get a MemorySegment from
> MemoryAddress parameters of
> upcalls which lifetime is mostly restricted to the call after the
> removal of asSegmentRestricted(long)?
The method is still there - just the Restricted suffix has gone :-)
> Creating a new scope for each call sounds like a lot of overhead, so
> should I inject an outside
> managed scope into the implementations or use the scope of the Addr
> (which for the upcalls is
> the global scope) and if this is the way to go why is the asSegment
> without scope is removed?
I think the code should work as before. Just the method name changed.
> And the second question is there a reason why ResourceScope.Handle
> isn't AutoCloseable?
> The provided example would look a lot cleaner with it:
> try (ResourceScope.Handle segmentHandle = segment.scope().acquire()) {
>     <critical operation on segment>
> }

There are issues with using TWR in that way - javac will issue warnings 
as the "resource" is not used inside the TWR body, so we opted for this 
other variant.

In any case we have plans to switch to a simpler API for doing the same 
in 18 - I plan to share something on that topic shortly.


> Best regards,
> Markus Knetschke

More information about the panama-dev mailing list