use super::*;
impl<'a, 'c> JournalSyscallPlayer<'a, 'c> {
#[allow(clippy::result_large_err)]
pub(crate) unsafe fn action_set_thread(
&mut self,
id: u32,
call_stack: Cow<'a, [u8]>,
memory_stack: Cow<'a, [u8]>,
store_data: Cow<'a, [u8]>,
is_64bit: bool,
start: ThreadStartType,
layout: WasiMemoryLayout,
differ_ethereal: Option<&mut Vec<JournalEntry<'a>>>,
) -> Result<(), WasiRuntimeError> {
if Some(&self.cur_module_hash) != self.journal_module_hash.as_ref() {
tracing::trace!(%id, "Skipping journal entry - SetThread call_stack={} bytes memory_stack={} bytes store_data={} bytes", call_stack.len(), memory_stack.len(), store_data.len());
return Ok(());
}
let state = RewindState {
memory_stack: memory_stack.to_vec().into(),
rewind_stack: call_stack.to_vec().into(),
store_data: store_data.to_vec().into(),
start,
layout: layout.clone(),
is_64bit,
};
if Into::<WasiThreadId>::into(id) == self.ctx.data().tid() {
tracing::trace!(%id, "Differ(end) journal - SetThread(main) call_stack={} bytes memory_stack={} bytes store_data={} bytes", call_stack.len(), memory_stack.len(), store_data.len());
self.rewind.replace(state);
} else if let Some(differ_ethereal) = differ_ethereal {
tracing::trace!(%id, "Differ(ether) journal - SetThread call_stack={} bytes memory_stack={} bytes store_data={} bytes", call_stack.len(), memory_stack.len(), store_data.len());
differ_ethereal.push(JournalEntry::SetThreadV1 {
id,
call_stack,
memory_stack,
store_data,
start,
layout,
is_64bit,
});
} else if self.bootstrapping {
tracing::trace!(%id, "Differ(end) journal - SetThread({id}) call_stack={} bytes memory_stack={} bytes store_data={} bytes", call_stack.len(), memory_stack.len(), store_data.len());
self.spawn_threads.insert(id.into(), state);
} else {
return Err(WasiRuntimeError::Runtime(RuntimeError::user(
anyhow::format_err!(
"Snapshot restoration does not currently support live updates of running threads."
)
.into(),
)));
}
Ok(())
}
}