risc0_circuit_rv32im/execute/
segment.rs1use std::cell::Cell;
16
17use anyhow::Result;
18use derive_more::Debug;
19use risc0_binfmt::MemoryImage;
20use serde::{Deserialize, Serialize};
21
22use crate::{
23 execute::{testutil, Executor},
24 Rv32imV2Claim, MAX_INSN_CYCLES,
25};
26
27use super::{Syscall, SyscallContext};
28
29#[derive(Clone, Debug, Serialize, Deserialize)]
30#[non_exhaustive]
31pub struct Segment {
32 pub partial_image: MemoryImage,
34
35 pub claim: Rv32imV2Claim,
36
37 #[debug("{}", read_record.len())]
39 pub read_record: Vec<Vec<u8>>,
40
41 #[debug("{}", write_record.len())]
43 pub write_record: Vec<u32>,
44
45 pub suspend_cycle: u32,
47
48 pub paging_cycles: u32,
50
51 pub segment_threshold: u32,
52
53 pub po2: u32,
54
55 pub index: u64,
56}
57
58impl Segment {
59 pub fn encode(&self) -> Result<Vec<u8>> {
60 Ok(postcard::to_stdvec(self)?)
61 }
62
63 pub fn decode(bytes: &[u8]) -> Result<Self> {
64 Ok(postcard::from_bytes(bytes)?)
65 }
66
67 pub fn execute(&self) -> Result<()> {
68 let handler = SegmentSyscallHandler {
69 segment: self,
70 read_pos: Cell::new(0),
71 write_pos: Cell::new(0),
72 };
73 Executor::new(self.partial_image.clone(), &handler, None, vec![]).run(
74 self.po2 as usize,
75 MAX_INSN_CYCLES,
76 testutil::DEFAULT_SESSION_LIMIT,
77 |_| Ok(()),
78 )?;
79 Ok(())
80 }
81}
82
83struct SegmentSyscallHandler<'a> {
84 segment: &'a Segment,
85 read_pos: Cell<usize>,
86 write_pos: Cell<usize>,
87}
88
89impl Syscall for SegmentSyscallHandler<'_> {
90 fn host_read(&self, _ctx: &mut dyn SyscallContext, _fd: u32, buf: &mut [u8]) -> Result<u32> {
91 let pos = self.read_pos.replace(self.read_pos.get() + 1);
92 let read_record = &self.segment.read_record[pos];
93 buf.copy_from_slice(read_record);
94 Ok(read_record.len() as u32)
95 }
96
97 fn host_write(&self, _ctx: &mut dyn SyscallContext, _fd: u32, _buf: &[u8]) -> Result<u32> {
98 let pos = self.write_pos.replace(self.read_pos.get() + 1);
99 Ok(self.segment.write_record[pos])
100 }
101}