Merge branch 'master' into feature/emscripten-getcwd

This commit is contained in:
Mackenzie Clark 2019-02-22 15:15:26 -08:00 committed by GitHub
commit 70e0b8cee1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 100 additions and 22 deletions

View File

@ -130,7 +130,7 @@ wasmer_link() {
printf "$cyan> Adding to bash profile...$reset\n"
WASMER_PROFILE="$(wasmer_detect_profile)"
LOAD_STR="\n# Wasmer\nexport WASMER_DIR=\"\$HOME/.wasmer\"\n[ -s \"\$WASMER_DIR/wasmer.sh\" ] && source \"\$WASMER_DIR/wasmer.sh\" # This loads wasmer\n"
SOURCE_STR="# Wasmer config\nexport WASMER_DIR=\"\$HOME/.wasmer\"\nexport PATH=\"\$HOME/.wasmer/bin:\$PATH\"\n"
SOURCE_STR="# Wasmer config\nexport WASMER_DIR=\"\$HOME/.wasmer\"\nexport WASMER_CACHE_DIR=\"\$WASMER_DIR/cache\"\nexport PATH=\"\$HOME/.wasmer/bin:\$PATH\"\n"
# We create the wasmer.sh file
echo "$SOURCE_STR" > "$HOME/.wasmer/wasmer.sh"

View File

@ -50,8 +50,6 @@ impl Module {
namespace_table: StringTable::new(),
name_table: StringTable::new(),
wasm_hash: WasmHash::generate(wasm),
},
}
}

View File

@ -67,7 +67,6 @@ struct ArtifactHeader {
magic: [u8; 8], // [W, A, S, M, E, R, \0, \0]
version: u64,
data_len: u64,
wasm_hash: [u8; 32], // Sha256 of the wasm in binary format.
}
impl ArtifactHeader {
@ -170,7 +169,6 @@ impl Artifact {
magic: WASMER_CACHE_MAGIC,
version: CURRENT_CACHE_VERSION,
data_len: 0,
wasm_hash: self.inner.info.wasm_hash.into_array(),
};
let mut buffer = cache_header.as_slice().to_vec();
@ -195,5 +193,5 @@ pub trait Cache {
type StoreError;
fn load(&self, key: WasmHash) -> Result<Module, Self::LoadError>;
fn store(&mut self, module: Module) -> Result<WasmHash, Self::StoreError>;
fn store(&mut self, key: WasmHash, module: Module) -> Result<(), Self::StoreError>;
}

View File

@ -56,8 +56,6 @@ pub struct ModuleInfo {
pub namespace_table: StringTable<NamespaceIndex>,
pub name_table: StringTable<NameIndex>,
pub wasm_hash: WasmHash,
}
/// A compiled WebAssembly module.
@ -116,6 +114,14 @@ impl Module {
}
}
impl Clone for Module {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
impl ModuleInner {}
#[doc(hidden)]

View File

@ -565,8 +565,6 @@ mod vm_ctx_tests {
namespace_table: StringTable::new(),
name_table: StringTable::new(),
wasm_hash: WasmHash::generate(&[]),
},
}
}

View File

