RFR: Fix incorrect base offset handling in generated array field accessors

Maurizio Cimadamore mcimadamore at openjdk.org
Wed Nov 12 11:39:42 UTC 2025


On Wed, 12 Nov 2025 10:49:06 GMT, Maurizio Cimadamore <mcimadamore 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.
>
> Marked as reviewed by mcimadamore (Reviewer).

> @mcimadamore Which approach do you think is more correct? `emitFieldArrayGetter`, `emitFieldArraySetter` patch or `VarHandle` patch?

I think the one you have in this PR is more consistent with how the rest of jextract code works. If we do a more global switch to path-based var handles, we might reconsider.

(the reason we don't use path-based var handle is we'd like to limit the number of dynamic classes being generated -- for big headers it might make a difference)

-------------

PR Comment: https://git.openjdk.org/jextract/pull/294#issuecomment-3521487074


More information about the jextract-dev mailing list