1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
pub use wasmtime_wiggle_macro::*;
pub use wiggle::*;

mod borrow;

use borrow::BorrowChecker;

/// Lightweight `wasmtime::Memory` wrapper so we can implement the
/// `wiggle::GuestMemory` trait on it.
pub struct WasmtimeGuestMemory {
    mem: wasmtime::Memory,
    bc: BorrowChecker,
}

impl WasmtimeGuestMemory {
    pub fn new(mem: wasmtime::Memory) -> Self {
        Self {
            mem,
            // Wiggle does not expose any methods for functions to re-enter
            // the WebAssembly instance, or expose the memory via non-wiggle
            // mechanisms. However, the user-defined code may end up
            // re-entering the instance, in which case this is an incorrect
            // implementation - we require exactly one BorrowChecker exist per
            // instance.
            // This BorrowChecker construction is a holdover until it is
            // integrated fully with wasmtime:
            // https://github.com/bytecodealliance/wasmtime/issues/1917
            bc: BorrowChecker::new(),
        }
    }
}

unsafe impl GuestMemory for WasmtimeGuestMemory {
    fn base(&self) -> (*mut u8, u32) {
        (self.mem.data_ptr(), self.mem.data_size() as _)
    }
    fn has_outstanding_borrows(&self) -> bool {
        self.bc.has_outstanding_borrows()
    }
    fn is_borrowed(&self, r: Region) -> bool {
        self.bc.is_borrowed(r)
    }
    fn borrow(&self, r: Region) -> Result<BorrowHandle, GuestError> {
        self.bc.borrow(r)
    }
    fn unborrow(&self, h: BorrowHandle) {
        self.bc.unborrow(h)
    }
}