jextract cannot generate portable code (anymore)
some-java-user-99206970363698485155 at vodafonemail.de
some-java-user-99206970363698485155 at vodafonemail.de
Mon Dec 29 22:43:25 UTC 2025
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/20251229/f95fec1e/attachment-0001.htm>
More information about the jextract-dev
mailing list