feat(wasmer/js): preliminary de/serialize support

This commit is contained in:
OJ Kwon
2022-03-17 13:13:32 -07:00
parent 4528527b6e
commit 160d4ad008
4 changed files with 64 additions and 1 deletions

View File

@@ -154,5 +154,7 @@ js-default = ["js", "std", "wasm-types-polyfill"]
wasm-types-polyfill = ["js", "wasmparser"] wasm-types-polyfill = ["js", "wasmparser"]
js-serializable-module = []
[package.metadata.docs.rs] [package.metadata.docs.rs]
features = ["compiler", "core", "cranelift", "default-compiler", "default-dylib", "default-engine", "dylib", "engine", "jit", "native", "singlepass", "sys", "sys-default", "universal"] features = ["compiler", "core", "cranelift", "default-compiler", "default-dylib", "default-engine", "dylib", "engine", "jit", "native", "singlepass", "sys", "sys-default", "universal"]

View File

@@ -87,3 +87,40 @@ pub enum WasmError {
#[cfg_attr(feature = "std", error("{0}"))] #[cfg_attr(feature = "std", error("{0}"))]
Generic(String), Generic(String),
} }
/// The Serialize error can occur when serializing a
/// compiled Module into a binary.
/// Copied from wasmer_engine::SerializeError
#[derive(Debug)]
#[cfg_attr(feature = "std", derive(Error))]
pub enum SerializeError {
/// An IO error
#[cfg_attr(feature = "std", error(transparent))]
Io(#[from] std::io::Error),
/// A generic serialization error
#[cfg_attr(feature = "std", error("{0}"))]
Generic(String),
}
/// The Deserialize error can occur when loading a
/// compiled Module from a binary.
/// Copied from wasmer_engine::DeSerializeError
#[derive(Error, Debug)]
pub enum DeserializeError {
/// An IO error
#[cfg_attr(feature = "std", error(transparent))]
Io(#[from] std::io::Error),
/// A generic deserialization error
#[cfg_attr(feature = "std", error("{0}"))]
Generic(String),
/// Incompatible serialized binary
#[cfg_attr(feature = "std", error("incompatible binary: {0}"))]
Incompatible(String),
/// The provided binary is corrupted
#[cfg_attr(feature = "std", error("corrupted binary: {0}"))]
CorruptedBinary(String),
/// The binary was valid, but we got an error when
/// trying to allocate the required resources.
#[cfg_attr(feature = "std", error(transparent))]
Compiler(CompileError),
}

View File

@@ -51,6 +51,7 @@ pub use wasmer_derive::WasmerEnv;
pub use crate::js::cell::WasmCell; pub use crate::js::cell::WasmCell;
pub use crate::js::env::{HostEnvInitError, LazyInit, WasmerEnv}; pub use crate::js::env::{HostEnvInitError, LazyInit, WasmerEnv};
pub use crate::js::error::{DeserializeError, SerializeError};
pub use crate::js::export::Export; pub use crate::js::export::Export;
pub use crate::js::exports::{ExportError, Exportable, Exports, ExportsIterator}; pub use crate::js::exports::{ExportError, Exportable, Exports, ExportsIterator};
pub use crate::js::externals::{ pub use crate::js::externals::{

View File

@@ -3,7 +3,7 @@ use crate::js::resolver::Resolver;
use crate::js::store::Store; use crate::js::store::Store;
use crate::js::types::{ExportType, ImportType}; use crate::js::types::{ExportType, ImportType};
// use crate::js::InstantiationError; // use crate::js::InstantiationError;
use crate::js::error::CompileError; use crate::js::error::{CompileError, SerializeError, DeserializeError};
#[cfg(feature = "wat")] #[cfg(feature = "wat")]
use crate::js::error::WasmError; use crate::js::error::WasmError;
use crate::js::RuntimeError; use crate::js::RuntimeError;
@@ -62,6 +62,8 @@ pub struct Module {
name: Option<String>, name: Option<String>,
// WebAssembly type hints // WebAssembly type hints
type_hints: Option<ModuleTypeHints>, type_hints: Option<ModuleTypeHints>,
#[cfg(feature = "js-serializable-module")]
raw_bytes: Option<Vec<u8>>
} }
impl Module { impl Module {
@@ -194,6 +196,8 @@ impl Module {
module, module,
type_hints, type_hints,
name, name,
#[cfg(feature = "js-serializable-module")]
raw_bytes: Some(binary.to_vec())
}) })
} }
@@ -273,6 +277,23 @@ impl Module {
// self.artifact.module_ref().name.as_deref() // self.artifact.module_ref().name.as_deref()
} }
/// Serializes a module into a binary representation that the `Engine`
/// can later process via [`Module::deserialize`].
///
#[cfg(feature = "js-serializable-module")]
pub fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
self.raw_bytes.clone().ok_or(SerializeError::Generic("Not able to serialize module".to_string()))
}
/// Deserializes a serialized Module binary into a `Module`.
///
/// This is safe since deserialization under `js` is essentially same as reconstructing `Module`.
/// We maintain the `unsafe` to preserve the same API as Wasmer
#[cfg(feature = "js-serializable-module")]
pub unsafe fn deserialize(store: &Store, bytes: &[u8]) -> Result<Self, DeserializeError> {
Self::new(store, bytes).map_err(|e| DeserializeError::Compiler(e))
}
/// Sets the name of the current module. /// Sets the name of the current module.
/// This is normally useful for stacktraces and debugging. /// This is normally useful for stacktraces and debugging.
/// ///
@@ -512,6 +533,8 @@ impl From<WebAssembly::Module> for Module {
module, module,
name: None, name: None,
type_hints: None, type_hints: None,
#[cfg(feature = "js-serializable-module")]
raw_bytes: None
} }
} }
} }