@ -19,19 +19,19 @@ pub use wasmer_runtime_core::cache::{Artifact, Cache, WasmHash};
/// # Usage:
///
/// ```rust
/// use wasmer_runtime::cache::{Cache, FileSystemCache};
/// use wasmer_runtime::cache::{Cache, FileSystemCache, WasmHash};
///
/// # use wasmer_runtime::{Module, error::CacheError};
/// fn store_and_load_module(module: Module) -> Result<Module, CacheError> {
/// fn store_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)
/// // Compute a key for a given WebAssembly binary
/// let key = WasmHash::generate(&[]);
/// // Store a module into the cache given a key
/// fs_cache.store(key, module.clone())?;
/// Ok(module)
/// }
/// ```
pub struct FileSystemCache {
@ -92,8 +92,7 @@ impl Cache for FileSystemCache {
unsafe { wasmer_runtime_core::load_cache_with(serialized_cache, super::default_compiler()) }
}
fn store(&mut self, module: Module) -> Result<WasmHash, CacheError> {
let key = module.info().wasm_hash;
fn store(&mut self, key: WasmHash, module: Module) -> Result<(), CacheError> {
let filename = key.encode();
let mut new_path_buf = self.path.clone();
new_path_buf.push(filename);
@ -104,6 +103,6 @@ impl Cache for FileSystemCache {
let mut file = File::create(new_path_buf)?;
file.write_all(&buffer)?;
Ok(key)
Ok(())
}
}

View File

@ -1,5 +1,7 @@
extern crate structopt;
use std::env;
use std::fs;
use std::fs::File;
use std::io;
use std::io::Read;
@ -11,6 +13,8 @@ use structopt::StructOpt;
use wasmer::webassembly::InstanceABI;
use wasmer::*;
use wasmer_emscripten;
use wasmer_runtime::cache::{Cache as BaseCache, FileSystemCache, WasmHash};
use wasmer_runtime::error::CacheError;
#[derive(Debug, StructOpt)]
#[structopt(name = "wasmer", about = "Wasm execution runtime.")]
@ -20,6 +24,10 @@ enum CLIOptions {
#[structopt(name = "run")]
Run(Run),
/// Wasmer cache
#[structopt(name = "cache")]
Cache(Cache),
/// Update wasmer to the latest version
#[structopt(name = "self-update")]
SelfUpdate,
@ -30,6 +38,10 @@ struct Run {
#[structopt(short = "d", long = "debug")]
debug: bool,
// Disable the cache
#[structopt(long = "disable-cache")]
disable_cache: bool,
/// Input file
#[structopt(parse(from_os_str))]
path: PathBuf,
@ -39,6 +51,15 @@ struct Run {
args: Vec<String>,
}
#[derive(Debug, StructOpt)]
enum Cache {
#[structopt(name = "clean")]
Clean,
#[structopt(name = "dir")]
Dir,
}
/// Read the contents of a file
fn read_file_contents(path: &PathBuf) -> Result<Vec<u8>, io::Error> {
let mut buffer: Vec<u8> = Vec::new();
@ -49,6 +70,18 @@ fn read_file_contents(path: &PathBuf) -> Result<Vec<u8>, io::Error> {
Ok(buffer)
}
fn get_cache_dir() -> PathBuf {
match env::var("WASMER_CACHE_DIR") {
Ok(dir) => PathBuf::from(dir),
Err(_) => {
// We use a temporal directory for saving cache files
let mut temp_dir = env::temp_dir();
temp_dir.push("wasmer");
temp_dir
}
}
}
/// Execute a wasm/wat file
fn execute_wasm(options: &Run) -> Result<(), String> {
let wasm_path = &options.path;
@ -66,8 +99,44 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
.map_err(|e| format!("Can't convert from wast to wasm: {:?}", e))?;
}
let module = webassembly::compile(&wasm_binary[..])
.map_err(|e| format!("Can't compile module: {:?}", e))?;
let module = if !options.disable_cache {
// If we have cache enabled
// We generate a hash for the given binary, so we can use it as key
// for the Filesystem cache
let hash = WasmHash::generate(&wasm_binary);
let wasmer_cache_dir = get_cache_dir();
// We create a new cache instance.
// It could be possible to use any other kinds of caching, as long as they
// implement the Cache trait (with save and load functions)
let mut cache = unsafe {
FileSystemCache::new(wasmer_cache_dir).map_err(|e| format!("Cache error: {:?}", e))?
};
// cache.load will return the Module if it's able to deserialize it properly, and an error if:
// * The file is not found
// * The file exists, but it's corrupted or can't be converted to a module
let module = match cache.load(hash) {
Ok(module) => {
// We are able to load the module from cache
module
}
Err(_) => {
let module = webassembly::compile(&wasm_binary[..])
.map_err(|e| format!("Can't compile module: {:?}", e))?;
// We save the module into a cache file
cache.store(hash, module.clone()).unwrap();
module
}
};
module
} else {
webassembly::compile(&wasm_binary[..])
.map_err(|e| format!("Can't compile module: {:?}", e))?
};
let (_abi, import_object, _em_globals) = if wasmer_emscripten::is_emscripten_module(&module) {
let mut emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new(&module);
@ -119,5 +188,15 @@ fn main() {
CLIOptions::SelfUpdate => {
println!("Self update is not supported on Windows. Use install instructions on the Wasmer homepage: https://wasmer.io");
}
CLIOptions::Cache(cache) => match cache {
Cache::Clean => {
let cache_dir = get_cache_dir();
fs::remove_dir_all(cache_dir.clone()).expect("Can't remove cache dir");
fs::create_dir(cache_dir.clone()).expect("Can't create cache dir");
}
Cache::Dir => {
println!("{}", get_cache_dir().to_string_lossy());
}
},
}
}