RFR: Fix incorrect base offset handling in generated array field accessors [v2]
Jorn Vernee
jvernee at openjdk.org
Wed Nov 12 12:16:48 UTC 2025
On Wed, 12 Nov 2025 12:03:33 GMT, devjeonghwan <duke at openjdk.org> wrote:
>> #### 1. Status Quo
>>
>> Array field accessors generated by jextract (e.g., for `int arr[3]`) currently use a fixed base offset `0L` in `VarHandle.get/set` or `MethodHandle.invokeExact`.
>> This causes all array accesses to start from the beginning of the struct, ignoring the field’s actual offset.
>>
>> #### 2. Problem
>>
>> Because of the missing base offset, writing to array elements in nested structs or unions can overwrite unrelated fields in the same structure.
>> For example, updating `maxBlockDimension[1]` could corrupt `computeCapabilityMajor` or other preceding fields.
>>
>> typedef struct CudaDeviceInfo_st
>> {
>> int id;
>>
>> int computeCapabilityMajor;
>> int computeCapabilityMinor;
>> int multiprocessorCount;
>>
>> int warpSize;
>> int maxThreadsPerBlock;
>> int maxThreadsPerMultiprocessor;
>> int maxBlockDimension[3];
>> int maxGridDimension[3];
>>
>> bool unifiedAddressing;
>> bool integratedMemory;
>> } CudaDeviceInfo;
>>
>>
>> #### 3. Fix
>>
>> This patch updates `emitFieldArrayGetter` and `emitFieldArraySetter` to pass the correct field offset (`offsetField`) to all generated array accessors.
>> This ensures correct addressing for both primitive and struct/union element arrays.
>>
>> **Example:**
>>
>>
>> // Before
>> varHandle.get(struct, 0L, index);
>>
>> // After
>> varHandle.get(struct, fieldOffset, index);
>>
>>
>> #### 4. Additional Notes
>>
>> While the more idiomatic FFM approach of generating 'path-based' `VarHandle`s (e.g., `LAYOUT.varHandle(groupElement(...), ...)`) was considered, this patch takes a minimal-change approach. So It retains the existing handle and fixes the bug by passing the `fieldOffset` as the base offset (replacing `0L`).
>>
>> If the path-based `VarHandle` approach is preferred, I can rework this.
>>
>> #### 5. Testing
>>
>> New test cases were added to verify correct offset handling for:
>>
>> * Primitive arrays in structs
>> * Struct arrays in structs
>> * Struct arrays inside unions
>>
>> All tests pass locally.
>
> devjeonghwan has updated the pull request incrementally with one additional commit since the last revision:
>
> Update test to use `C_INT.byteSize()` for array field layout assertions
Thanks for fixing!
I think I've run into this in the past as well, but assumed that the intent was to get the array segment first with the segment getter, and then pass that segment to the array accessor (it didn't really feel right, but then it feel off my radar again).
-------------
PR Review: https://git.openjdk.org/jextract/pull/294#pullrequestreview-3453135815
More information about the jextract-dev
mailing list