<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hello,</p>
<p>the jextract guide [1] says that jextract can generate portable
code if the C code on which it is executed is portable.<br>
That seems to be no longer the case due to
<a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/CODETOOLS-7903923">https://bugs.openjdk.org/browse/CODETOOLS-7903923</a>. There are two
problems:</p>
<ul>
<li>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"</li>
<li>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.<br>
Take for example
<a class="moz-txt-link-freetext" href="https://github.com/tree-sitter/java-tree-sitter/blob/master/scripts/jextract.sh">https://github.com/tree-sitter/java-tree-sitter/blob/master/scripts/jextract.sh</a>
which runs jextract for
<a class="moz-txt-link-freetext" href="https://github.com/tree-sitter/tree-sitter/blob/master/lib/include/tree_sitter/api.h">https://github.com/tree-sitter/tree-sitter/blob/master/lib/include/tree_sitter/api.h</a><br>
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.<br>
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).</li>
</ul>
<p>jextract version: Build 25-jextract+2-4 (2025/11/25)</p>
<p>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?<br>
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)?<br>
Or a way for jextract to not convert `int64_t` and `size_t` to
C_LONG, if that is possible? </p>
<p>Or is there possibly also a problem with the <a class="moz-txt-link-freetext" href="https://github.com/tree-sitter/java-tree-sitter">https://github.com/tree-sitter/java-tree-sitter</a>
setup mentioned above? For example is there a way to make jextract
refer to `int64_t` in the generated code instead of `C_LONG`?</p>
<p>Kind regards</p>
<p><br>
</p>
<p>[1]
<a class="moz-txt-link-freetext" href="https://github.com/openjdk/jextract/blob/b96ad6618a70ddbdf6b67cc3eb8342efc39c0692/doc/GUIDE.md?plain=1#L103-L111">https://github.com/openjdk/jextract/blob/b96ad6618a70ddbdf6b67cc3eb8342efc39c0692/doc/GUIDE.md?plain=1#L103-L111</a></p>
</body>
</html>