Handling Rust Slices (&[T] and &mut [T]) in Java

Rust Side

In Rust, slices (&[T] and &mut [T]) represent a reference to a contiguous sequence of elements, without ownership. For FFI, we pass both the pointer to the data and the length of the slice.

Example Rust Slice:

#![allow(unused)]
fn main() {
#[no_mangle]
extern "C" fn sum_slice(slice: *const i32, len: usize) -> i32 {
    let slice = unsafe { std::slice::from_raw_parts(slice, len) };
    slice.iter().sum()
}
}

Explanation: sum_slice: Accepts a pointer and a length, allowing Rust to treat them as a slice. This approach enables safe manipulation and reading of slice data in Rust while preserving FFI compatibility.

Java Side

To interact with Rust slices from Java:

  1. Define a SequenceLayout that reflects the slice structure.
  2. Use a MethodHandle to invoke Rust’s functions on the slice.

Example Java Code:

// Define the layout for an array of 5 integers
SequenceLayout sliceLayout = MemoryLayout.sequenceLayout(5, ValueLayout.JAVA_INT);

// MethodHandle for sum_slice function
MethodHandle sumSlice = linker.downcallHandle(
    symbolLookup.lookup("sum_slice").get(),
    FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_LONG)
);

Explanation:

  • sliceLayout: Defines the memory layout for a fixed-size slice.
  • MethodHandle (sumSlice): Links to Rust’s sum_slice function, allowing Java to call it with a memory segment and length.

Allocating and Accessing Slice Elements

var arena = Arena.ofConfined();
MemorySegment sliceSegment = arena.allocate(sliceLayout);

VarHandle intHandle = ValueLayout.JAVA_INT.varHandle();
intHandle.set(sliceSegment, 0, 10);
intHandle.set(sliceSegment, 1, 20);

int result = (int) sumSlice.invokeExact(sliceSegment, 5L);  // Sum the slice
System.out.println("Sum of slice elements: " + result);

Explanation: Arena Allocation: Allocates the slice’s memory in an arena for safe usage.

Setting and Summing Elements: Uses VarHandles for direct element access and sumSlice for calculating the sum, bridging Rust’s slice handling with Java effectively.