Module wasmtime_runtime::libcalls
source · Expand description
Runtime library calls.
Note that Wasm compilers may sometimes perform these inline rather than calling them, particularly when CPUs have special instructions which compute them directly.
These functions are called by compiled Wasm code, and therefore must take certain care about some things:
-
They must only contain basic, raw i32/i64/f32/f64/pointer parameters that are safe to pass across the system ABI.
-
If any nested function propagates an
Err(trap)
out to the library function frame, we need to raise it. This involves some nasty and quite unsafe code under the covers! Notably, after raising the trap, drops will not be run for local variables! This can lead to things like leakingInstanceHandle
s which leads to never deallocating JIT code, instances, and modules if we are not careful! -
The libcall must be entered via a Wasm-to-libcall trampoline that saves the last Wasm FP and PC for stack walking purposes. (For more details, see
crates/runtime/src/backtrace.rs
.)
To make it easier to correctly handle all these things, all libcalls
must be defined via the libcall!
helper macro! See its doc comments below
for an example, or just look at the rest of the file.
Dealing with externref
s
When receiving a raw *mut u8
that is actually a VMExternRef
reference,
convert it into a proper VMExternRef
with VMExternRef::clone_from_raw
as
soon as apossible. Any GC before raw pointer is converted into a reference
can potentially collect the referenced object, which could lead to use after
free.
Avoid this by eagerly converting into a proper VMExternRef
! (Unfortunately
there is no macro to help us automatically get this correct, so stay
vigilant!)
pub unsafe extern "C" my_libcall_takes_ref(raw_extern_ref: *mut u8) {
// Before `clone_from_raw`, `raw_extern_ref` is potentially unrooted,
// and doing GC here could lead to use after free!
let my_extern_ref = if raw_extern_ref.is_null() {
None
} else {
Some(VMExternRef::clone_from_raw(raw_extern_ref))
};
// Now that we did `clone_from_raw`, it is safe to do a GC (or do
// anything else that might transitively GC, like call back into
// Wasm!)
}
Modules
- Actually public trampolines which are used by the runtime as the entrypoint for libcalls.