diff --git a/docs/langref.rst b/docs/langref.rst index 6d64b42f03..d2896722c4 100644 --- a/docs/langref.rst +++ b/docs/langref.rst @@ -191,6 +191,10 @@ in this reference. This is either :type:`i32`, or :type:`i64`, depending on whether the target platform has 32-bit or 64-bit pointers. +.. type:: iN + + Any of the scalar integer types :type:`i8` -- :type:`i64`. + Control flow ============ @@ -514,6 +518,89 @@ instructions before instruction selection:: v9 = stack_addr ss3, 16 v1 = load.f64 v9 +Heaps +----- + +Code compiled from WebAssembly or asm.js runs in a sandbox where it can't access +all process memory. Instead, it is given a small set of memory areas to work +in, and all accesses are bounds checked. Cretonne models this through the +concept of *heaps*. + +A heap is declared in the function preample and can be accessed with restricted +instructions that trap on out-of-bounds accesses. Heap addresses can be smaller +than the native pointer size, for example unsigned :type:`i32` offsets on a +64-bit architecture. + +.. inst:: H = heap Name + + Declare a heap in the function preample. + + This doesn't allocate memory, it just retrieves a handle to a sandbox from + the runtime environment. + + :arg Name: String identifying the heap in the runtime environment. + :result H: Heap identifier. + +.. inst:: a = heap_load H, p, Offset + + Load a value at the address ``p + Offset`` in the heap H. + + Trap if the heap access would be out of bounds. + + :arg H: Heap identifier created by :inst:`heap`. + :arg iN p: Unsigned base address in heap. + :arg Offset: Immediate signed offset. + :flag align(N): Expected alignment of ``p + Offset``. Power of two. + :flag aligntrap: Always trap if the memory access is misaligned. + :result T a: Loaded value. + +.. inst:: a = heap_store H, x, p, Offset + + Store a value at the address ``p + Offset`` in the heap H. + + Trap if the heap access would be out of bounds. + + :arg H: Heap indetifier created by :inst:`heap`. + :arg T x: Value to be stored. + :arg iN p: Unsigned base address in heap. + :arg Offset: Immediate signed offset. + :flag align(N): Expected alignment of ``p + Offset``. Power of two. + :flag aligntrap: Always trap if the memory access is misaligned. + +When optimizing heap accesses, Cretonne may separate the heap bounds checking +and address computations from the memory accesses. + +.. inst:: a = heap_addr H, p, Size + + Bounds check and compute absolute address of heap memory. + + Verify that the address range ``p .. p + Size - 1`` is valid in the heap H, + and trap if not. + + Convert the heap-relative address in ``p`` to a real absolute address and + return it. + + :arg H: Heap identifier created by :inst:`heap`. + :arg iN p: Unsigned base address in heap. + :arg Size: Immediate unsigned byte count for range to verify. + :result iPtr a: Absolute address corresponding to ``p``. + +A small example using heaps:: + + function vdup(i32, i32) { + h1 = heap "main" + + entry ebb1(v1: i32, v2: i32): + v3 = heap_load.i32x4 h1, v1, 0 + v4 = heap_addr h1, v2, 32 ; Shared range check for two stores. + store v3, v4, 0 + store v3, v4, 16 + return + } + +The final expansion of the :inst:`heap_addr` range check and address conversion +depends on the runtime environment. + Operations ==========