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