MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / enter_wasm

Method enter_wasm

crates/wasmtime/src/runtime/func.rs:1517–1607  ·  view source on GitHub ↗

This function is called to update and save state when WebAssembly is entered within the `Store`. This updates various fields such as: The stack limit. This is what ensures that we limit the stack space allocated by WebAssembly code and it's relative to the initial stack pointer that called into wasm. It also saves the different last_wasm_* values in the `VMStoreContext`.

(
        store: &mut StoreContextMut<'_, T>,
        initial_stack_information: *mut VMCommonStackInformation,
    )

Source from the content-addressed store, hash-verified

1515 ///
1516 /// It also saves the different last_wasm_* values in the `VMStoreContext`.
1517 pub fn enter_wasm<T>(
1518 store: &mut StoreContextMut<'_, T>,
1519 initial_stack_information: *mut VMCommonStackInformation,
1520 ) -> Self {
1521 let stack_limit;
1522
1523 // If this is a recursive call, e.g. our stack limit is already set, then
1524 // we may be able to skip this function.
1525 //
1526 // For synchronous stores there's nothing else to do because all wasm calls
1527 // happen synchronously and on the same stack. This means that the previous
1528 // stack limit will suffice for the next recursive call.
1529 //
1530 // For asynchronous stores then each call happens on a separate native
1531 // stack. This means that the previous stack limit is no longer relevant
1532 // because we're on a separate stack.
1533 if unsafe { *store.0.vm_store_context().stack_limit.get() } != usize::MAX
1534 && !store.0.can_block()
1535 {
1536 stack_limit = None;
1537 }
1538 // Ignore this stack pointer business on miri since we can't execute wasm
1539 // anyway and the concept of a stack pointer on miri is a bit nebulous
1540 // regardless.
1541 else if cfg!(miri) {
1542 stack_limit = None;
1543 } else {
1544 // When Cranelift has support for the host then we might be running native
1545 // compiled code meaning we need to read the actual stack pointer. If
1546 // Cranelift can't be used though then we're guaranteed to be running pulley
1547 // in which case this stack pointer isn't actually used as Pulley has custom
1548 // mechanisms for stack overflow.
1549 #[cfg(has_host_compiler_backend)]
1550 let stack_pointer = crate::runtime::vm::get_stack_pointer();
1551 #[cfg(not(has_host_compiler_backend))]
1552 let stack_pointer = {
1553 use wasmtime_environ::TripleExt;
1554 debug_assert!(store.engine().target().is_pulley());
1555 usize::MAX
1556 };
1557
1558 // Determine the stack pointer where, after which, any wasm code will
1559 // immediately trap. This is checked on the entry to all wasm functions.
1560 //
1561 // Note that this isn't 100% precise. We are requested to give wasm
1562 // `max_wasm_stack` bytes, but what we're actually doing is giving wasm
1563 // probably a little less than `max_wasm_stack` because we're
1564 // calculating the limit relative to this function's approximate stack
1565 // pointer. Wasm will be executed on a frame beneath this one (or next
1566 // to it). In any case it's expected to be at most a few hundred bytes
1567 // of slop one way or another. When wasm is typically given a MB or so
1568 // (a million bytes) the slop shouldn't matter too much.
1569 //
1570 // After we've got the stack limit then we store it into the `stack_limit`
1571 // variable.
1572 //
1573 // Also note that `saturating_sub` is used here since if the user
1574 // said that the function gets nigh-infinite stack well then by

Callers

nothing calls this directly

Calls 10

saturating_subMethod · 0.80
get_stack_pointerFunction · 0.50
replaceFunction · 0.50
InitialStackClass · 0.50
getMethod · 0.45
vm_store_contextMethod · 0.45
can_blockMethod · 0.45
configMethod · 0.45
engineMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected