use crate::instance::{FaultDetails, TerminationDetails};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error("Invalid argument: {0}")]
InvalidArgument(&'static str),
#[error("Region capacity reached: {0} instances")]
RegionFull(usize),
#[error("Module error: {0}")]
ModuleError(ModuleError),
#[error("Instance limits exceeded: {0}")]
LimitsExceeded(String),
#[error("No linear memory available: {0}")]
NoLinearMemory(String),
#[error("Symbol not found: {0}")]
SymbolNotFound(String),
#[error("Function not found: (table {0}, func {1}")]
FuncNotFound(u32, u32),
#[error("Runtime fault: {0:?}")]
RuntimeFault(FaultDetails),
#[error("Runtime terminated")]
RuntimeTerminated(TerminationDetails),
#[error("Dynamic loading error: {0}")]
DlError(#[from] std::io::Error),
#[error("Instance not returned")]
InstanceNotReturned,
#[error("Instance not yielded")]
InstanceNotYielded,
#[error("Start function yielded")]
StartYielded,
#[error("Internal error")]
InternalError(#[source] anyhow::Error),
#[error("Unsupported feature: {0}")]
Unsupported(String),
}
impl From<crate::context::Error> for Error {
fn from(e: crate::context::Error) -> Error {
Error::InternalError(e.into())
}
}
impl From<nix::Error> for Error {
fn from(e: nix::Error) -> Error {
Error::InternalError(e.into())
}
}
impl From<std::ffi::IntoStringError> for Error {
fn from(e: std::ffi::IntoStringError) -> Error {
Error::InternalError(e.into())
}
}
impl From<lucet_module::Error> for Error {
fn from(e: lucet_module::Error) -> Error {
Error::ModuleError(ModuleError::ModuleDataError(e))
}
}
#[derive(Debug, Error)]
pub enum ModuleError {
#[error("Incorrect module definition: {0}")]
IncorrectModule(String),
#[error("Module data error: {0}")]
ModuleDataError(#[from] lucet_module::Error),
}
#[macro_export]
macro_rules! lucet_bail {
($e:expr) => {
return Err(lucet_format_err!($e));
};
($fmt:expr, $($arg:tt)*) => {
return Err(lucet_format_err!($fmt, $($arg)*));
};
}
#[macro_export(local_inner_macros)]
macro_rules! lucet_ensure {
($cond:expr, $e:expr) => {
if !($cond) {
lucet_bail!($e);
}
};
($cond:expr, $fmt:expr, $($arg:tt)*) => {
if !($cond) {
lucet_bail!($fmt, $($arg)*);
}
};
}
#[macro_export]
macro_rules! lucet_format_err {
($($arg:tt)*) => { $crate::error::Error::InternalError(anyhow::format_err!($($arg)*)) }
}
#[macro_export]
macro_rules! lucet_incorrect_module {
($($arg:tt)*) => {
$crate::error::Error::ModuleError(
$crate::error::ModuleError::IncorrectModule(format!($($arg)*))
)
}
}
#[macro_export]
macro_rules! bail_limits_exceeded {
($($arg:tt)*) => { return Err($crate::error::Error::LimitsExceeded(format!($($arg)*))); }
}