miden_processor/chiplets/memory/
errors.rs

1use alloc::sync::Arc;
2
3use miette::Diagnostic;
4use vm_core::{
5    Felt,
6    debuginfo::{SourceFile, SourceSpan},
7    mast::MastNodeExt,
8};
9
10use crate::{ContextId, errors::ErrorContext};
11
12#[derive(Debug, thiserror::Error, Diagnostic)]
13pub enum MemoryError {
14    #[error("memory address cannot exceed 2^32 but was {addr}")]
15    #[diagnostic()]
16    AddressOutOfBounds {
17        #[label]
18        label: SourceSpan,
19        #[source_code]
20        source_file: Option<Arc<SourceFile>>,
21        addr: u64,
22    },
23    #[error(
24        "memory address {addr} in context {ctx} was read and written, or written twice, in the same clock cycle {clk}"
25    )]
26    IllegalMemoryAccess { ctx: ContextId, addr: u32, clk: Felt },
27    #[error(
28        "memory range start address cannot exceed end address, but was ({start_addr}, {end_addr})"
29    )]
30    InvalidMemoryRange { start_addr: u64, end_addr: u64 },
31    #[error(
32        "word memory access at address {addr} in context {ctx} is unaligned at clock cycle {clk}"
33    )]
34    #[diagnostic(help(
35        "ensure that the memory address accessed is aligned to a word boundary (it is a multiple of 4)"
36    ))]
37    UnalignedWordAccess {
38        #[label("tried to access memory address {addr}")]
39        label: SourceSpan,
40        #[source_code]
41        source_file: Option<Arc<SourceFile>>,
42        addr: u32,
43        ctx: ContextId,
44        clk: Felt,
45    },
46    // Note: we need this version as well because to handle advice provider calls, which don't
47    // have access to the clock.
48    #[error("word access at memory address {addr} in context {ctx} is unaligned")]
49    UnalignedWordAccessNoClk { addr: u32, ctx: ContextId },
50}
51
52impl MemoryError {
53    pub fn unaligned_word_access(
54        addr: u32,
55        ctx: ContextId,
56        clk: Felt,
57        error_ctx: &ErrorContext<'_, impl MastNodeExt>,
58    ) -> Self {
59        let (label, source_file) = error_ctx.label_and_source_file();
60        MemoryError::UnalignedWordAccess { addr, ctx, clk, label, source_file }
61    }
62
63    pub fn address_out_of_bounds(
64        addr: u64,
65        error_ctx: &ErrorContext<'_, impl MastNodeExt>,
66    ) -> Self {
67        let (label, source_file) = error_ctx.label_and_source_file();
68        MemoryError::AddressOutOfBounds { label, source_file, addr }
69    }
70}