Merge wasi-common into wasmtime
This commit merges [CraneStation/wasi-common] repo as a subdir of this repo while preserving **all** of git history. There is an initiative to pull `wasi-common` into [CraneStation/wasmtime], and [CraneStation/wasmtime] becoming a monorepo. This came about for several reasons with a common theme of convenience, namely, having a monorepo: 1. cleans up the problem of dependencies (as we have seen first hand with dependabot enabled, it can cause some grief) 2. completely removes the problem of syncing the closely dependent repos (e.g., updating `wasi-common` with say a bugfix generally implies creating a "sync" commit for pulling in the changes into the "parent" repo, in this case, `wasmtime`) 3. mainly for the two reasons above, makes publishing to crates.io easier 4. hopefully streamlines the process of getting the community involved in contributing to `wasi-common` as now everything is one place [CraneStation/wasi-common]: https://github.com/CraneStation/wasi-common [CraneStation/wasmtime]: https://github.com/CraneStation/wasmtime
This commit is contained in:
92
wasi-common/tests/runtime.rs
Normal file
92
wasi-common/tests/runtime.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use cranelift_codegen::settings::{self, Configurable};
|
||||
use std::{collections::HashMap, path::Path};
|
||||
use wasmtime_api::{Config, Engine, HostRef, Instance, Module, Store};
|
||||
use wasmtime_jit::{CompilationStrategy, Features};
|
||||
|
||||
pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> Result<(), String> {
|
||||
// Prepare runtime
|
||||
let mut flag_builder = settings::builder();
|
||||
|
||||
// Enable proper trap for division
|
||||
flag_builder
|
||||
.enable("avoid_div_traps")
|
||||
.map_err(|err| format!("error while enabling proper division trap: {}", err))?;
|
||||
|
||||
let config = Config::new(
|
||||
settings::Flags::new(flag_builder),
|
||||
Features::default(),
|
||||
false,
|
||||
CompilationStrategy::Auto,
|
||||
);
|
||||
let engine = HostRef::new(Engine::new(config));
|
||||
let store = HostRef::new(Store::new(engine));
|
||||
|
||||
let mut module_registry = HashMap::new();
|
||||
let global_exports = store.borrow().global_exports().clone();
|
||||
let get_preopens = |workspace: Option<&Path>| -> Result<Vec<_>, String> {
|
||||
if let Some(workspace) = workspace {
|
||||
let preopen_dir = wasi_common::preopen_dir(workspace).map_err(|e| {
|
||||
format!(
|
||||
"error while preopening directory '{}': {}",
|
||||
workspace.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(vec![(".".to_owned(), preopen_dir)])
|
||||
} else {
|
||||
Ok(vec![])
|
||||
}
|
||||
};
|
||||
module_registry.insert(
|
||||
"wasi_unstable".to_owned(),
|
||||
Instance::from_handle(
|
||||
store.clone(),
|
||||
wasmtime_wasi::instantiate_wasi(
|
||||
"",
|
||||
global_exports.clone(),
|
||||
&get_preopens(workspace)?,
|
||||
&[bin_name.to_owned(), ".".to_owned()],
|
||||
&[],
|
||||
)
|
||||
.map_err(|e| format!("error instantiating WASI: {}", e))?,
|
||||
)
|
||||
.map_err(|err| format!("error instantiating from handle: {}", err))?,
|
||||
);
|
||||
|
||||
let module = HostRef::new(
|
||||
Module::new(store.clone(), &data)
|
||||
.map_err(|err| format!("error while creating Wasm module '{}': {}", bin_name, err))?,
|
||||
);
|
||||
let imports = module
|
||||
.borrow()
|
||||
.imports()
|
||||
.iter()
|
||||
.map(|i| {
|
||||
let module_name = i.module().to_string();
|
||||
if let Some((instance, map)) = module_registry.get(&module_name) {
|
||||
let field_name = i.name().to_string();
|
||||
if let Some(export_index) = map.get(&field_name) {
|
||||
Ok(instance.exports()[*export_index].clone())
|
||||
} else {
|
||||
Err(format!(
|
||||
"import {} was not found in module {}",
|
||||
field_name, module_name
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(format!("import module {} was not found", module_name))
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let _ = HostRef::new(
|
||||
Instance::new(store.clone(), module.clone(), &imports).map_err(|err| {
|
||||
format!(
|
||||
"error while instantiating Wasm module '{}': {}",
|
||||
bin_name, err
|
||||
)
|
||||
})?,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
30
wasi-common/tests/utils.rs
Normal file
30
wasi-common/tests/utils.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use tempfile::{Builder, TempDir};
|
||||
|
||||
pub fn read_wasm(path: &Path) -> Result<Vec<u8>, String> {
|
||||
let data = fs::read(path).map_err(|err| err.to_string())?;
|
||||
if data.starts_with(&[b'\0', b'a', b's', b'm']) {
|
||||
Ok(data)
|
||||
} else {
|
||||
Err("Invalid Wasm file encountered".to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prepare_workspace(exe_name: &str) -> Result<TempDir, String> {
|
||||
let prefix = format!("wasi_common_{}", exe_name);
|
||||
Builder::new()
|
||||
.prefix(&prefix)
|
||||
.tempdir()
|
||||
.map_err(|e| format!("couldn't create workspace in temp files: {}", e))
|
||||
}
|
||||
|
||||
pub fn extract_exec_name_from_path(path: &Path) -> Result<String, String> {
|
||||
path.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
.map(String::from)
|
||||
.ok_or(format!(
|
||||
"couldn't extract the file stem from path {}",
|
||||
path.display()
|
||||
))
|
||||
}
|
||||
16
wasi-common/tests/wasm_tests.rs
Normal file
16
wasi-common/tests/wasm_tests.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
#![cfg(feature = "wasm_tests")]
|
||||
|
||||
mod runtime;
|
||||
mod utils;
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
static LOG_INIT: Once = Once::new();
|
||||
|
||||
fn setup_log() {
|
||||
LOG_INIT.call_once(|| {
|
||||
pretty_env_logger::init();
|
||||
})
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/wasi_misc_tests.rs"));
|
||||
Reference in New Issue
Block a user