<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>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.<br>
<br>
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:<br>
<br>
<font face="monospace">#ifdef WIN32<br>
typedef long long my_int</font><font face="monospace">;<br>
#else<br>
typedef long </font><font face="monospace">my_int</font><font face="monospace"></font><font face="monospace">;<br>
#endif</font></p>
<p>This code is portable in the C sense, but jextract eagerly picks
one of the two branches of this compiler switch when extracting.</p>
<p>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.</p>
<p>Jorn</p>
<div class="moz-cite-prefix">On 29-12-2025 23:43,
<a class="moz-txt-link-abbreviated" href="mailto:some-java-user-99206970363698485155@vodafonemail.de">some-java-user-99206970363698485155@vodafonemail.de</a> wrote:<br>
</div>
<blockquote type="cite" cite="mid:7f755534-64eb-42f5-bd6e-b0c8371f992f@vodafonemail.de">
<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" moz-do-not-send="true">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" moz-do-not-send="true">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" moz-do-not-send="true">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" moz-do-not-send="true">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" moz-do-not-send="true">https://github.com/openjdk/jextract/blob/b96ad6618a70ddbdf6b67cc3eb8342efc39c0692/doc/GUIDE.md?plain=1#L103-L111</a></p>
</blockquote>
</body>
</html>