Module wasmtime_runtime::libcalls [−][src]
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 always be
pub extern "C"
and should 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! Notable, 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! Therefore, always use nested blocks to ensure drops run before raising a trap:ⓘpub extern "C" fn my_lib_function(...) { let result = { // Do everything in here so drops run at the end of the block. ... }; if let Err(trap) = result { // Now we can safely raise the trap without leaking! raise_lib_trap(trap); } }
-
When receiving a raw
*mut u8
that is actually aVMExternRef
reference, convert it into a properVMExternRef
withVMExternRef::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 properVMExternRef
!ⓘpub unsafe extern "C" my_lib_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!) }
Functions
wasmtime_activations_table_insert_with_gc⚠ | Do a GC and insert the given |
wasmtime_data_drop⚠ | Implementation of |
wasmtime_drop_externref⚠ | Drop a |
wasmtime_elem_drop⚠ | Implementation of |
wasmtime_externref_global_get⚠ | Perform a Wasm |
wasmtime_externref_global_set⚠ | Perform a Wasm |
wasmtime_f32_ceil | Implementation of f32.ceil |
wasmtime_f32_floor | Implementation of f32.floor |
wasmtime_f32_nearest | Implementation of f32.nearest |
wasmtime_f32_trunc | Implementation of f32.trunc |
wasmtime_f64_ceil | Implementation of f64.ceil |
wasmtime_f64_floor | Implementation of f64.floor |
wasmtime_f64_nearest | Implementation of f64.nearest |
wasmtime_f64_trunc | Implementation of f64.trunc |
wasmtime_i64_ishl | Implementation of i64.ishl |
wasmtime_i64_sdiv | Implementation of i64.sdiv |
wasmtime_i64_srem | Implementation of i64.srem |
wasmtime_i64_sshr | Implementation of i64.sshr |
wasmtime_i64_udiv | Implementation of i64.udiv |
wasmtime_i64_urem | Implementation of i64.urem |
wasmtime_i64_ushr | Implementation of i64.ushr |
wasmtime_imported_memory32_grow⚠ | Implementation of memory.grow for imported 32-bit memories. |
wasmtime_imported_memory32_size⚠ | Implementation of memory.size for imported 32-bit memories. |
wasmtime_imported_memory_fill⚠ | Implementation of |
wasmtime_memory32_grow⚠ | Implementation of memory.grow for locally-defined 32-bit memories. |
wasmtime_memory32_size⚠ | Implementation of memory.size for locally-defined 32-bit memories. |
wasmtime_memory_copy⚠ | Implementation of |
wasmtime_memory_fill⚠ | Implementation of |
wasmtime_memory_init⚠ | Implementation of |
wasmtime_table_copy⚠ | Implementation of |
wasmtime_table_fill⚠ | Implementation of |
wasmtime_table_grow⚠ | Implementation of |
wasmtime_table_init⚠ | Implementation of |