pchickey opened Issue #1917:
Issue filed based on discussion: https://github.com/bytecodealliance/wasmtime/pull/1910#discussion_r444963814
The
wigglecrate relies on performing run-time borrow checking of accesses into a linear memory for safety. Currently, there is no mechanism in Wasmtime which can associate a borrow checker with a linear memory. Presently, we create a fresh borrow checker each time we enter host code, but this requires the host code to never re-enter the same WebAssembly instance, a property which we cannot enforce statically or dynamically.We need to design some mechanism by which the
wasmtimecrate can associate a borrow checker with a memory for the memory's entire lifetime. Wasmtime would then be responsible for checking that the borrow checker has no outstanding borrows whenever an instance which has access to that memory is called.Ideally, the wasmtime borrow checker would be represented as a trait object, so that we can keep the definition of the borrow checker in the wiggle crate (where it is also used in Lucet), and not require wasmtime users to depend on wiggle nor wiggle users to depend on wasmtime.
pchickey labeled Issue #1917:
Issue filed based on discussion: https://github.com/bytecodealliance/wasmtime/pull/1910#discussion_r444963814
The
wigglecrate relies on performing run-time borrow checking of accesses into a linear memory for safety. Currently, there is no mechanism in Wasmtime which can associate a borrow checker with a linear memory. Presently, we create a fresh borrow checker each time we enter host code, but this requires the host code to never re-enter the same WebAssembly instance, a property which we cannot enforce statically or dynamically.We need to design some mechanism by which the
wasmtimecrate can associate a borrow checker with a memory for the memory's entire lifetime. Wasmtime would then be responsible for checking that the borrow checker has no outstanding borrows whenever an instance which has access to that memory is called.Ideally, the wasmtime borrow checker would be represented as a trait object, so that we can keep the definition of the borrow checker in the wiggle crate (where it is also used in Lucet), and not require wasmtime users to depend on wiggle nor wiggle users to depend on wasmtime.
alexcrichton commented on Issue #1917:
One thing we could do here is allow attaching a type map or a
Box<Any>to an instance, but I think the best route here may actually be to move the borrow checker into wasmtime itself. It seems like trying to get a raw view into wasm memory is going to be a pretty common thing to do in Rust, so making this a safe method onMemorywould be pretty compelling. I'm not sure how to best work with the wasmtime/lucet split, though?
pchickey commented on Issue #1917:
My idea to manage the wasmtime/lucet split:
- change the
wiggle::GuestMemorytrait to have all ofBorrowChecker's methods inline (has_outstanding_borrows,borrow,unborrow,is_borrowed) rather than aborrow_checker(&self) -> &BorrowCheckermethod.- move the concrete
wiggle::BorrowCheckertype to be part of wasmtime. Impl theGuestMemorytrait inwasmtime-wigglewith wasmtime'sBorrowCheckerandMemory.- Lucet can make its own copy of
BorrowCheckerto keep inlucet-wiggleor elsewhere.
pchickey edited a comment on Issue #1917:
My idea to manage the wasmtime/lucet split:
- change the
wiggle::GuestMemorytrait to have all ofBorrowChecker's methods inline (has_outstanding_borrows,borrow,unborrow,is_borrowed) rather than aborrow_checker(&self) -> &BorrowCheckermethod.- move the concrete
wiggle::BorrowCheckertype to be part of wasmtime. Impl theGuestMemorytrait inwasmtime-wigglewith wasmtime'sBorrowCheckerandMemory.- Lucet can make its own copy of
BorrowCheckerto keep inlucet-wiggleor elsewhere, and i mpl theGuestMemorytrait in terms of that concrete type and ourVmctx(we dont have aMemoryequivelant)
pchickey edited a comment on Issue #1917:
My idea to manage the wasmtime/lucet split:
- change the
wiggle::GuestMemorytrait to have all ofBorrowChecker's methods inline (has_outstanding_borrows,borrow,unborrow,is_borrowed) rather than aborrow_checker(&self) -> &BorrowCheckermethod.- move the concrete
wiggle::BorrowCheckertype to be part of wasmtime. Impl theGuestMemorytrait inwasmtime-wigglewith wasmtime'sBorrowCheckerandMemory.- Lucet can make its own copy of
BorrowCheckerto keep inlucet-wiggleor elsewhere, and i mpl theGuestMemorytrait in terms of that concrete type and ourVmctx(we dont have aMemoryequivalent)
pchickey edited a comment on Issue #1917:
My idea to manage the wasmtime/lucet split:
- change the
wiggle::GuestMemorytrait to have all ofBorrowChecker's methods inline (has_outstanding_borrows,borrow,unborrow,is_borrowed) rather than aborrow_checker(&self) -> &BorrowCheckermethod.- move the concrete
wiggle::BorrowCheckertype to be part of wasmtime. Impl theGuestMemorytrait inwasmtime-wigglewith wasmtime'sBorrowCheckerandMemory.- Lucet can make its own copy of
BorrowCheckerto keep inlucet-wiggleor elsewhere, and impl theGuestMemorytrait in terms of that concrete type and ourVmctx(we dont have aMemoryequivalent)
pchickey edited a comment on Issue #1917:
My idea to manage the wasmtime/lucet split:
- change the
wiggle::GuestMemorytrait to have all ofBorrowChecker's methods inline (has_outstanding_borrows,borrow,unborrow,is_borrowed) rather than aborrow_checker(&self) -> &BorrowCheckermethod. We can then delete theBorrowCheckertype from wiggle.- move the concrete
wiggle::BorrowCheckertype to be part of wasmtime. Impl theGuestMemorytrait inwasmtime-wigglewith wasmtime'sBorrowCheckerandMemory.- Lucet can make its own copy of
BorrowCheckerto keep inlucet-wiggleor elsewhere, and impl theGuestMemorytrait in terms of that concrete type and ourVmctx(we dont have aMemoryequivalent)
alexcrichton commented on Issue #1917:
Sounds reasonable to me!
pchickey commented on Issue #1917:
I'm preparing a PR which does steps 1 and 3 of this transformation, moving the
BorrowCheckerconcrete impl towasmtime-wiggleas a staging ground for step 2, where it can be moved fully intowasmtime.
Last updated: Dec 06 2025 at 06:05 UTC