use super::*;
use crate::syscalls::*;
#[instrument(level = "trace", skip_all, ret)]
pub fn stack_restore<M: MemorySize>(
mut ctx: FunctionEnvMut<'_, WasiEnv>,
snapshot_ptr: WasmPtr<StackSnapshot, M>,
mut val: Longsize,
) -> Result<(), WasiError> {
let env = ctx.data();
let memory = unsafe { env.memory_view(&ctx) };
let snapshot = match snapshot_ptr.read(&memory) {
Ok(a) => {
trace!("with_ret={}, hash={}, user={}", val, a.hash(), a.user);
a
}
Err(err) => {
warn!("failed to read stack snapshot - {}", err);
return Err(WasiError::Exit(mem_error_to_wasi(err).into()));
}
};
unwind::<M, _>(ctx, move |mut ctx, _, _| {
let env = ctx.data();
if let Some((mut memory_stack, rewind_stack, store_data)) =
env.thread.get_snapshot(snapshot.hash())
{
let env = ctx.data();
let memory = unsafe { env.memory_view(&ctx) };
let pid = ctx.data().pid();
let tid = ctx.data().tid();
let rewind_result = bincode::serialize(&val).unwrap().into();
let ret = rewind_ext::<M>(
&mut ctx,
None, rewind_stack,
store_data,
RewindResultType::RewindWithResult(rewind_result),
);
match ret {
Errno::Success => OnCalledAction::InvokeAgain,
err => {
warn!("failed to rewind the stack - errno={}", err);
OnCalledAction::Trap(Box::new(WasiError::Exit(err.into())))
}
}
} else {
warn!(
"snapshot stack restore failed - the snapshot can not be found and hence restored (hash={})",
snapshot.hash()
);
OnCalledAction::Trap(Box::new(WasiError::Exit(Errno::Unknown.into())))
}
});
Ok(())
}