wasmtime_cranelift/translate/
heap.rs

1//! Heaps to implement WebAssembly linear memories.
2
3use cranelift_codegen::ir::{self, GlobalValue, MemoryType, Type};
4use cranelift_entity::entity_impl;
5use wasmtime_environ::{IndexType, Memory};
6
7/// An opaque reference to a [`HeapData`][crate::HeapData].
8///
9/// While the order is stable, it is arbitrary.
10#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
11pub struct Heap(u32);
12entity_impl!(Heap, "heap");
13
14/// A heap implementing a WebAssembly linear memory.
15///
16/// Code compiled from WebAssembly runs in a sandbox where it can't access all
17/// process memory. Instead, it is given a small set of memory areas to work in,
18/// and all accesses are bounds checked. Wasmtime models this through
19/// the concept of *heaps*.
20///
21/// Heap addresses can be smaller than the native pointer size, for example
22/// unsigned `i32` offsets on a 64-bit architecture.
23///
24/// A heap appears as three consecutive ranges of address space:
25///
26/// 1. The *mapped pages* are the accessible memory range in the heap. A heap
27///    may have a minimum guaranteed size which means that some mapped pages are
28///    always present.
29///
30/// 2. The *unmapped pages* is a possibly empty range of address space that may
31///    be mapped in the future when the heap is grown. They are addressable but
32///    not accessible.
33///
34/// 3. The *offset-guard pages* is a range of address space that is guaranteed
35///    to always cause a trap when accessed. It is used to optimize bounds
36///    checking for heap accesses with a shared base pointer. They are
37///    addressable but not accessible.
38#[derive(Clone, PartialEq, Hash)]
39pub struct HeapData {
40    /// The address of the start of the heap's storage.
41    pub base: GlobalValue,
42
43    /// The dynamic byte length of this heap, if needed.
44    pub bound: GlobalValue,
45
46    /// The type of wasm memory that this heap is operating on.
47    pub memory: Memory,
48
49    /// The memory type for the pointed-to memory, if using proof-carrying code.
50    pub pcc_memory_type: Option<MemoryType>,
51}
52
53impl HeapData {
54    pub fn index_type(&self) -> Type {
55        match self.memory.idx_type {
56            IndexType::I32 => ir::types::I32,
57            IndexType::I64 => ir::types::I64,
58        }
59    }
60}