Misalignment handling - chung-leong/zigar GitHub Wiki
If a pointer contains an address that does not meet the Zig's alignment requirement, Zigar will allocate a new buffer, copy the data there, and pass a correctly aligned pointer to the Zig function. Afterward, it'll copy the data back. Consider the following example:
const std = @import("std");
pub fn set(ptr1: *i16, ptr2: *i32) void {
ptr2.* = 0x22222222;
ptr1.* = 0x1111;
}
import { set } from './misalignment-example-1.zig';
const buffer = new ArrayBuffer(16);
const int32 = new DataView(buffer, 1, 4);
const int16 = new DataView(buffer, 3, 2);
set(int16, int32);
console.log(buffer);
ArrayBuffer {
[Uint8Contents]: <00 22 22 11 11 00 00 00 00 00 00 00 00 00 00 00>,
byteLength: 16
}
Both int32
and int16
sit on odd-number addresses (ArrayBuffer
is aligned to at least 8).
Since the alignment for i32
is 4 and i16
is 2, corrective measures are needed. Zigar is
designed to handle aliasing pointers, that is, pointers that point to overlapping regions of
memory. In the example int16
sits within int32
, that's why half of the latter gets partially
overwritten.
You'll get an error when you create a situation where alignment requirements cannot be satisfied for all aliasing pointers:
import { set } from './misalignment-example-1.zig';
const buffer = new ArrayBuffer(16);
const i32 = new DataView(buffer, 1, 4);
const i16 = new DataView(buffer, 4, 2);
try {
set(i16, i32);
} catch (err) {
console.log(err.message);
}
Unable to simultaneously align memory to 4-byte and 2-byte boundary