use std::fmt;
use std::sync::Arc;
use crate::executor::LoadModuleError;
use crate::schema::module::low::Header;
#[derive(Clone)]
pub struct CompiledModule {
pub(crate) header: Header,
pub(crate) code: Code,
}
#[derive(Clone)]
pub(crate) enum Code {
#[cfg(all(feature = "wasmtime-host", not(target_arch = "wasm32")))]
Wasmtime(wasmtime::Module),
#[cfg(target_arch = "wasm32")]
Browser(js_sys::WebAssembly::Module),
Executable(Arc<[u8]>),
}
impl CompiledModule {
pub fn new(header: Header, executable: &[u8]) -> Result<Self, LoadModuleError> {
let code = if header.executor.name == WASM_EXECUTOR {
compile_wasm(executable)?
} else {
Code::Executable(executable.into())
};
Ok(Self { header, code })
}
pub fn header(&self) -> &Header {
&self.header
}
}
impl fmt::Debug for CompiledModule {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("CompiledModule")
.field("header", &self.header)
.finish_non_exhaustive()
}
}
const WASM_EXECUTOR: &str = "wasm";
#[cfg(all(feature = "wasmtime-host", not(target_arch = "wasm32")))]
fn compile_wasm(executable: &[u8]) -> Result<Code, LoadModuleError> {
crate::executor::wasm::compile(executable).map(Code::Wasmtime)
}
#[cfg(target_arch = "wasm32")]
fn compile_wasm(executable: &[u8]) -> Result<Code, LoadModuleError> {
crate::executor::browser::compile(executable).map(Code::Browser)
}
#[cfg(not(any(feature = "wasmtime-host", target_arch = "wasm32")))]
fn compile_wasm(executable: &[u8]) -> Result<Code, LoadModuleError> {
Ok(Code::Executable(executable.into()))
}
#[cfg(all(test, not(target_arch = "wasm32")))]
mod tests {
use super::*;
#[test]
fn is_send_and_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<CompiledModule>();
}
}