@@ -152,19 +152,38 @@ impl wasmtime_environ::Compiler for Compiler {
152152
153153 let mut func_env = FuncEnvironment :: new ( isa, translation, types, tunables) ;
154154
155- // We use these as constant offsets below in
156- // `stack_limit_from_arguments`, so assert their values here. This
157- // allows the closure below to get coerced to a function pointer, as
158- // needed by `ir::Function`.
155+ // The `stack_limit` global value below is the implementation of stack
156+ // overflow checks in Wasmtime.
159157 //
160- // Otherwise our stack limit is specially calculated from the vmctx
161- // argument, where we need to load the `*const VMRuntimeLimits`
162- // pointer, and then from that pointer we need to load the stack
163- // limit itself. Note that manual register allocation is needed here
164- // too due to how late in the process this codegen happens.
158+ // The Wasm spec defines that stack overflows will raise a trap, and
159+ // there's also an added constraint where as an embedder you frequently
160+ // are running host-provided code called from wasm. WebAssembly and
161+ // native code currently share the same call stack, so Wasmtime needs to
162+ // make sure that host-provided code will have enough call-stack
163+ // available to it.
165164 //
166- // For more information about interrupts and stack checks, see the
167- // top of this file.
165+ // The way that stack overflow is handled here is by adding a prologue
166+ // check to all functions for how much native stack is remaining. The
167+ // `VMContext` pointer is the first argument to all functions, and the
168+ // first field of this structure is `*const VMRuntimeLimits` and the
169+ // first field of that is the stack limit. Note that the stack limit in
170+ // this case means "if the stack pointer goes below this, trap". Each
171+ // function which consumes stack space or isn't a leaf function starts
172+ // off by loading the stack limit, checking it against the stack
173+ // pointer, and optionally traps.
174+ //
175+ // This manual check allows the embedder to give wasm a relatively
176+ // precise amount of stack allocation. Using this scheme we reserve a
177+ // chunk of stack for wasm code relative from where wasm code was
178+ // called. This ensures that native code called by wasm should have
179+ // native stack space to run, and the numbers of stack spaces here
180+ // should all be configurable for various embeddings.
181+ //
182+ // Note that this check is independent of each thread's stack guard page
183+ // here. If the stack guard page is reached that's still considered an
184+ // abort for the whole program since the runtime limits configured by
185+ // the embedder should cause wasm to trap before it reaches that
186+ // (ensuring the host has enough space as well for its functionality).
168187 let vmctx = context
169188 . func
170189 . create_global_value ( ir:: GlobalValueData :: VMContext ) ;
0 commit comments