jextract cannot generate portable code (anymore)

Jorn Vernee jorn.vernee at oracle.com
Mon Jan 5 12:01:25 UTC 2026


I had a look at what jextract does in the case of int64_t and size_t. In 
both cases these are typedefs for another builtin type. The former is a 
typedef for `long` and the latter a typedef for `unsigned long`. 
jextract uses the underlying type of the typedef to determine which 
layout to use, so we end up with C_LONG in both cases.

While these types are semantically portable, their typedefs may have a 
non-portable definition, which jextract expands - like a macro - during 
extraction. This problem is similar to this example:

#ifdef WIN32
typedef long long my_int;
#else
typedef long my_int;
#endif

This code is portable in the C sense, but jextract eagerly picks one of 
the two branches of this compiler switch when extracting.

This seems like a tricky issue to workaround. In this case I think we'd 
want the type to be 'resolved' at runtime rather than extraction time, 
but I don't think we can let jextract collect all the different 
definitions of `my_int`, and then pick the right one at runtime.

Jorn

On 29-12-2025 23:43, some-java-user-99206970363698485155 at vodafonemail.de 
wrote:
>
> Hello,
>
> the jextract guide [1] says that jextract can generate portable code 
> if the C code on which it is executed is portable.
> That seems to be no longer the case due to 
> https://bugs.openjdk.org/browse/CODETOOLS-7903923. There are two problems:
>
>   * On Windows it generates `OfInt C_LONG`, on non-Windows `OfLong
>     C_LONG`. But it looks up the layout dynamically using
>     `canonicalLayouts().get(...)`. Regardless of whether the generated
>     code actually uses `C_LONG` you will get a ClassCastException
>     during initialization when trying for example to use code
>     generated on Linux on a Windows machine: "ClassCastException:
>     class jdk.internal.foreign.layout.ValueLayouts$OfIntImpl cannot be
>     cast to class java.lang.foreign.ValueLayout$OfLong"
>   * The general approach of using `canonicalLayouts().get(...)` seems
>     to make this non-portable (even if the code declared `C_LONG` as
>     the general `ValueLayout` instead of the specific `OfInt` /
>     `OfLong`, avoiding the ClassCastException), because jextract
>     converts types such as `size_t` and `int64_t` to `C_LONG` on
>     Linux, even though these types are defined in `canonicalLayouts()`
>     as well.
>     Take for example
>     https://github.com/tree-sitter/java-tree-sitter/blob/master/scripts/jextract.sh
>     which runs jextract for
>     https://github.com/tree-sitter/tree-sitter/blob/master/lib/include/tree_sitter/api.h
>     Note that `api.h` is (if I see it correctly) portable. However for
>     `int64_t` (used by `ts_tree_cursor_goto_first_child_for_byte`)
>     jextract uses the non-portable `C_LONG` on Linux.
>     Another problem are `calloc` and `malloc` where jextract treats
>     `size_t` as non-portable `C_LONG` as well (I guess `size_t` would
>     be portable at least across 64 bit platforms, or would fail with a
>     ClassCastException if not, as desired).
>
> jextract version: Build 25-jextract+2-4 (2025/11/25)
>
> Note sure what a good solution to this is. Maybe an opt-out CLI flag 
> for the CODETOOLS-7903923 behavior, and an update to GUIDE.md?
> That would make code generated with jextract on Linux portable to 
> Windows again I think. Or are there cases where CODETOOLS-7903923 is 
> really needed (even for portable C libraries)?
> Or a way for jextract to not convert `int64_t` and `size_t` to C_LONG, 
> if that is possible?
>
> Or is there possibly also a problem with the 
> https://github.com/tree-sitter/java-tree-sitter setup mentioned above? 
> For example is there a way to make jextract refer to `int64_t` in the 
> generated code instead of `C_LONG`?
>
> Kind regards
>
>
> [1] 
> https://github.com/openjdk/jextract/blob/b96ad6618a70ddbdf6b67cc3eb8342efc39c0692/doc/GUIDE.md?plain=1#L103-L111
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jextract-dev/attachments/20260105/7c5fe0e6/attachment-0001.htm>


More information about the jextract-dev mailing list