Call a function from within the current host-function invocation. This is the safe way for host functions to perform blocking reentrant calls into Wasm. Unlike [`Function::call`], it preserves the active invocation's stacks and resumes the host caller after the nested call completes. Nested calls are currently blocking only. If the surrounding invocation is resumed with fuel or a time budget, th
(&mut self, func: &Function, args: &[WasmValue])
| 321 | /// is resumed with fuel or a time budget, this method does not suspend and |
| 322 | /// later continue the host function in the middle of the nested call. |
| 323 | pub fn call_untyped(&mut self, func: &Function, args: &[WasmValue]) -> Result<Vec<WasmValue>> { |
| 324 | if !self.store.execution_active { |
| 325 | return Err(Error::other("FuncContext::call requires an active host-function invocation")); |
| 326 | } |
| 327 | |
| 328 | func.item.validate_store(self.store)?; |
| 329 | validate_call_params(&func.ty, args)?; |
| 330 | |
| 331 | let func_instance = self.store.state.get_func(func.addr).clone(); |
| 332 | match func_instance { |
| 333 | FunctionInstance::Host(host_func) => { |
| 334 | host_func.call(FuncContext { store: &mut *self.store, module_addr: func.module_addr }, args) |
| 335 | } |
| 336 | FunctionInstance::Wasm(wasm_func) => { |
| 337 | let call_stack_base = self.store.call_stack.len(); |
| 338 | let value_stack_base = self.store.value_stack.base(); |
| 339 | |
| 340 | self.store.value_stack.extend_from_wasmvalues(args).inspect_err(|_| { |
| 341 | self.store.value_stack.truncate_to_base(value_stack_base); |
| 342 | })?; |
| 343 | |
| 344 | let locals_base = self |
| 345 | .store |
| 346 | .value_stack |
| 347 | .enter_locals(&wasm_func.func.params, &wasm_func.func.locals) |
| 348 | .inspect_err(|_| self.store.value_stack.truncate_to_base(value_stack_base))?; |
| 349 | |
| 350 | let callframe = CallFrame::new(func.addr, locals_base, wasm_func.func.locals); |
| 351 | InterpreterRuntime::exec(self.store, callframe, call_stack_base).inspect_err(|_| { |
| 352 | self.store.call_stack.truncate_to(call_stack_base); |
| 353 | self.store.value_stack.truncate_to_base(value_stack_base); |
| 354 | })?; |
| 355 | |
| 356 | collect_call_results(&mut self.store.value_stack, &func.ty) |
| 357 | } |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | /// Call a typed function from within the current host-function invocation. |
| 362 | /// |
no test coverage detected