use crate::instance::{FaultDetails, TerminationDetails};
use failure::Fail;
#[derive(Debug, Fail)]
pub enum Error {
#[fail(display = "Invalid argument: {}", _0)]
InvalidArgument(&'static str),
#[fail(display = "Region capacity reached: {} instances", _0)]
RegionFull(usize),
#[fail(display = "Module error: {}", _0)]
ModuleError(ModuleError),
#[fail(display = "Instance limits exceeded: {}", _0)]
LimitsExceeded(String),
#[fail(display = "No linear memory available: {}", _0)]
NoLinearMemory(String),
#[fail(display = "Symbol not found: {}", _0)]
SymbolNotFound(String),
#[fail(display = "Function not found: (table {}, func {})", _0, _1)]
FuncNotFound(u32, u32),
#[fail(display = "Runtime fault: {:?}", _0)]
RuntimeFault(FaultDetails),
#[fail(display = "Runtime terminated")]
RuntimeTerminated(TerminationDetails),
#[fail(display = "Dynamic loading error: {}", _0)]
DlError(#[cause] std::io::Error),
#[fail(display = "Instance not returned")]
InstanceNotReturned,
#[fail(display = "Instance not yielded")]
InstanceNotYielded,
#[fail(display = "Start function yielded")]
StartYielded,
#[fail(display = "Internal error: {}", _0)]
InternalError(#[cause] failure::Error),
#[fail(display = "Unsupported feature: {}", _0)]
Unsupported(String),
}
impl From<failure::Error> for Error {
fn from(e: failure::Error) -> Error {
Error::InternalError(e)
}
}
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, Fail)]
pub enum ModuleError {
#[fail(display = "Incorrect module definition: {}", _0)]
IncorrectModule(String),
#[fail(display = "Module data error: {}", _0)]
ModuleDataError(#[cause] 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(failure::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)*))); }
}