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

devjeonghwan duke at openjdk.org
Tue Nov 11 19:52:09 UTC 2025


#### 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.

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

Commit messages:
 - Update copyright year to 2025
 - Simplify test method names for clarity
 - Fix nits
 - Add test for struct and union array field handling
 - Update parameter type `Variable` to `Declaration.Variable` in `emitFieldArrayGetter` and `emitFieldArraySetter`
 - Add `offsetField` parameter to emit method for `FieldArray` getter and setter

Changes: https://git.openjdk.org/jextract/pull/294/files
  Webrev: https://webrevs.openjdk.org/?repo=jextract&pr=294&range=00
  Stats: 245 lines in 3 files changed: 235 ins; 0 del; 10 mod
  Patch: https://git.openjdk.org/jextract/pull/294.diff
  Fetch: git fetch https://git.openjdk.org/jextract.git pull/294/head:pull/294

PR: https://git.openjdk.org/jextract/pull/294


More information about the jextract-dev mailing list