RFR: 7903649: Field and global variables of array type should have indexed accessors
Jorn Vernee
jvernee at openjdk.org
Tue Jan 30 14:21:40 UTC 2024
On Tue, 30 Jan 2024 14:14:17 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:
>> Here's a concrete example (obtained from quickly hacking jextract's generated output). Consider this C global var declaration:
>>
>>
>> struct Point { int x; int y; } aPoint[3][4];
>>
>>
>> And here's the code generated by jextract:
>>
>> ```java
>> public static class aPoint {
>> static final SequenceLayout LAYOUT = MemoryLayout.sequenceLayout(3, MemoryLayout.sequenceLayout(4, Point.layout()));
>> static final MemorySegment SEGMENT = foo_h.findOrThrow("aPoint").reinterpret(LAYOUT.byteSize());
>> static final MethodHandle HANDLE = LAYOUT.sliceHandle(sequenceElement(), sequenceElement());
>> static final long[] DIMS = { 3, 4 };
>> }
>>
>> /**
>> * Getter for variable:
>> * {@snippet lang=c :
>> * struct Point aPoint[3][4]
>> * }
>> */
>> public static MemorySegment aPoint() {
>> return aPoint.SEGMENT;
>> }
>>
>> /**
>> * Setter for variable:
>> * {@snippet lang=c :
>> * struct Point aPoint[3][4]
>> * }
>> */
>> public static void aPoint(MemorySegment varValue) {
>> MemorySegment.copy(varValue, 0L, aPoint.SEGMENT, 0L, aPoint.LAYOUT.byteSize());
>> }
>>
>> /**
>> * Indexed getter for variable:
>> * {@snippet lang=c :
>> * struct Point aPoint[3][4]
>> * }
>> */
>> public static MemorySegment aPoint(long index0, long index1) {
>> try {
>> return (MemorySegment)aPoint.HANDLE.invokeExact(aPoint.SEGMENT, 0L, index0, index1);
>> } catch (Throwable ex$) {
>> throw new AssertionError("should not reach here", ex$);
>> }
>> }
>>
>> /**
>> * Indexed setter for variable:
>> * {@snippet lang=c :
>> * struct Point aPoint[3][4]
>> * }
>> */
>> public static void aPoint(long index0, long index1, MemorySegment varValue) {
>> MemorySegment.copy(varValue, 0L, aPoint(index0, index1), 0L, Point.layout().byteSize());
>> }
>>
>>
>> The accessors are still as available and as discoverable as before. But if the clients want to know additional info, they can dig deeper, by accessing the static fields on the public holder class. Thoughts?
>
> Quickly running some tests - the above approach runs into some ambiguities between function pointer class names and holder class names:
>
>
> test/jtreg/generator/funcPointerInvokers/TestFuncPointerInvokers.java:80: error: reference to fp is ambiguous
> fp(fp.allocate((i) -> val.set(i), arena));
>
>
> That's because the name used for the function pointer class is the same as the name of the variable which introduced the function pointer. So, if the client code uses a blanket static import of all members of the header class (which is what most jextract clients do), we run into ambiguities (as two classes with same name are available at different levels).
I think this looks great, at least for globals. For struct fields it might be okay as well, but it seems tempting to try and find a way to put these extra fields directly in the struct class.
-------------
PR Review Comment: https://git.openjdk.org/jextract/pull/198#discussion_r1471307291
More information about the jextract-dev
mailing list