mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-14 01:21:19 +00:00
Add documentation and make load safe
This commit is contained in:
@ -29,16 +29,34 @@ pub enum Error {
|
|||||||
InvalidatedCache,
|
InvalidatedCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for Error {
|
||||||
|
fn from(io_err: io::Error) -> Self {
|
||||||
|
Error::IoError(io_err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The hash of a wasm module.
|
||||||
|
///
|
||||||
|
/// Used as a key when loading and storing modules in a [`Cache`].
|
||||||
|
///
|
||||||
|
/// [`Cache`]: trait.Cache.html
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub struct WasmHash([u8; 32]);
|
pub struct WasmHash([u8; 32]);
|
||||||
|
|
||||||
impl WasmHash {
|
impl WasmHash {
|
||||||
|
/// Hash a wasm module.
|
||||||
|
///
|
||||||
|
/// # Note:
|
||||||
|
/// This does no verification that the supplied data
|
||||||
|
/// is, in fact, a wasm module.
|
||||||
pub fn generate(wasm: &[u8]) -> Self {
|
pub fn generate(wasm: &[u8]) -> Self {
|
||||||
let mut array = [0u8; 32];
|
let mut array = [0u8; 32];
|
||||||
array.copy_from_slice(Sha256::digest(wasm).as_slice());
|
array.copy_from_slice(Sha256::digest(wasm).as_slice());
|
||||||
WasmHash(array)
|
WasmHash(array)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create the hexadecimal representation of the
|
||||||
|
/// stored hash.
|
||||||
pub fn encode(self) -> String {
|
pub fn encode(self) -> String {
|
||||||
hex::encode(self.0)
|
hex::encode(self.0)
|
||||||
}
|
}
|
||||||
@ -183,10 +201,13 @@ impl SerializedCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A generic cache for storing and loading compiled wasm modules.
|
||||||
|
///
|
||||||
|
/// The `wasmer-runtime` supplies a naive `FileSystemCache` api.
|
||||||
pub trait Cache {
|
pub trait Cache {
|
||||||
type LoadError;
|
type LoadError;
|
||||||
type StoreError;
|
type StoreError;
|
||||||
|
|
||||||
unsafe fn load(&self, key: WasmHash) -> Result<Module, Self::LoadError>;
|
fn load(&self, key: WasmHash) -> Result<Module, Self::LoadError>;
|
||||||
fn store(&mut self, module: Module) -> Result<WasmHash, Self::StoreError>;
|
fn store(&mut self, module: Module) -> Result<WasmHash, Self::StoreError>;
|
||||||
}
|
}
|
||||||
|
@ -91,12 +91,42 @@ use wasmer_runtime_core::cache::{Error as CacheError, SerializedCache};
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub struct FSCache {
|
/// Representation of a directory that contains compiled wasm artifacts.
|
||||||
|
///
|
||||||
|
/// The `FileSystemCache` type implements the [`Cache`] trait, which allows it to be used
|
||||||
|
/// generically when some sort of cache is required.
|
||||||
|
///
|
||||||
|
/// [`Cache`]: trait.Cache.html
|
||||||
|
///
|
||||||
|
/// # Usage:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use wasmer_runtime::cache::{Cache, FileSystemCache};
|
||||||
|
///
|
||||||
|
/// # use wasmer_runtime::{Module, error::CacheError};
|
||||||
|
/// fn store_and_load_module(module: Module) -> Result<Module, CacheError> {
|
||||||
|
/// // Create a new file system cache.
|
||||||
|
/// // This is unsafe because we can't ensure that the artifact wasn't
|
||||||
|
/// // corrupted or tampered with.
|
||||||
|
/// let mut fs_cache = unsafe { FileSystemCache::new("some/directory/goes/here")? };
|
||||||
|
/// // Store a module into the cache.
|
||||||
|
/// // The returned `key` is equivalent to `module.info().wasm_hash`.
|
||||||
|
/// let key = fs_cache.store(module)?;
|
||||||
|
/// // Load the module back from the cache with the `key`.
|
||||||
|
/// fs_cache.load(key)
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub struct FileSystemCache {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FSCache {
|
impl FileSystemCache {
|
||||||
pub fn open<P: Into<PathBuf>>(path: P) -> io::Result<FSCache> {
|
/// Construct a new `FileSystemCache` around the specified directory.
|
||||||
|
///
|
||||||
|
/// # Note:
|
||||||
|
/// This method is unsafe because there's no way to ensure the artifacts
|
||||||
|
/// stored in this cache haven't been corrupted or tampered with.
|
||||||
|
pub unsafe fn new<P: Into<PathBuf>>(path: P) -> io::Result<Self> {
|
||||||
let path: PathBuf = path.into();
|
let path: PathBuf = path.into();
|
||||||
|
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
@ -129,17 +159,17 @@ impl FSCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cache for FSCache {
|
impl Cache for FileSystemCache {
|
||||||
type LoadError = CacheError;
|
type LoadError = CacheError;
|
||||||
type StoreError = CacheError;
|
type StoreError = CacheError;
|
||||||
|
|
||||||
unsafe fn load(&self, key: WasmHash) -> Result<Module, CacheError> {
|
fn load(&self, key: WasmHash) -> Result<Module, CacheError> {
|
||||||
let filename = key.encode();
|
let filename = key.encode();
|
||||||
let mut new_path_buf = self.path.clone();
|
let mut new_path_buf = self.path.clone();
|
||||||
new_path_buf.push(filename);
|
new_path_buf.push(filename);
|
||||||
|
|
||||||
let serialized_cache = SerializedCache::open(new_path_buf)?;
|
let serialized_cache = SerializedCache::open(new_path_buf)?;
|
||||||
wasmer_runtime_core::load_cache_with(serialized_cache, super::default_compiler())
|
unsafe { wasmer_runtime_core::load_cache_with(serialized_cache, super::default_compiler()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store(&mut self, module: Module) -> Result<WasmHash, CacheError> {
|
fn store(&mut self, module: Module) -> Result<WasmHash, CacheError> {
|
||||||
|
Reference in New Issue
Block a user