diff --git a/crates/verifier/Cargo.toml b/crates/verifier/Cargo.toml index d532a7b1..0122308e 100644 --- a/crates/verifier/Cargo.toml +++ b/crates/verifier/Cargo.toml @@ -17,3 +17,5 @@ keywords = ["compiler", "evm", "wasm", "smart-contract"] [dependencies] sonatina-ir = { path = "../ir", version = "0.0.3-alpha" } cranelift-entity = "0.112" +rustc-hash = "2.0.0" +smallvec = "1.13.2" diff --git a/crates/verifier/src/error/kind.rs b/crates/verifier/src/error/kind.rs index deb52bd4..58c45999 100644 --- a/crates/verifier/src/error/kind.rs +++ b/crates/verifier/src/error/kind.rs @@ -3,7 +3,7 @@ use std::fmt; use sonatina_ir::{ insn::DisplayInsn, module::FuncRef, - types::{CompoundType, DisplayCompoundType, DisplayType}, + types::{DisplayCompoundType, DisplayType}, value::DisplayArgValue, Block, Function, Insn, Type, Value, }; @@ -22,7 +22,6 @@ pub enum ErrorKind { ValueIsNullReference(Value), BlockIsNullReference(Block), FunctionIsNullReference(FuncRef), - CompoundTypeIsNullReference(CompoundType), BranchToEntryBlock(Block), // SSA form errors ValueLeak(Value), @@ -31,6 +30,31 @@ pub enum ErrorKind { InsnResultWrongType(Type), CalleeArgWrongType(Type), CalleeResultWrongType(Type), + CompoundTypeIsNullReference(Type), +} + +impl ErrorKind { + pub fn ir_source(&self) -> IrSource { + use ErrorKind::*; + + match *self { + PhiInEntryBlock(i) => IrSource::Insn(i), + EmptyBlock(b) => IrSource::Block(b), + TerminatorBeforeEnd(i) + | NotEndedByTerminator(i) + | InstructionMapMismatched(i) + | BranchBrokenLink(i) => IrSource::Insn(i), + ValueIsNullReference(v) => IrSource::Value(v), + BlockIsNullReference(b) | BranchToEntryBlock(b) => IrSource::Block(b), + FunctionIsNullReference(f) => IrSource::Callee(f), + ValueLeak(v) => IrSource::Value(v), + InsnArgWrongType(ty) + | InsnResultWrongType(ty) + | CalleeArgWrongType(ty) + | CalleeResultWrongType(ty) + | CompoundTypeIsNullReference(ty) => IrSource::Type(ty), + } + } } pub struct DisplayErrorKind<'a> { @@ -83,7 +107,10 @@ impl<'a> fmt::Display for DisplayErrorKind<'a> { "instruction references inexistent function, opaque ref: {func_ref:?}" ) } - CompoundTypeIsNullReference(cmpd_ty) => { + CompoundTypeIsNullReference(ty) => { + let Type::Compound(cmpd_ty) = ty else { + unreachable!("badly formed error"); + }; let cmpd_ty = DisplayCompoundType::new(cmpd_ty, &func.dfg); write!(f, "instruction references inexistent value, {cmpd_ty}") } @@ -114,3 +141,12 @@ impl<'a> fmt::Display for DisplayErrorKind<'a> { } } } + +#[derive(Debug, Clone, Copy)] +pub enum IrSource { + Callee(FuncRef), + Block(Block), + Insn(Insn), + Value(Value), + Type(Type), +} diff --git a/crates/verifier/src/error/mod.rs b/crates/verifier/src/error/mod.rs index 8cb1fe25..1f8935cd 100644 --- a/crates/verifier/src/error/mod.rs +++ b/crates/verifier/src/error/mod.rs @@ -1,21 +1,26 @@ -mod kind; +pub mod kind; + mod trace_info; pub use kind::ErrorKind; pub use trace_info::{TraceInfo, TraceInfoBuilder}; +use kind::DisplayErrorKind; use trace_info::DisplayTraceInfo; use std::{error, fmt}; +use cranelift_entity::entity_impl; use sonatina_ir::Function; -use crate::error::kind::DisplayErrorKind; +#[derive(Clone, Copy, PartialEq, Eq)] +pub struct ErrorRef(u32); +entity_impl!(ErrorRef, "err"); /// Verifier error. #[derive(Debug, Clone, Copy)] pub struct ErrorData { - kind: ErrorKind, + pub kind: ErrorKind, trace_info: TraceInfo, } diff --git a/crates/verifier/src/error_stack.rs b/crates/verifier/src/error_stack.rs new file mode 100644 index 00000000..a9ef2d5a --- /dev/null +++ b/crates/verifier/src/error_stack.rs @@ -0,0 +1,21 @@ +use cranelift_entity::PrimaryMap; +use sonatina_ir::Function; + +use crate::error::{Error, ErrorData, ErrorRef}; + +#[derive(Debug, Default)] +pub struct ErrorStack { + pub errors: PrimaryMap, +} + +impl ErrorStack { + pub fn push(&mut self, err: ErrorData) -> ErrorRef { + self.errors.push(err) + } + + pub fn into_errs_iter(self, func: &Function) -> impl IntoIterator> { + self.errors + .into_iter() + .map(|(_, err)| Error::new(err, func)) + } +} diff --git a/crates/verifier/src/lib.rs b/crates/verifier/src/lib.rs index a91e7351..d32fd422 100644 --- a/crates/verifier/src/lib.rs +++ b/crates/verifier/src/lib.rs @@ -1 +1,2 @@ pub mod error; +pub mod error_stack;