pub(crate) mod inner;
pub(crate) use inner::*;
use std::{fs, path::Path};
use bytes::Bytes;
use thiserror::Error;
#[cfg(feature = "wat")]
use wasmer_types::WasmError;
use wasmer_types::{
CompilationProgress, CompilationProgressCallback, CompileError, DeserializeError, ExportType,
ExportsIterator, ImportType, ImportsIterator, ModuleInfo, SerializeError, UserAbort,
};
use crate::{AsEngineRef, macros::backend::match_rt, utils::IntoBytes};
#[derive(Error, Debug)]
pub enum IoCompileError {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Compile(#[from] CompileError),
}
#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
#[derive(Clone, PartialEq, Eq, derive_more::From)]
pub struct Module(pub(crate) BackendModule);
impl Module {
pub fn new(engine: &impl AsEngineRef, bytes: impl AsRef<[u8]>) -> Result<Self, CompileError> {
BackendModule::new(engine, bytes).map(Self)
}
pub fn from_file(
engine: &impl AsEngineRef,
file: impl AsRef<Path>,
) -> Result<Self, IoCompileError> {
BackendModule::from_file(engine, file).map(Self)
}
pub fn from_binary(engine: &impl AsEngineRef, binary: &[u8]) -> Result<Self, CompileError> {
BackendModule::from_binary(engine, binary).map(Self)
}
pub unsafe fn from_binary_unchecked(
engine: &impl AsEngineRef,
binary: &[u8],
) -> Result<Self, CompileError> {
unsafe { BackendModule::from_binary_unchecked(engine, binary) }.map(Self)
}
pub fn validate(engine: &impl AsEngineRef, binary: &[u8]) -> Result<(), CompileError> {
BackendModule::validate(engine, binary)?;
Ok(())
}
pub fn serialize(&self) -> Result<Bytes, SerializeError> {
self.0.serialize()
}
pub fn serialize_to_file(&self, path: impl AsRef<Path>) -> Result<(), SerializeError> {
let serialized = self.serialize()?;
fs::write(path, serialized)?;
Ok(())
}
pub unsafe fn deserialize_unchecked(
engine: &impl AsEngineRef,
bytes: impl IntoBytes,
) -> Result<Self, DeserializeError> {
unsafe { BackendModule::deserialize_unchecked(engine, bytes) }.map(Self)
}
pub unsafe fn deserialize(
engine: &impl AsEngineRef,
bytes: impl IntoBytes,
) -> Result<Self, DeserializeError> {
unsafe { BackendModule::deserialize_unchecked(engine, bytes) }.map(Self)
}
pub unsafe fn deserialize_from_file(
engine: &impl AsEngineRef,
path: impl AsRef<Path>,
) -> Result<Self, DeserializeError> {
unsafe { BackendModule::deserialize_from_file(engine, path) }.map(Self)
}
pub unsafe fn deserialize_from_file_unchecked(
engine: &impl AsEngineRef,
path: impl AsRef<Path>,
) -> Result<Self, DeserializeError> {
unsafe { BackendModule::deserialize_from_file_unchecked(engine, path) }.map(Self)
}
pub fn name(&self) -> Option<&str> {
self.0.name()
}
pub fn set_name(&mut self, name: &str) -> bool {
self.0.set_name(name)
}
pub fn imports(&self) -> ImportsIterator<Box<dyn Iterator<Item = ImportType> + '_>> {
self.0.imports()
}
pub fn exports(&self) -> ExportsIterator<Box<dyn Iterator<Item = ExportType> + '_>> {
self.0.exports()
}
pub fn custom_sections<'a>(&'a self, name: &'a str) -> impl Iterator<Item = Box<[u8]>> + 'a {
self.0.custom_sections(name)
}
#[doc(hidden)]
pub fn info(&self) -> &ModuleInfo {
self.0.info()
}
}
impl std::fmt::Debug for Module {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Module")
.field("name", &self.name())
.finish()
}
}
#[cfg(feature = "js")]
impl From<Module> for wasm_bindgen::JsValue {
fn from(value: Module) -> Self {
match value.0 {
BackendModule::Js(module) => Self::from(module),
_ => unreachable!(),
}
}
}