sp1_core_executor/syscalls/
context.rsuse hashbrown::HashMap;
use crate::{
events::{LookupId, MemoryLocalEvent, MemoryReadRecord, MemoryWriteRecord},
record::ExecutionRecord,
Executor, Register,
};
#[allow(dead_code)]
pub struct SyscallContext<'a, 'b: 'a> {
pub current_shard: u32,
pub clk: u32,
pub next_pc: u32,
pub exit_code: u32,
pub rt: &'a mut Executor<'b>,
pub syscall_lookup_id: LookupId,
pub local_memory_access: HashMap<u32, MemoryLocalEvent>,
}
impl<'a, 'b> SyscallContext<'a, 'b> {
pub fn new(runtime: &'a mut Executor<'b>) -> Self {
let current_shard = runtime.shard();
let clk = runtime.state.clk;
Self {
current_shard,
clk,
next_pc: runtime.state.pc.wrapping_add(4),
exit_code: 0,
rt: runtime,
syscall_lookup_id: LookupId::default(),
local_memory_access: HashMap::new(),
}
}
pub fn record_mut(&mut self) -> &mut ExecutionRecord {
&mut self.rt.record
}
#[must_use]
pub fn current_shard(&self) -> u32 {
self.rt.state.current_shard
}
pub fn mr(&mut self, addr: u32) -> (MemoryReadRecord, u32) {
let record =
self.rt.mr(addr, self.current_shard, self.clk, Some(&mut self.local_memory_access));
(record, record.value)
}
pub fn mr_slice(&mut self, addr: u32, len: usize) -> (Vec<MemoryReadRecord>, Vec<u32>) {
let mut records = Vec::new();
let mut values = Vec::new();
for i in 0..len {
let (record, value) = self.mr(addr + i as u32 * 4);
records.push(record);
values.push(value);
}
(records, values)
}
pub fn mw(&mut self, addr: u32, value: u32) -> MemoryWriteRecord {
self.rt.mw(addr, value, self.current_shard, self.clk, Some(&mut self.local_memory_access))
}
pub fn mw_slice(&mut self, addr: u32, values: &[u32]) -> Vec<MemoryWriteRecord> {
let mut records = Vec::new();
for i in 0..values.len() {
let record = self.mw(addr + i as u32 * 4, values[i]);
records.push(record);
}
records
}
pub fn postprocess(&mut self) -> Vec<MemoryLocalEvent> {
let mut syscall_local_mem_events = Vec::new();
if !self.rt.unconstrained {
for (addr, event) in self.local_memory_access.drain() {
let local_mem_access = self.rt.local_memory_access.remove(&addr);
if let Some(local_mem_access) = local_mem_access {
self.rt.record.cpu_local_memory_access.push(local_mem_access);
}
syscall_local_mem_events.push(event);
}
}
syscall_local_mem_events
}
#[must_use]
pub fn register_unsafe(&mut self, register: Register) -> u32 {
self.rt.register(register)
}
#[must_use]
pub fn byte_unsafe(&mut self, addr: u32) -> u8 {
self.rt.byte(addr)
}
#[must_use]
pub fn word_unsafe(&mut self, addr: u32) -> u32 {
self.rt.word(addr)
}
#[must_use]
pub fn slice_unsafe(&mut self, addr: u32, len: usize) -> Vec<u32> {
let mut values = Vec::new();
for i in 0..len {
values.push(self.rt.word(addr + i as u32 * 4));
}
values
}
pub fn set_next_pc(&mut self, next_pc: u32) {
self.next_pc = next_pc;
}
pub fn set_exit_code(&mut self, exit_code: u32) {
self.exit_code = exit_code;
}
}