Skip to content

Commit

Permalink
improvement: convert anyhow to thiserror errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Wodann committed May 14, 2023
1 parent dacb609 commit d9232b5
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 126 deletions.
1 change: 1 addition & 0 deletions crates/mun_libloader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ mun_abi = { version = "0.4.0", path = "../mun_abi" }
anyhow = { version = "1.0", default-features = false, features = ["std"] }
libloading = { version = "0.7", default-features = false }
tempfile = { version = "3", default-features = false }
thiserror = { version = "1.0.38", default-features = false }
29 changes: 24 additions & 5 deletions crates/mun_libloader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ pub use temp_library::TempLibrary;

mod temp_library;

/// An error that occurs upon construction of a [`MunLibrary`].
#[derive(Debug, thiserror::Error)]
pub enum InitError {
#[error(transparent)]
FailedToCreateTempLibrary(#[from] temp_library::InitError),
#[error("Missing symbol for retrieving ABI version: {0}")]
MissingGetAbiVersionFn(libloading::Error),
#[error("Missing symbol for retrieving ABI information: {0}")]
MissingGetInfoFn(libloading::Error),
#[error("Missing symbol for setting allocator handle: {0}")]
MissingSetAllocatorHandleFn(libloading::Error),
}

pub struct MunLibrary(TempLibrary);

impl MunLibrary {
Expand All @@ -22,23 +35,29 @@ impl MunLibrary {
/// executed when the library is unloaded.
///
/// See [`libloading::Library::new`] for more information.
pub unsafe fn new(library_path: &Path) -> Result<Self, anyhow::Error> {
pub unsafe fn new(library_path: &Path) -> Result<Self, InitError> {
// Although loading a library is technically unsafe, we assume here that this is not the
// case for munlibs.
let library = TempLibrary::new(library_path)?;

// Verify that the `*.munlib` contains all required functions. Note that this is an unsafe
// operation because the loaded symbols don't actually contain type information. Casting
// is therefore unsafe.
let _get_abi_version_fn: libloading::Symbol<'_, extern "C" fn() -> u32> =
library.library().get(abi::GET_VERSION_FN_NAME.as_bytes())?;
let _get_abi_version_fn: libloading::Symbol<'_, extern "C" fn() -> u32> = library
.library()
.get(abi::GET_VERSION_FN_NAME.as_bytes())
.map_err(InitError::MissingGetAbiVersionFn)?;

let _get_info_fn: libloading::Symbol<'_, extern "C" fn() -> abi::AssemblyInfo<'static>> =
library.library().get(abi::GET_INFO_FN_NAME.as_bytes())?;
library
.library()
.get(abi::GET_INFO_FN_NAME.as_bytes())
.map_err(InitError::MissingGetInfoFn)?;

let _set_allocator_handle_fn: libloading::Symbol<'_, extern "C" fn(*mut c_void)> = library
.library()
.get(abi::SET_ALLOCATOR_HANDLE_FN_NAME.as_bytes())?;
.get(abi::SET_ALLOCATOR_HANDLE_FN_NAME.as_bytes())
.map_err(InitError::MissingSetAllocatorHandleFn)?;

Ok(MunLibrary(library))
}
Expand Down
23 changes: 17 additions & 6 deletions crates/mun_libloader/src/temp_library.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
use std::fs;
use std::path::Path;
use std::{fs, io, path::Path};

use anyhow::Error;
use libloading::Library;

/// An error that occurs upon construction of a [`TempLibrary`].
#[derive(Debug, thiserror::Error)]
pub enum InitError {
#[error("Failed to create a named temp file: {0}.")]
CreateTempFile(io::Error),
#[error("Failed to copy shared library: {0}.")]
CopyLibrary(io::Error),
#[error("Failed to load temp shared library: {0}")]
LoadTempLibrary(#[from] libloading::Error),
}

/// A structure that holds a `Library` instance but creates a unique file per load. This enables
/// writing to the original library and ensures that each shared object on Linux is loaded
/// separately.
Expand Down Expand Up @@ -36,9 +45,11 @@ impl TempLibrary {
/// executed when the library is unloaded.
///
/// See [`libloading::Library::new`] for more information.
pub unsafe fn new(path: &Path) -> Result<Self, Error> {
let tmp_path = tempfile::NamedTempFile::new()?.into_temp_path();
fs::copy(path, &tmp_path)?;
pub unsafe fn new(path: &Path) -> Result<Self, InitError> {
let tmp_path = tempfile::NamedTempFile::new()
.map_err(InitError::CreateTempFile)?
.into_temp_path();
fs::copy(path, &tmp_path).map_err(InitError::CopyLibrary)?;
let library = Library::new(&tmp_path)?;
Ok(TempLibrary {
_tmp_path: tmp_path,
Expand Down
3 changes: 1 addition & 2 deletions crates/mun_memory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ pub mod mapping;
mod r#type;
pub mod type_table;
use mun_abi as abi;
use thiserror::Error;

pub mod prelude {
pub use crate::diff::{compute_struct_diff, FieldDiff, FieldEditKind, StructDiff};
Expand All @@ -25,7 +24,7 @@ pub mod prelude {
}

/// An error that can occur when trying to convert from an abi type to an internal type.
#[derive(Debug, Error)]
#[derive(Debug, thiserror::Error)]
pub enum TryFromAbiError<'a> {
#[error("unknown TypeId '{0}'")]
UnknownTypeId(abi::TypeId<'a>),
Expand Down
2 changes: 1 addition & 1 deletion crates/mun_memory/src/type/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,7 @@ impl Type {
}

/// Tries to convert multiple [`abi::TypeDefinition`] to internal type representations. If
/// the conversion succeeds an updated [`TypeTable`] is returned
/// the conversion succeeds an updated [`TypeTable`] is returned.
pub fn try_from_abi<'abi>(
type_info: impl IntoIterator<Item = &'abi abi::TypeDefinition<'abi>>,
type_table: TypeTable,
Expand Down
2 changes: 1 addition & 1 deletion crates/mun_runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ mun_libloader = { version = "0.4.0", path = "../mun_libloader" }
mun_capi_utils = { version = "0.4.0", path = "../mun_capi_utils"}
mun_memory = { version = "0.4.0", path = "../mun_memory" }
mun_project = { version = "0.4.0", path = "../mun_project" }
anyhow = { version = "1.0", default-features = false }
itertools = { version = "0.10.3", default-features = false, features = ["use_alloc"] }
log = { version = "0.4", default-features = false }
notify = "5.0.0"
once_cell = { version = "1.4.0", default-features = false }
parking_lot = { version = "0.12.0", default-features = false }
rustc-hash = { version = "1.1", default-features = false }
seq-macro = { version = "0.3.0", default-features = false }
thiserror = { version = "1.0.38", default-features = false }

[dev-dependencies]
mun_compiler = { path="../mun_compiler" }
Expand Down
Loading

0 comments on commit d9232b5

Please sign in to comment.