<!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>