Resume execution with up to `fuel` units of fuel. Fuel is accounted in chunks, so execution may overshoot the requested fuel before returning [`ExecProgress::Suspended`] (currently the chunk size is 128 instructions between fuel checks, but this may change in the future). Returns [`ExecProgress::Suspended`] when fuel is exhausted, or [`ExecProgress::Completed`] with the final values once the inv
(&mut self, fuel: u32)
| 433 | /// currently blocking. They do not suspend and later resume the host |
| 434 | /// function in the middle of the nested call. |
| 435 | pub fn resume_with_fuel(&mut self, fuel: u32) -> Result<ExecProgress<Vec<WasmValue>>> { |
| 436 | let FuncExecutionState::Running { exec_state, root_func_addr } = &mut self.state else { |
| 437 | let FuncExecutionState::Completed { result } = &mut self.state else { |
| 438 | unreachable!("invalid function execution state") |
| 439 | }; |
| 440 | return match result.take() { |
| 441 | Some(res) => Ok(ExecProgress::Completed(res)), |
| 442 | None => Err(Error::other("execution already completed")), |
| 443 | }; |
| 444 | }; |
| 445 | |
| 446 | self.store.enter_execution()?; |
| 447 | let result = InterpreterRuntime::exec_with_fuel(self.store, exec_state.callframe, fuel); |
| 448 | self.store.exit_execution(); |
| 449 | |
| 450 | match result? { |
| 451 | crate::interpreter::ExecState::Completed => { |
| 452 | let result_ty = self.store.state.get_func(*root_func_addr).ty().clone(); |
| 453 | self.state = FuncExecutionState::Completed { result: None }; |
| 454 | Ok(ExecProgress::Completed(collect_call_results(&mut self.store.value_stack, &result_ty)?)) |
| 455 | } |
| 456 | crate::interpreter::ExecState::Suspended(callframe) => { |
| 457 | exec_state.callframe = callframe; |
| 458 | Ok(ExecProgress::Suspended) |
| 459 | } |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | #[cfg(feature = "std")] |
| 464 | /// Resume execution for at most `time_budget` wall-clock time. |