From mcimadamore at openjdk.org Tue Jul 1 08:59:51 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 1 Jul 2025 08:59:51 GMT Subject: RFR: 7904049: Add LLM inference example to jextract samples [v2] In-Reply-To: <5aA0hlx6BQWkGBdRtOMhzOFHDXoCuDD0nw7-0RkYzTo=.eecfce0a-f816-4a53-aa27-e4b0db01bb93@github.com> References: <5aA0hlx6BQWkGBdRtOMhzOFHDXoCuDD0nw7-0RkYzTo=.eecfce0a-f816-4a53-aa27-e4b0db01bb93@github.com> Message-ID: On Mon, 30 Jun 2025 10:16:35 GMT, Nizar Benalla wrote: >> Please review this PR to add an LLM inference example to the jextract samples. >> >> Thanks! > > Nizar Benalla has updated the pull request incrementally with one additional commit since the last revision: > > use `MemorySegment::reinterpret` to clean up objects > modify compile script slightly Looks great! ------------- Marked as reviewed by mcimadamore (Reviewer). PR Review: https://git.openjdk.org/jextract/pull/285#pullrequestreview-2974326850 From nbenalla at openjdk.org Tue Jul 1 11:15:01 2025 From: nbenalla at openjdk.org (Nizar Benalla) Date: Tue, 1 Jul 2025 11:15:01 GMT Subject: Withdrawn: 7904051: Jextract should generate symbols in the same class consistently In-Reply-To: References: Message-ID: <3zy9J-1coG5ZueGKkEuceNq_xhtNv3z_uZbFgohthJM=.19fb7c40-15dd-4896-b1b7-82f986fb6869@github.com> On Mon, 30 Jun 2025 16:18:24 GMT, Nizar Benalla wrote: > Very simple change, done in a way to not break existing code as a simple sort would've changed the names of variables in the generated code. > There was a test case that had to be updated. This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jextract/pull/286 From nbenalla at openjdk.org Wed Jul 2 11:34:51 2025 From: nbenalla at openjdk.org (Nizar Benalla) Date: Wed, 2 Jul 2025 11:34:51 GMT Subject: RFR: 7904049: Add LLM inference example to jextract samples [v2] In-Reply-To: <5aA0hlx6BQWkGBdRtOMhzOFHDXoCuDD0nw7-0RkYzTo=.eecfce0a-f816-4a53-aa27-e4b0db01bb93@github.com> References: <5aA0hlx6BQWkGBdRtOMhzOFHDXoCuDD0nw7-0RkYzTo=.eecfce0a-f816-4a53-aa27-e4b0db01bb93@github.com> Message-ID: <51UZY2N1B9azLXSirBEhixGzUkF5fJ6K1joQOTq6jsw=.ed141d8f-c8c3-4236-b623-2e73471cada7@github.com> On Mon, 30 Jun 2025 10:16:35 GMT, Nizar Benalla wrote: >> Please review this PR to add an LLM inference example to the jextract samples. >> >> Thanks! > > Nizar Benalla has updated the pull request incrementally with one additional commit since the last revision: > > use `MemorySegment::reinterpret` to clean up objects > modify compile script slightly Thanks for reviewing ------------- PR Comment: https://git.openjdk.org/jextract/pull/285#issuecomment-3027523410 From duke at openjdk.org Wed Jul 2 11:34:51 2025 From: duke at openjdk.org (duke) Date: Wed, 2 Jul 2025 11:34:51 GMT Subject: RFR: 7904049: Add LLM inference example to jextract samples [v2] In-Reply-To: <5aA0hlx6BQWkGBdRtOMhzOFHDXoCuDD0nw7-0RkYzTo=.eecfce0a-f816-4a53-aa27-e4b0db01bb93@github.com> References: <5aA0hlx6BQWkGBdRtOMhzOFHDXoCuDD0nw7-0RkYzTo=.eecfce0a-f816-4a53-aa27-e4b0db01bb93@github.com> Message-ID: On Mon, 30 Jun 2025 10:16:35 GMT, Nizar Benalla wrote: >> Please review this PR to add an LLM inference example to the jextract samples. >> >> Thanks! > > Nizar Benalla has updated the pull request incrementally with one additional commit since the last revision: > > use `MemorySegment::reinterpret` to clean up objects > modify compile script slightly @nizarbenalla Your change (at version b023e0a0e6eb2d1f52d2646f8d0cb6493bc73d3b) is now ready to be sponsored by a Committer. ------------- PR Comment: https://git.openjdk.org/jextract/pull/285#issuecomment-3027525932 From nbenalla at openjdk.org Wed Jul 2 13:34:04 2025 From: nbenalla at openjdk.org (Nizar Benalla) Date: Wed, 2 Jul 2025 13:34:04 GMT Subject: Integrated: 7904049: Add LLM inference example to jextract samples In-Reply-To: References: Message-ID: On Wed, 25 Jun 2025 15:58:28 GMT, Nizar Benalla wrote: > Please review this PR to add an LLM inference example to the jextract samples. > > Thanks! This pull request has now been integrated. Changeset: 267a0abe Author: Nizar Benalla Committer: Maurizio Cimadamore URL: https://git.openjdk.org/jextract/commit/267a0abe441ba9bf2da3cfebd3dfd05c26bf464c Stats: 188 lines in 4 files changed: 188 ins; 0 del; 0 mod 7904049: Add LLM inference example to jextract samples Reviewed-by: mcimadamore ------------- PR: https://git.openjdk.org/jextract/pull/285 From duke at openjdk.org Wed Jul 2 21:18:31 2025 From: duke at openjdk.org (Clayton Walker) Date: Wed, 2 Jul 2025 21:18:31 GMT Subject: RFR: Gradle cleanup Message-ID: <2PIJo_9p4vA97BdA39UARTeRy2F_-5GZSH22o2cV_kM=.e89c04f2-30c8-487f-8ccb-a4732d49972c@github.com> I've been doing some development, and came across a few warnings during build. These are, [Project::task](https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html#task(java.lang.String)) is now deprecated, avoiding Project::mkdir, project::delete and Project::getProjectDir as they cannot work under configuration-cache. ------------- Commit messages: - Fix running with configuration-cache enabled - Fix deprecated mkdir call - Fix jar inputs - Remove use of deprecated task creation method Changes: https://git.openjdk.org/jextract/pull/283/files Webrev: https://webrevs.openjdk.org/?repo=jextract&pr=283&range=00 Stats: 20 lines in 1 file changed: 5 ins; 0 del; 15 mod Patch: https://git.openjdk.org/jextract/pull/283.diff Fetch: git fetch https://git.openjdk.org/jextract.git pull/283/head:pull/283 PR: https://git.openjdk.org/jextract/pull/283 From duke at openjdk.org Wed Jul 2 21:30:26 2025 From: duke at openjdk.org (Vivek Narang) Date: Wed, 2 Jul 2025 21:30:26 GMT Subject: RFR: Generate Java enums Message-ID: We are using jextract in our [cuVS Java](https://github.com/rapidsai/cuvs/tree/branch-25.08/java) project. As of now, jextract generates individual getter functions for the C enums. This results in code where it is difficult to disambiguate which getter functions are logically grouped together for a particular Enum. Additionally, given the lack of this capability, we also have to manually create and maintain Java enums for each enum in the C layer. In this PR, I wish to introduce an option to additionally generate Java enums by passing an optional flag `--generate-java-enums`. In case a Java user wishes to use bitwise operations on the enums, they can use the enum's `.ordinal()` method for this. The original static getter methods will still be generated as before. Example C enum: enum SIZE { S, M, L }; Produces the following with jextract: private static final int S = (int)0L; public static int S() { return S; } private static final int M = (int)1L; public static int M() { return M; } private static final int L = (int)2L; public static int L() { return L; } With this feature enabled using the `--generate-java-enums` flag, the following enum is generated (in addition to the above): public enum Size { S(0), M(1), L(2); private final int value; private Size(int value) {; this.value = value; } public int getValue() { return this.value; } } This PR is created against the `jdk22` branch. I will rebase it to `master` branch if needed. ------------- Commit messages: - Remove extra space in messages.properties - Generate enums in header file instead - Initial work Changes: https://git.openjdk.org/jextract/pull/284/files Webrev: https://webrevs.openjdk.org/?repo=jextract&pr=284&range=00 Stats: 184 lines in 12 files changed: 168 ins; 0 del; 16 mod Patch: https://git.openjdk.org/jextract/pull/284.diff Fetch: git fetch https://git.openjdk.org/jextract.git pull/284/head:pull/284 PR: https://git.openjdk.org/jextract/pull/284 From duke at openjdk.org Wed Jul 2 22:13:50 2025 From: duke at openjdk.org (Clayton Walker) Date: Wed, 2 Jul 2025 22:13:50 GMT Subject: RFR: Gradle cleanup In-Reply-To: <2PIJo_9p4vA97BdA39UARTeRy2F_-5GZSH22o2cV_kM=.e89c04f2-30c8-487f-8ccb-a4732d49972c@github.com> References: <2PIJo_9p4vA97BdA39UARTeRy2F_-5GZSH22o2cV_kM=.e89c04f2-30c8-487f-8ccb-a4732d49972c@github.com> Message-ID: On Mon, 16 Jun 2025 22:15:12 GMT, Clayton Walker wrote: > I've been doing some development, and came across a few warnings during build. > > These are, [Project::task](https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html#task(java.lang.String)) is now deprecated, avoiding Project::mkdir, project::delete and Project::getProjectDir as they cannot work under configuration-cache. As a follow-up I'd like to see all of the explicit `dependsOn` get removed in favor of implicit dependencies based on manually specified task inputs and outputs. https://docs.gradle.org/9.0.0-rc-1/userguide/best_practices_tasks.html#avoid_depends_on ------------- PR Comment: https://git.openjdk.org/jextract/pull/283#issuecomment-3029455960 From liach at openjdk.org Wed Jul 2 23:31:52 2025 From: liach at openjdk.org (Chen Liang) Date: Wed, 2 Jul 2025 23:31:52 GMT Subject: RFR: Gradle cleanup In-Reply-To: <2PIJo_9p4vA97BdA39UARTeRy2F_-5GZSH22o2cV_kM=.e89c04f2-30c8-487f-8ccb-a4732d49972c@github.com> References: <2PIJo_9p4vA97BdA39UARTeRy2F_-5GZSH22o2cV_kM=.e89c04f2-30c8-487f-8ccb-a4732d49972c@github.com> Message-ID: On Mon, 16 Jun 2025 22:15:12 GMT, Clayton Walker wrote: > I've been doing some development, and came across a few warnings during build. > > These are, [Project::task](https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html#task(java.lang.String)) is now deprecated, avoiding Project::mkdir, project::delete and Project::getProjectDir as they cannot work under configuration-cache. build.gradle line 101: > 99: > 100: // if these inputs or outputs change, gradle will rerun the task > 101: inputs.file(tasks.named('jar', Jar).flatMap { it.archiveFile}) Suggestion: inputs.file(tasks.named('jar', Jar).flatMap { it.archiveFile }) ------------- PR Review Comment: https://git.openjdk.org/jextract/pull/283#discussion_r2181147694 From duke at openjdk.org Thu Jul 3 05:37:42 2025 From: duke at openjdk.org (Clayton Walker) Date: Thu, 3 Jul 2025 05:37:42 GMT Subject: RFR: Gradle cleanup [v2] In-Reply-To: <2PIJo_9p4vA97BdA39UARTeRy2F_-5GZSH22o2cV_kM=.e89c04f2-30c8-487f-8ccb-a4732d49972c@github.com> References: <2PIJo_9p4vA97BdA39UARTeRy2F_-5GZSH22o2cV_kM=.e89c04f2-30c8-487f-8ccb-a4732d49972c@github.com> Message-ID: > I've been doing some development, and came across a few warnings during build. > > These are, [Project::task](https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html#task(java.lang.String)) is now deprecated, avoiding Project::mkdir, project::delete and Project::getProjectDir as they cannot work under configuration-cache. Clayton Walker has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: Fix running with configuration-cache enabled ------------- Changes: - all: https://git.openjdk.org/jextract/pull/283/files - new: https://git.openjdk.org/jextract/pull/283/files/d576694e..c79d28e5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jextract&pr=283&range=01 - incr: https://webrevs.openjdk.org/?repo=jextract&pr=283&range=00-01 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jextract/pull/283.diff Fetch: git fetch https://git.openjdk.org/jextract.git pull/283/head:pull/283 PR: https://git.openjdk.org/jextract/pull/283 From duke at openjdk.org Thu Jul 3 05:37:43 2025 From: duke at openjdk.org (Clayton Walker) Date: Thu, 3 Jul 2025 05:37:43 GMT Subject: RFR: Gradle cleanup [v2] In-Reply-To: References: <2PIJo_9p4vA97BdA39UARTeRy2F_-5GZSH22o2cV_kM=.e89c04f2-30c8-487f-8ccb-a4732d49972c@github.com> Message-ID: On Wed, 2 Jul 2025 23:29:38 GMT, Chen Liang wrote: >> Clayton Walker has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: >> >> Fix running with configuration-cache enabled > > build.gradle line 101: > >> 99: >> 100: // if these inputs or outputs change, gradle will rerun the task >> 101: inputs.file(tasks.named('jar', Jar).flatMap { it.archiveFile}) > > Suggestion: > > inputs.file(tasks.named('jar', Jar).flatMap { it.archiveFile }) Fixed! ------------- PR Review Comment: https://git.openjdk.org/jextract/pull/283#discussion_r2181804554 From mcimadamore at openjdk.org Thu Jul 3 09:40:55 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 3 Jul 2025 09:40:55 GMT Subject: RFR: Generate Java enums In-Reply-To: References: Message-ID: <6l9HLjo-lG7jlTreLx9ML3vYb-VFw1TIk0Wi7hj2tjQ=.7ca76e76-17aa-40c0-b8ae-89ec11097a22@github.com> On Fri, 20 Jun 2025 17:09:19 GMT, Vivek Narang wrote: > We are using jextract in our [cuVS Java](https://github.com/rapidsai/cuvs/tree/branch-25.08/java) project. As of now, jextract generates individual getter functions for the C enums. This results in code where it is difficult to disambiguate which getter functions are logically grouped together for a particular Enum. Additionally, given the lack of this capability, we also have to manually create and maintain Java enums for each enum in the C layer. > > In this PR, I wish to introduce an option to additionally generate Java enums by passing an optional flag `--generate-java-enums`. In case a Java user wishes to use bitwise operations on the enums, they can use the enum's `.ordinal()` method for this. The original static getter methods will still be generated as before. > > Example C enum: > > enum SIZE { > S, > M, > L > }; > > Produces the following with jextract: > > private static final int S = (int)0L; > public static int S() { > return S; > } > > private static final int M = (int)1L; > public static int M() { > return M; > } > > private static final int L = (int)2L; > public static int L() { > return L; > } > > With this feature enabled using the `--generate-java-enums` flag, the following enum is generated (in addition to the above): > > public enum Size { > S(0), > M(1), > L(2); > > private final int value; > > private Size(int value) {; > this.value = value; > } > > public int getValue() { > return this.value; > } > } > > This PR is created against the `jdk22` branch. I will rebase it to `master` branch if needed. In general we have not used the translation to Java enum because it's not 100% semantics preserving. In C enum constants are more of loose constants -- given: enum Color { Red, Green, Blue, } C code can do things like `Red | Blue` -- which are not possible with Java enums. Moreover, C enum constants live in the same namespace as global variables. So it seemed again honest to allow clients to access enum constants directly after having imported (statically) the main generated header class. While in some ways using Java enums to model C enums look more natural, it also represents a significant departure from C. I can imagine that some simple uses of C enums would be quite happy with the approach you propose -- but this approach would not scale for more complex uses. The philosophy of jextract has, so far, been to generate a set of bindings that was as close as possible to the semantics of the extracted header. That has been the main guiding principle. There's a lot of "creativity" jextract could provide on top (and enums is a good example), but adding creativity almost always results in binding that work better in some cases and worse in others. For these reasons, I don't think this PR fits well with the design principles of jextract. One less radical move could be to give up to the "single namespace" property, and at least group related enum constants together, under a separate generated class. That would mean the Java code would require more "qualifiers" than the associated C code, but with some better separation. Would something like that be enough? Or do you really need these constants to be enum constants (e.g. because you use them in exhaustive switches etc.) ? ------------- PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3031589143 From mcimadamore at openjdk.org Thu Jul 3 09:46:58 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 3 Jul 2025 09:46:58 GMT Subject: RFR: Generate Java enums In-Reply-To: References: Message-ID: On Fri, 20 Jun 2025 17:09:19 GMT, Vivek Narang wrote: > We are using jextract in our [cuVS Java](https://github.com/rapidsai/cuvs/tree/branch-25.08/java) project. As of now, jextract generates individual getter functions for the C enums. This results in code where it is difficult to disambiguate which getter functions are logically grouped together for a particular Enum. Additionally, given the lack of this capability, we also have to manually create and maintain Java enums for each enum in the C layer. > > In this PR, I wish to introduce an option to additionally generate Java enums by passing an optional flag `--generate-java-enums`. In case a Java user wishes to use bitwise operations on the enums, they can use the enum's `.ordinal()` method for this. The original static getter methods will still be generated as before. > > Example C enum: > > enum SIZE { > S, > M, > L > }; > > Produces the following with jextract: > > private static final int S = (int)0L; > public static int S() { > return S; > } > > private static final int M = (int)1L; > public static int M() { > return M; > } > > private static final int L = (int)2L; > public static int L() { > return L; > } > > With this feature enabled using the `--generate-java-enums` flag, the following enum is generated (in addition to the above): > > public enum Size { > S(0), > M(1), > L(2); > > private final int value; > > private Size(int value) {; > this.value = value; > } > > public int getValue() { > return this.value; > } > } > > This PR is created against the `jdk22` branch. I will rebase it to `master` branch if needed. Another thing that came to mind: if we translate C enums as Java enums -- how is a native function accepting a C enum type translated? If we translate it as an int-accepting function (what we do now) then the Java enum constants cannot be used to call into native functions. If we translate it as a Java-enum-accepting function, then we would make these function stricter than their C counterparts. ------------- PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3031606147 From liach at openjdk.org Thu Jul 3 15:23:51 2025 From: liach at openjdk.org (Chen Liang) Date: Thu, 3 Jul 2025 15:23:51 GMT Subject: RFR: Gradle cleanup [v2] In-Reply-To: References: <2PIJo_9p4vA97BdA39UARTeRy2F_-5GZSH22o2cV_kM=.e89c04f2-30c8-487f-8ccb-a4732d49972c@github.com> Message-ID: <81HWuwzqNRclBJqZSlNUrBP-x1FOecDc86z2Ej99u8E=.f1977a06-3c31-4842-a335-fb3f32129567@github.com> On Thu, 3 Jul 2025 05:37:42 GMT, Clayton Walker wrote: >> I've been doing some development, and came across a few warnings during build. >> >> These are, [Project::task](https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html#task(java.lang.String)) is now deprecated, avoiding Project::mkdir, project::delete and Project::getProjectDir as they cannot work under configuration-cache. > > Clayton Walker has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: > > Fix running with configuration-cache enabled Haven't used gradle in a while so don't know about the latest deprecations, but these changes are existing gradle styles and make sense. ------------- Marked as reviewed by liach (no project role). PR Review: https://git.openjdk.org/jextract/pull/283#pullrequestreview-2983629813 From duke at openjdk.org Mon Jul 7 18:17:51 2025 From: duke at openjdk.org (Vivek Narang) Date: Mon, 7 Jul 2025 18:17:51 GMT Subject: RFR: Generate Java enums In-Reply-To: <6l9HLjo-lG7jlTreLx9ML3vYb-VFw1TIk0Wi7hj2tjQ=.7ca76e76-17aa-40c0-b8ae-89ec11097a22@github.com> References: <6l9HLjo-lG7jlTreLx9ML3vYb-VFw1TIk0Wi7hj2tjQ=.7ca76e76-17aa-40c0-b8ae-89ec11097a22@github.com> Message-ID: On Thu, 3 Jul 2025 09:38:18 GMT, Maurizio Cimadamore wrote: > One less radical move could be to give up to the "single namespace" property, and at least group related enum constants together, under a separate generated class. That would mean the Java code would require more "qualifiers" than the associated C code, but with some better separation. Would something like that be enough? Or do you really need these constants to be enum constants (e.g. because you use them in exhaustive switches etc.) ? Thanks @mcimadamore for your feedback. Yes, if we can at least group related enum constants together under a separate generated class, that will be awesome. Would it be okay if I update this PR to have this change? Please let me know. Thanks! ------------- PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3046121662 From duke at openjdk.org Mon Jul 7 18:39:51 2025 From: duke at openjdk.org (Vivek Narang) Date: Mon, 7 Jul 2025 18:39:51 GMT Subject: RFR: Generate Java enums In-Reply-To: <6l9HLjo-lG7jlTreLx9ML3vYb-VFw1TIk0Wi7hj2tjQ=.7ca76e76-17aa-40c0-b8ae-89ec11097a22@github.com> References: <6l9HLjo-lG7jlTreLx9ML3vYb-VFw1TIk0Wi7hj2tjQ=.7ca76e76-17aa-40c0-b8ae-89ec11097a22@github.com> Message-ID: On Thu, 3 Jul 2025 09:38:18 GMT, Maurizio Cimadamore wrote: > > ``` > enum Color > { > Red, > Green, > Blue, > } > ``` > > C code can do things like `Red | Blue` -- which are not possible with Java enums. > Hey @mcimadamore please excuse my gap in understanding here, but won't this operation be possible in Java by doing: `Color.Red.ordinal() | Color.Blue.ordinal()`? ------------- PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3046175531 From davidalayachew at gmail.com Mon Jul 7 18:48:48 2025 From: davidalayachew at gmail.com (David Alayachew) Date: Mon, 7 Jul 2025 14:48:48 -0400 Subject: RFR: Generate Java enums In-Reply-To: References: <6l9HLjo-lG7jlTreLx9ML3vYb-VFw1TIk0Wi7hj2tjQ=.7ca76e76-17aa-40c0-b8ae-89ec11097a22@github.com> Message-ID: No, because ordinal returns 0, 1, 2, 3, 4, 5, etc for each subsequent value. Whereas, it sounds like you need it to return 1, 2, 4, 8, etc. You could do the transformation yourself, of course. But if that doesn't work, maybe come at this from the opposite direction? What, in Java, gives you this OR-like functionality for enums? EnumSet! Maybe the better answer would be to have some way to return a long or long[] from an EnumSet to represent the included values? On Mon, Jul 7, 2025, 2:40?PM Vivek Narang wrote: > On Thu, 3 Jul 2025 09:38:18 GMT, Maurizio Cimadamore < > mcimadamore at openjdk.org> wrote: > > > > > ``` > > enum Color > > { > > Red, > > Green, > > Blue, > > } > > ``` > > > > C code can do things like `Red | Blue` -- which are not possible with > Java enums. > > > Hey @mcimadamore please excuse my gap in understanding here, but won't > this operation be possible in Java by doing: `Color.Red.ordinal() | > Color.Blue.ordinal()`? > > ------------- > > PR Comment: > https://git.openjdk.org/jextract/pull/284#issuecomment-3046175531 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mcimadamore at openjdk.org Mon Jul 7 21:28:52 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 7 Jul 2025 21:28:52 GMT Subject: RFR: Generate Java enums In-Reply-To: References: Message-ID: On Thu, 3 Jul 2025 09:43:59 GMT, Maurizio Cimadamore wrote: >> We are using jextract in our [cuVS Java](https://github.com/rapidsai/cuvs/tree/branch-25.08/java) project. As of now, jextract generates individual getter functions for the C enums. This results in code where it is difficult to disambiguate which getter functions are logically grouped together for a particular Enum. Additionally, given the lack of this capability, we also have to manually create and maintain Java enums for each enum in the C layer. >> >> In this PR, I wish to introduce an option to additionally generate Java enums by passing an optional flag `--generate-java-enums`. In case a Java user wishes to use bitwise operations on the enums, they can use the enum's `.ordinal()` method for this. The original static getter methods will still be generated as before. >> >> Example C enum: >> >> enum SIZE { >> S, >> M, >> L >> }; >> >> Produces the following with jextract: >> >> private static final int S = (int)0L; >> public static int S() { >> return S; >> } >> >> private static final int M = (int)1L; >> public static int M() { >> return M; >> } >> >> private static final int L = (int)2L; >> public static int L() { >> return L; >> } >> >> With this feature enabled using the `--generate-java-enums` flag, the following enum is generated (in addition to the above): >> >> public enum Size { >> S(0), >> M(1), >> L(2); >> >> private final int value; >> >> private Size(int value) {; >> this.value = value; >> } >> >> public int getValue() { >> return this.value; >> } >> } >> >> This PR is created against the `jdk22` branch. I will rebase it to `master` branch if needed. > > Another thing that came to mind: if we translate C enums as Java enums -- how is a native function accepting a C enum type translated? If we translate it as an int-accepting function (what we do now) then the Java enum constants cannot be used to call into native functions. If we translate it as a Java-enum-accepting function, then we would make these function stricter than their C counterparts. > Hey @mcimadamore please excuse my gap in understanding here, but won't this operation be possible in Java by doing: `Color.Red.ordinal() | Color.Blue.ordinal()`? As said in another comment, there's no guarantee that the Java enum ordinal and the value of the C enum constant will be the same. So, no, that would not be a good translation. Also, please consider clients passing enums to native functions -- right now they can just say e.g. native_func(RED); It would be sad if they had to do: native_func(RED.ordinal()); Of course one could imagine generating one extra overload for each enum-accepting function -- but that has issues: * you can only use the Java enum-accepting overload in some cases, but not other (where you want to use bitwise ops) * if a function uses N enum types, you need 2^N overloads (at least if you want to generate all possible combinations) I don't think much joy is to be had by modelling C enums with Java enums. We've been at it several times, and we keep retracing our steps back to the same answers. ------------- PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3046568103 From mcimadamore at openjdk.org Mon Jul 7 21:36:51 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 7 Jul 2025 21:36:51 GMT Subject: RFR: Generate Java enums In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 21:26:46 GMT, Maurizio Cimadamore wrote: >> Another thing that came to mind: if we translate C enums as Java enums -- how is a native function accepting a C enum type translated? If we translate it as an int-accepting function (what we do now) then the Java enum constants cannot be used to call into native functions. If we translate it as a Java-enum-accepting function, then we would make these function stricter than their C counterparts. > >> Hey @mcimadamore please excuse my gap in understanding here, but won't this operation be possible in Java by doing: `Color.Red.ordinal() | Color.Blue.ordinal()`? > > As said in another comment, there's no guarantee that the Java enum ordinal and the value of the C enum constant will be the same. So, no, that would not be a good translation. Also, please consider clients passing enums to native functions -- right now they can just say e.g. > > > native_func(RED); > > > It would be sad if they had to do: > > > native_func(RED.ordinal()); > > > Of course one could imagine generating one extra overload for each enum-accepting function -- but that has issues: > > * you can only use the Java enum-accepting overload in some cases, but not other (where you want to use bitwise ops) > * if a function uses N enum types, you need 2^N overloads (at least if you want to generate all possible combinations) > > I don't think much joy is to be had by modelling C enums with Java enums. We've been at it several times, and we keep retracing our steps back to the same answers. > Thanks @mcimadamore for your feedback. Yes, if we can at least group related enum constants together under a separate generated class, that will be awesome. Would it be okay if I update this PR to have this change? Please let me know. Thanks! I think we should ponder this some more. For simple use cases, it is really great to just have all the enum constants "in scope" in the same way as it happens with C. W/o that, the user would be left to try and figure out "what to include" for each enum. This might not be too obvious because the C source file one is trying to convert might only refer to enum _constants_ but never to the _enum type_ bringing these constants into existence. E.g. a C source might just use `Red` and `Green` and pass them to functions (and maybe these functions just take an `int`) -- and the code might never utter `Color`, ever. As a jextract user, how would I know that I need to `import static foo.Color.*` to get there? I'm not saying this is a blocker -- just listing all the various potential issues with changing the status quo (also as a way to explain why we are where we are). ------------- PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3046576333 From mcimadamore at openjdk.org Mon Jul 7 21:36:51 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 7 Jul 2025 21:36:51 GMT Subject: RFR: Generate Java enums In-Reply-To: References: Message-ID: <0F01GSE5o6Wntl5qJ5M0OXiCrLLpYR5CFq0xb69ym6s=.e5f5d649-a980-44a0-88ef-12458d4d6776@github.com> On Mon, 7 Jul 2025 18:50:48 GMT, David Alayachew wrote: > What, in Java, gives you this OR-like functionality for enums? EnumSet! Modelling each enum value as an enum set is certainly possible. It also sounds as overkill. One of the principles of jextract is to add as little overhead as possible. I think here we should just be honest and admit that C enums and Java enums don't have much in common, except for the use of the word `enum`. ------------- PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3046580435 From mcimadamore at openjdk.org Mon Jul 7 21:36:51 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 7 Jul 2025 21:36:51 GMT Subject: RFR: Generate Java enums In-Reply-To: <0F01GSE5o6Wntl5qJ5M0OXiCrLLpYR5CFq0xb69ym6s=.e5f5d649-a980-44a0-88ef-12458d4d6776@github.com> References: <0F01GSE5o6Wntl5qJ5M0OXiCrLLpYR5CFq0xb69ym6s=.e5f5d649-a980-44a0-88ef-12458d4d6776@github.com> Message-ID: On Mon, 7 Jul 2025 21:33:15 GMT, Maurizio Cimadamore wrote: > > What, in Java, gives you this OR-like functionality for enums? EnumSet! > > Modelling each enum value as an enum set is certainly possible. It also sounds as overkill. One of the principles of jextract is to add as little overhead as possible. I think here we should just be honest and admit that C enums and Java enums don't have much in common, except for the use of the word `enum`. (note -- this does NOT mean that other, more specialized, code generators could not model C enums as Java enums. Perhaps in some code bases that makes total sense. But jextract is intended to provide reliable bindings for _all_ C headers -- which sort of restricts the kind of tricks we can play) ------------- PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3046583256 From duke at openjdk.org Wed Jul 16 19:39:53 2025 From: duke at openjdk.org (Marcono1234) Date: Wed, 16 Jul 2025 19:39:53 GMT Subject: RFR: Generate Java enums In-Reply-To: References: <0F01GSE5o6Wntl5qJ5M0OXiCrLLpYR5CFq0xb69ym6s=.e5f5d649-a980-44a0-88ef-12458d4d6776@github.com> Message-ID: On Mon, 7 Jul 2025 21:34:38 GMT, Maurizio Cimadamore wrote: >>> What, in Java, gives you this OR-like functionality for enums? EnumSet! >> >> Modelling each enum value as an enum set is certainly possible. It also sounds as overkill. One of the principles of jextract is to add as little overhead as possible. I think here we should just be honest and admit that C enums and Java enums don't have much in common, except for the use of the word `enum`. > >> > What, in Java, gives you this OR-like functionality for enums? EnumSet! >> >> Modelling each enum value as an enum set is certainly possible. It also sounds as overkill. One of the principles of jextract is to add as little overhead as possible. I think here we should just be honest and admit that C enums and Java enums don't have much in common, except for the use of the word `enum`. > > (note -- this does NOT mean that other, more specialized, code generators could not model C enums as Java enums. Perhaps in some code bases that makes total sense. But jextract is intended to provide reliable bindings for _all_ C headers -- which sort of restricts the kind of tricks we can play) > > Hey @mcimadamore please excuse my gap in understanding here, but won't this operation be possible in Java by doing: `Color.Red.ordinal() | Color.Blue.ordinal()`? > > As said in another comment, there's no guarantee that the Java enum ordinal and the value of the C enum constant will be the same. So, no, that would not be a good translation. Also, please consider clients passing enums to native functions -- right now they can just say e.g. > > ```java > native_func(RED); > ``` Isn't this what the enum `getValue()` method included in this PR is for? E.g. `Color.Red.getValue() | Color.Blue.getValue()` and `native_func(RED.getValue())`. But the other concerns mentioned above still remain, such as making it difficult to discover which enum to use when a jextract-generated method just accepts an `int`, and that users might still accidentally use `ordinal()` or `MyEnum.values()[i]` instead of the `getValue()` method. ------------- PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3080028890 From nbenalla at openjdk.org Wed Jul 23 12:44:03 2025 From: nbenalla at openjdk.org (Nizar Benalla) Date: Wed, 23 Jul 2025 12:44:03 GMT Subject: RFR: 7903947: Access to function pointers in structs could be streamlined Message-ID: Please review this patch to add a new option where you can generate an direct invoker methods. This feature is intended to be used on structs that are just a collection of functions we had like to call. If this feature is used, we remove the getter to avoid name collisions as we assume this is similar to an interface. Changes to `GUIDE.md` have been intentionally left out from this initial patch to make reviews easier. struct Foo { struct Bar (*a)(void); struct Bar (*b)(int); }; Before var foo = alloc_callback_h.foo(); var barA = Foo.a.invoke(Foo.a(foo), arena); var barB = Foo.b.invoke(Foo.b(foo), arena, 100); After var foo = alloc_callback_h.foo(); var barA = Foo.a(foo, arena); var barB = Foo.b(foo, arena, 100); ------------- Commit messages: - add functional dispatch feature Changes: https://git.openjdk.org/jextract/pull/287/files Webrev: https://webrevs.openjdk.org/?repo=jextract&pr=287&range=00 Issue: https://bugs.openjdk.org/browse/CODETOOLS-7903947 Stats: 294 lines in 8 files changed: 263 ins; 6 del; 25 mod Patch: https://git.openjdk.org/jextract/pull/287.diff Fetch: git fetch https://git.openjdk.org/jextract.git pull/287/head:pull/287 PR: https://git.openjdk.org/jextract/pull/287 From mcimadamore at openjdk.org Thu Jul 24 09:29:11 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 24 Jul 2025 09:29:11 GMT Subject: RFR: 7903947: Access to function pointers in structs could be streamlined In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 12:37:47 GMT, Nizar Benalla wrote: > Please review this patch to add a new option where you can generate an direct invoker methods. This feature is intended to be used on structs that are just a collection of functions we had like to call. > > If this feature is used, we remove the getter to avoid name collisions as we assume this is similar to an interface. > > Changes to `GUIDE.md` have been intentionally left out from this initial patch to make reviews easier. > > > struct Foo { > struct Bar (*a)(void); > struct Bar (*b)(int); > }; > > > Before > > > var foo = alloc_callback_h.foo(); > > var barA = Foo.a.invoke(Foo.a(foo), arena); > var barB = Foo.b.invoke(Foo.b(foo), arena, 100); > > > After > > > var foo = alloc_callback_h.foo(); > > var barA = Foo.a(foo, arena); > var barB = Foo.b(foo, arena, 100); Just to recap solution we have explored previously. It would be nice if, in principle, just doing this: var bar = Foo.a(foo, ); worked, and it invoked the correct function pointer on the `foo` struct. But this solution can lead to clashes. Specifically, if the function pointer takes no arguments, then `Foo.a(foo)` would look exactly like a struct getter. Another solution would be to tweak `a::invoke` method to work on a `foo` instance directly, and not on the _address_ that function takes. But this breaks composition -- if you first obtain the function pointer (a MemorySegment) stored at `Foo::a`, and then want to invoke it at a later point, how would you do it? If `invoke` takes a segment for `Foo` you can't really -- you always need to _first_ store the address in the `Foo` struct, and _then_ call the desired function pointer using `a::invoke`. Which seems awkward. (note also that we cannot "just" add an overload of `a::invoke` that takes a Foo, because that is a memory segment too, so we get another clash). In other words, there's no "easy" solution here. One possibility might be to add an invoker accessor to `Foo` -- something like `Foo.a$invoke()`. Since this uses a different name there would be no clash with the getter. This leaves the problem that, in structs that contain only function pointers, the getters are probably not very useful, but maybe we can add logic to filter those out. The other solution is the one explored here: the developer _knows_ this isn't just _any_ struct, but a "functional" struct. It tells jextract, and jextract reacts by generating slightly different code. Perhaps one issue with this approach (although we arrived at it honestly) is that if one stares at code like: var barA = Foo.a(); It is pretty difficult to tell whether that's a getter/setter or an "invoker". src/main/java/org/openjdk/jextract/impl/StructBuilder.java line 160: > 158: boolean isFuncPtr = functionalDispatch && Utils.isFunctionPointer(type); > 159: if (isFuncPtr) { > 160: emitFieldSetter(javaName, varTree, layoutField, offsetField); I'm not sure we even want the setter -- the fields in these structs are typically populated by a library src/main/java/org/openjdk/jextract/impl/StructBuilder.java line 180: > 178: * Generates exactly one invoker, inlining the struct.get(...) to avoid name collision. > 179: */ > 180: private void emitFunctionalConvenience(String invokerName, I'd call this `emitInvoker` ------------- PR Comment: https://git.openjdk.org/jextract/pull/287#issuecomment-3112725685 PR Review Comment: https://git.openjdk.org/jextract/pull/287#discussion_r2227973060 PR Review Comment: https://git.openjdk.org/jextract/pull/287#discussion_r2227971894 From mcimadamore at openjdk.org Thu Jul 24 09:40:12 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 24 Jul 2025 09:40:12 GMT Subject: RFR: 7903947: Access to function pointers in structs could be streamlined In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 12:37:47 GMT, Nizar Benalla wrote: > Please review this patch to add a new option where you can generate an direct invoker methods. This feature is intended to be used on structs that are just a collection of functions we had like to call. > > If this feature is used, we remove the getter to avoid name collisions as we assume this is similar to an interface. > > Changes to `GUIDE.md` have been intentionally left out from this initial patch to make reviews easier. > > > struct Foo { > struct Bar (*a)(void); > struct Bar (*b)(int); > }; > > > Before > > > var foo = alloc_callback_h.foo(); > > var barA = Foo.a.invoke(Foo.a(foo), arena); > var barB = Foo.b.invoke(Foo.b(foo), arena, 100); > > > After > > > var foo = alloc_callback_h.foo(); > > var barA = Foo.a(foo, arena); > var barB = Foo.b(foo, arena, 100); src/main/java/org/openjdk/jextract/impl/IncludeHelper.java line 111: > 109: } > 110: > 111: if (kind == IncludeKind.STRUCT || kind == IncludeKind.UNION) { Not sure I get this logic -- it seems like we're always setting a property P for a typedef with name N whenever we see it set for a struct N? That seems odd. But in example as the one you added in the test are a bit ambiguous, as the same declaration induces both an anonymous struct decl and a typedef, so it is less clear which is which. If I write: typedef struct Foo { int a; }; It seems to be that jextract only retains a "struct" tree, and throws away the typedef. In fact I was surprised that your test worked at all, as in the above case `dump-includes` would include something like this: --include-struct Foo # header: .... And *not*: --include-typedef Foo # header: .... So adding a property on the typedef should have no effect? ------------- PR Review Comment: https://git.openjdk.org/jextract/pull/287#discussion_r2227999700 From duncan.gittins at gmail.com Thu Jul 24 13:49:50 2025 From: duncan.gittins at gmail.com (Duncan Gittins) Date: Thu, 24 Jul 2025 14:49:50 +0100 Subject: RFR: 7903947: Access to function pointers in structs could be streamlined In-Reply-To: References: Message-ID: This proposal makes it nicer to handle invokers. I generated my code with this change but as you'vr noted it does indeed lead to clashes using the proposed naming convention. My Windows COM apps run fine once I'd commented out a few of the clashing setters that I don't use, such as: // public static void Release(MemorySegment struct, MemorySegment fieldValue) { // struct.set(Release$LAYOUT, Release$OFFSET, fieldValue); // } public static int Release(MemorySegment struct, MemorySegment _x0) { MemorySegment fp = struct.get(Release$LAYOUT, Release$OFFSET); return Release.invoke(fp, _x0); } Will the use of ",functional" be the intended way to trigger this enhancement? I wonder whether last error capture could be built in with "--include-function funcname,erro" or "--include-function funcname,GetLastError" Kind regards Duncan On Thu, 24 Jul 2025 at 10:29, Maurizio Cimadamore wrote: > On Wed, 23 Jul 2025 12:37:47 GMT, Nizar Benalla > wrote: > > > Please review this patch to add a new option where you can generate an > direct invoker methods. This feature is intended to be used on structs that > are just a collection of functions we had like to call. > > > > If this feature is used, we remove the getter to avoid name collisions > as we assume this is similar to an interface. > > > > Changes to `GUIDE.md` have been intentionally left out from this initial > patch to make reviews easier. > > > > > > struct Foo { > > struct Bar (*a)(void); > > struct Bar (*b)(int); > > }; > > > > > > Before > > > > > > var foo = alloc_callback_h.foo(); > > > > var barA = Foo.a.invoke(Foo.a(foo), arena); > > var barB = Foo.b.invoke(Foo.b(foo), arena, 100); > > > > > > After > > > > > > var foo = alloc_callback_h.foo(); > > > > var barA = Foo.a(foo, arena); > > var barB = Foo.b(foo, arena, 100); > > Just to recap solution we have explored previously. > > It would be nice if, in principle, just doing this: > > > var bar = Foo.a(foo, ); > > > worked, and it invoked the correct function pointer on the `foo` struct. > But this solution can lead to clashes. Specifically, if the function > pointer takes no arguments, then `Foo.a(foo)` would look exactly like a > struct getter. > > Another solution would be to tweak `a::invoke` method to work on a `foo` > instance directly, and not on the _address_ that function takes. But this > breaks composition -- if you first obtain the function pointer (a > MemorySegment) stored at `Foo::a`, and then want to invoke it at a later > point, how would you do it? If `invoke` takes a segment for `Foo` you can't > really -- you always need to _first_ store the address in the `Foo` struct, > and _then_ call the desired function pointer using `a::invoke`. Which seems > awkward. > > (note also that we cannot "just" add an overload of `a::invoke` that takes > a Foo, because that is a memory segment too, so we get another clash). > > In other words, there's no "easy" solution here. One possibility might be > to add an invoker accessor to `Foo` -- something like > `Foo.a$invoke()`. Since this uses a different name there would be no > clash with the getter. This leaves the problem that, in structs that > contain only function pointers, the getters are probably not very useful, > but maybe we can add logic to filter those out. > > The other solution is the one explored here: the developer _knows_ this > isn't just _any_ struct, but a "functional" struct. It tells jextract, and > jextract reacts by generating slightly different code. Perhaps one issue > with this approach (although we arrived at it honestly) is that if one > stares at code like: > > > var barA = Foo.a(); > > > It is pretty difficult to tell whether that's a getter/setter or an > "invoker". > > src/main/java/org/openjdk/jextract/impl/StructBuilder.java line 160: > > > 158: boolean isFuncPtr = functionalDispatch && > Utils.isFunctionPointer(type); > > 159: if (isFuncPtr) { > > 160: emitFieldSetter(javaName, varTree, layoutField, > offsetField); > > I'm not sure we even want the setter -- the fields in these structs are > typically populated by a library > > src/main/java/org/openjdk/jextract/impl/StructBuilder.java line 180: > > > 178: * Generates exactly one invoker, inlining the struct.get(...) > to avoid name collision. > > 179: */ > > 180: private void emitFunctionalConvenience(String invokerName, > > I'd call this `emitInvoker` > > ------------- > > PR Comment: > https://git.openjdk.org/jextract/pull/287#issuecomment-3112725685 > PR Review Comment: > https://git.openjdk.org/jextract/pull/287#discussion_r2227973060 > PR Review Comment: > https://git.openjdk.org/jextract/pull/287#discussion_r2227971894 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mcimadamore at openjdk.org Thu Jul 24 15:05:16 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 24 Jul 2025 15:05:16 GMT Subject: RFR: 7903947: Access to function pointers in structs could be streamlined In-Reply-To: References: Message-ID: <86xB-gtak3q3U9wReUzoSqAruZUiYaljxrroZF1lfqs=.75ac9434-969b-4461-9dec-5c1efe6ca921@github.com> On Thu, 24 Jul 2025 13:52:05 GMT, Duncan Gittins wrote: > Will the use of ",functional" be the intended way to trigger this > enhancement? I wonder whether last error capture could be built in with > "--include-function funcname,erro" or "--include-function > funcname,GetLastError" Nice connection -- we do in fact have plans (at least in theory) to use this same mechanism for errno -- and maybe even to declare "disjoint enums" (e.g. enums that can be modelled as plain Java enums because you swear not to rely on low-level bitmask operation -- which is often the case if the enum you are modelling is just a "tag") > This proposal makes it nicer to handle invokers. I generated my code with > this change but as you'vr noted it does indeed lead to clashes using the > proposed naming convention. I think the issue is that the changes in this PR generate both setter and invoker -- and we should only emit the invoker. ------------- PR Comment: https://git.openjdk.org/jextract/pull/287#issuecomment-3113817281 PR Comment: https://git.openjdk.org/jextract/pull/287#issuecomment-3113821975 From duncan.gittins at gmail.com Fri Jul 25 09:25:18 2025 From: duncan.gittins at gmail.com (Duncan Gittins) Date: Fri, 25 Jul 2025 10:25:18 +0100 Subject: RFR: 7903947: Access to function pointers in structs could be streamlined In-Reply-To: <86xB-gtak3q3U9wReUzoSqAruZUiYaljxrroZF1lfqs=.75ac9434-969b-4461-9dec-5c1efe6ca921@github.com> References: <86xB-gtak3q3U9wReUzoSqAruZUiYaljxrroZF1lfqs=.75ac9434-969b-4461-9dec-5c1efe6ca921@github.com> Message-ID: Now I think about it, renaming the invoker may be necessary after all. The setter would be useful for applications to fill struct with Java upcalls to implement callbacks. eg implementing COM api, rather than using one. Duncan On Thu, 24 Jul 2025 at 16:05, Maurizio Cimadamore wrote: > On Thu, 24 Jul 2025 13:52:05 GMT, Duncan Gittins > wrote: > > > Will the use of ",functional" be the intended way to trigger this > > enhancement? I wonder whether last error capture could be built in with > > "--include-function funcname,erro" or "--include-function > > funcname,GetLastError" > > Nice connection -- we do in fact have plans (at least in theory) to use > this same mechanism for errno -- and maybe even to declare "disjoint enums" > (e.g. enums that can be modelled as plain Java enums because you swear not > to rely on low-level bitmask operation -- which is often the case if the > enum you are modelling is just a "tag") > > > This proposal makes it nicer to handle invokers. I generated my code with > > this change but as you'vr noted it does indeed lead to clashes using the > > proposed naming convention. > > I think the issue is that the changes in this PR generate both setter and > invoker -- and we should only emit the invoker. > > ------------- > > PR Comment: > https://git.openjdk.org/jextract/pull/287#issuecomment-3113817281 > PR Comment: > https://git.openjdk.org/jextract/pull/287#issuecomment-3113821975 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mcimadamore at openjdk.org Fri Jul 25 15:17:13 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 25 Jul 2025 15:17:13 GMT Subject: RFR: 7903947: Access to function pointers in structs could be streamlined In-Reply-To: References: Message-ID: <7qFTcupNNetWB-nsx9-25e0-eACotZtNi3_eZJmbCs4=.0edecd73-a021-4d32-8300-49e248ae82f0@github.com> On Fri, 25 Jul 2025 09:27:13 GMT, Duncan Gittins wrote: > Now I think about it, renaming the invoker may be necessary after all. > The setter would be useful for applications to fill struct with Java > upcalls to implement callbacks. eg implementing COM api, rather than using > one. Thanks, this is an useful data point. If it turns out that our assumption that "these structs only need invokers" is not 100% true, that doesn't leave us in a good place. While you could refrain from using the new flag on your struct, it feels like a "glass half empty" situation, because the code jextract would be able to generate is _almost there_. Which brings us back to another option: maybe the more honest option is to indeed add an invoker-like accessor for each function pointer field (e.g. Foo.m$invoke). The dollar in the same sucks a bit but, oh well, at least it's clear. Then, let's approach this from the other angle, and give developer more options to NOT generate stuff they don't want. E.g. maybe this struct is read-only and doesn't need setters? Or maybe it's invoke-only and doesn't need neither getters nor setters? Whatever the needs, and whatever the reason, we'd have a way to generate, more or less, only the stuff one would be interested in. So, maybe, instead of "functional struct", maybe some way to say what you want in a struct -- similar to Linux filesystem `rwx` (read/write/execute) :-) ------------- PR Comment: https://git.openjdk.org/jextract/pull/287#issuecomment-3118491817 From nbenalla at openjdk.org Mon Jul 28 13:50:14 2025 From: nbenalla at openjdk.org (Nizar Benalla) Date: Mon, 28 Jul 2025 13:50:14 GMT Subject: RFR: 7903947: Access to function pointers in structs could be streamlined In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 12:37:47 GMT, Nizar Benalla wrote: > Please review this patch to add a new option where you can generate an direct invoker methods. This feature is intended to be used on structs that are just a collection of functions we had like to call. > > If this feature is used, we remove the getter to avoid name collisions as we assume this is similar to an interface. > > Changes to `GUIDE.md` have been intentionally left out from this initial patch to make reviews easier. > > > struct Foo { > struct Bar (*a)(void); > struct Bar (*b)(int); > }; > > > Before > > > var foo = alloc_callback_h.foo(); > > var barA = Foo.a.invoke(Foo.a(foo), arena); > var barB = Foo.b.invoke(Foo.b(foo), arena, 100); > > > After > > > var foo = alloc_callback_h.foo(); > > var barA = Foo.a(foo, arena); > var barB = Foo.b(foo, arena, 100); I kept trying to avoid renaming the invoker as I didn't like having the dollar sign or a prefix in the invoker, but I like the idea of having readonly/write/execute mode in the config. ------------- PR Comment: https://git.openjdk.org/jextract/pull/287#issuecomment-3127329675 From mcimadamore at openjdk.org Mon Jul 28 15:03:10 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 28 Jul 2025 15:03:10 GMT Subject: RFR: 7903947: Access to function pointers in structs could be streamlined In-Reply-To: References: Message-ID: On Mon, 28 Jul 2025 15:00:13 GMT, Maurizio Cimadamore wrote: > > I kept trying to avoid renaming the invoker as I didn't like having the dollar sign or a prefix in the invoker, but I like the idea of having readonly/write/execute mode in the config. > > I feel your pain. We defo went thorugh a lot of pain to remove dollars from generated code: > > https://cr.openjdk.org/~mcimadamore/panama/jextract_changes.html > > So, it will be a bit sad to see them coming back. Also, it will make some code more verbose compared to their C counterpart, as the C syntax can distinguish between application (`foo.x()`) and access (`foo.x = ...`). Maybe worth thinking some more about what our options are... ------------- PR Comment: https://git.openjdk.org/jextract/pull/287#issuecomment-3127642536 From mcimadamore at openjdk.org Mon Jul 28 15:03:10 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 28 Jul 2025 15:03:10 GMT Subject: RFR: 7903947: Access to function pointers in structs could be streamlined In-Reply-To: References: Message-ID: On Mon, 28 Jul 2025 13:47:56 GMT, Nizar Benalla wrote: > I kept trying to avoid renaming the invoker as I didn't like having the dollar sign or a prefix in the invoker, but I like the idea of having readonly/write/execute mode in the config. I feel your pain. We defo went thorugh a lot of pain to remove dollars from generated code: https://cr.openjdk.org/~mcimadamore/panama/jextract_changes.html So, it will be a bit sad to see them coming back. Also, it will make some code more verbose compared to their C counterpart, as the C syntax can distinguish between application (`foo.x()`) and access (`foo.x = ...`). ------------- PR Comment: https://git.openjdk.org/jextract/pull/287#issuecomment-3127640332