Files
endorphin-aster-vm/crates/objects/src/error.rs
T

106 lines
3.6 KiB
Rust

use std::fmt;
/// Shared object/bytecode/execution errors. The established VmError name is
/// retained for embedders; defining it here avoids a dependency on the VM.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VmError {
ForeignHandle,
InvalidHandle,
IdentityExhausted,
RefCountOverflow,
NoOwnedReference,
AttributeNotFound(String),
UnsupportedOperation(&'static str),
InvalidArgument(&'static str),
ObjectKindMismatch(&'static str),
TraitViolation {
capability: String,
method: String,
reason: &'static str,
},
OverrideViolation {
definition: String,
method: String,
reason: &'static str,
},
UnknownAnnotation(String),
TypeMismatch {
function: String,
position: String,
expected: String,
actual: String,
},
EmptyCell,
InvalidBytecode {
offset: usize,
reason: &'static str,
},
UnboundLocal(String),
NameNotFound(String),
ArgumentCount {
name: String,
required: usize,
maximum: usize,
provided: usize,
},
ExecutionLimit(&'static str),
}
impl fmt::Display for VmError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::ForeignHandle => f.write_str("handle belongs to another VM"),
Self::InvalidHandle => f.write_str("handle does not identify a live object"),
Self::IdentityExhausted => f.write_str("process-local VM identities exhausted"),
Self::RefCountOverflow => f.write_str("object reference count exhausted"),
Self::NoOwnedReference => f.write_str("no external strong reference to release"),
Self::AttributeNotFound(name) => write!(f, "attribute not found: {name}"),
Self::UnsupportedOperation(operation) => {
write!(f, "object does not support {operation}")
}
Self::InvalidArgument(message) => f.write_str(message),
Self::ObjectKindMismatch(expected) => write!(f, "expected {expected} object"),
Self::TraitViolation {
capability,
method,
reason,
} => write!(f, "trait {capability} method {method}: {reason}"),
Self::UnknownAnnotation(name) => {
write!(f, "unknown or invalid type annotation: {name}")
}
Self::OverrideViolation {
definition,
method,
reason,
} => write!(f, "override {definition}.{method}: {reason}"),
Self::TypeMismatch {
function,
position,
expected,
actual,
} => write!(
f,
"{function} {position} expects {expected}, received {actual}"
),
Self::EmptyCell => f.write_str("cell is empty"),
Self::InvalidBytecode { offset, reason } => {
write!(f, "invalid bytecode at code unit {offset}: {reason}")
}
Self::UnboundLocal(name) => write!(f, "local variable is unbound: {name}"),
Self::NameNotFound(name) => write!(f, "name not found: {name}"),
Self::ArgumentCount {
name,
required,
maximum,
provided,
} => write!(
f,
"{name} expects {required}..={maximum} positional arguments, received {provided}"
),
Self::ExecutionLimit(limit) => write!(f, "execution limit reached: {limit}"),
}
}
}
impl std::error::Error for VmError {}