mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-24 18:02:13 +00:00
Update from feedback, fix CI issues, update wasi-test
This commit is contained in:
parent
064ffd3938
commit
be217e8f8e
@ -58,8 +58,8 @@ members = [
|
||||
"lib/wasi-tests",
|
||||
"lib/emscripten-tests",
|
||||
"lib/middleware-common-tests",
|
||||
"examples/plugin-for-example",
|
||||
"examples/parallel",
|
||||
"examples/plugin-for-example",
|
||||
"examples/parallel-guest",
|
||||
]
|
||||
|
||||
|
@ -16,7 +16,13 @@ fn serializing_works() {
|
||||
b"GOROOT=$HOME/.cargo/bin".into_iter().cloned().collect(),
|
||||
];
|
||||
let wasm_binary = include_bytes!("../wasitests/fd_read.wasm");
|
||||
let import_object = generate_import_object(
|
||||
let module = compile(&wasm_binary[..])
|
||||
.map_err(|e| format!("Can't compile module: {:?}", e))
|
||||
.unwrap();
|
||||
|
||||
let wasi_version = get_wasi_version(&module).expect("WASI module");
|
||||
let import_object = generate_import_object_for_version(
|
||||
wasi_version,
|
||||
args.clone(),
|
||||
envs.clone(),
|
||||
vec![],
|
||||
@ -25,9 +31,6 @@ fn serializing_works() {
|
||||
std::path::PathBuf::from("wasitests/test_fs/hamlet"),
|
||||
)],
|
||||
);
|
||||
let module = compile(&wasm_binary[..])
|
||||
.map_err(|e| format!("Can't compile module: {:?}", e))
|
||||
.unwrap();
|
||||
|
||||
let state_bytes = {
|
||||
let instance = module.instantiate(&import_object).unwrap();
|
||||
|
@ -20,9 +20,4 @@ serde = { version = "1", features = ["derive"] }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.10.1" }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = "0.3"
|
||||
|
||||
[features]
|
||||
# Enable support for the older snapshot0 WASI modules
|
||||
snapshot0 = []
|
||||
default = ["snapshot0"]
|
||||
winapi = "0.3"
|
@ -130,9 +130,24 @@ pub fn generate_import_object(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "snapshot0")]
|
||||
/// Creates a Wasi [`ImportObject`] with [`WasiState`] for the given [`WasiVersion`].
|
||||
pub fn generate_import_object_for_version(
|
||||
version: WasiVersion,
|
||||
args: Vec<Vec<u8>>,
|
||||
envs: Vec<Vec<u8>>,
|
||||
preopened_files: Vec<PathBuf>,
|
||||
mapped_dirs: Vec<(String, PathBuf)>,
|
||||
) -> ImportObject {
|
||||
match version {
|
||||
WasiVersion::Snapshot0 => {
|
||||
generate_import_object_snapshot0(args, envs, preopened_files, mapped_dirs)
|
||||
}
|
||||
WasiVersion::Snapshot1 => generate_import_object(args, envs, preopened_files, mapped_dirs),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a legacy Wasi [`ImportObject`] with [`WasiState`].
|
||||
pub fn generate_import_object_snapshot0(
|
||||
fn generate_import_object_snapshot0(
|
||||
args: Vec<Vec<u8>>,
|
||||
envs: Vec<Vec<u8>>,
|
||||
preopened_files: Vec<PathBuf>,
|
||||
|
@ -2,5 +2,4 @@
|
||||
//!
|
||||
//! If you are relying on legacy WASI, please upgrade for the best experience.
|
||||
|
||||
#[cfg(feature = "snapshot0")]
|
||||
pub mod snapshot0;
|
||||
|
@ -5,7 +5,6 @@ pub mod unix;
|
||||
#[cfg(any(target_os = "windows"))]
|
||||
pub mod windows;
|
||||
|
||||
#[cfg(any(feature = "snapshot0"))]
|
||||
pub mod legacy;
|
||||
|
||||
use self::types::*;
|
||||
|
@ -26,7 +26,7 @@ use wasmer_clif_backend::CraneliftCompiler;
|
||||
use wasmer_llvm_backend::{LLVMCompiler, LLVMOptions};
|
||||
use wasmer_runtime::{
|
||||
cache::{Cache as BaseCache, FileSystemCache, WasmHash},
|
||||
Func, Value, VERSION,
|
||||
Value, VERSION,
|
||||
};
|
||||
#[cfg(feature = "managed")]
|
||||
use wasmer_runtime_core::tiering::{run_tiering, InteractiveShellContext, ShellExitOperation};
|
||||
@ -41,25 +41,6 @@ use wasmer_singlepass_backend::SinglePassCompiler;
|
||||
#[cfg(feature = "wasi")]
|
||||
use wasmer_wasi;
|
||||
|
||||
// stub module to make conditional compilation happy
|
||||
#[cfg(not(feature = "wasi"))]
|
||||
mod wasmer_wasi {
|
||||
use wasmer_runtime_core::{import::ImportObject, module::Module};
|
||||
|
||||
pub fn is_wasi_module(_module: &Module) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn generate_import_object(
|
||||
_args: Vec<Vec<u8>>,
|
||||
_envs: Vec<Vec<u8>>,
|
||||
_preopened_files: Vec<std::path::PathBuf>,
|
||||
_mapped_dirs: Vec<(String, std::path::PathBuf)>,
|
||||
) -> ImportObject {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(name = "wasmer", about = "Wasm execution runtime.", author)]
|
||||
/// The options for the wasmer Command Line Interface
|
||||
@ -308,6 +289,7 @@ fn get_mapped_dirs(input: &[String]) -> Result<Vec<(String, PathBuf)>, String> {
|
||||
Ok(md)
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasi")]
|
||||
fn get_env_var_args(input: &[String]) -> Result<Vec<(&str, &str)>, String> {
|
||||
let mut ev = vec![];
|
||||
for entry in input.iter() {
|
||||
@ -323,11 +305,111 @@ fn get_env_var_args(input: &[String]) -> Result<Vec<(&str, &str)>, String> {
|
||||
Ok(ev)
|
||||
}
|
||||
|
||||
/// Helper function for `execute_wasm` (the `Run` command)
|
||||
#[cfg(feature = "wasi")]
|
||||
fn execute_wasi(
|
||||
wasi_version: wasmer_wasi::WasiVersion,
|
||||
options: &Run,
|
||||
env_vars: Vec<(&str, &str)>,
|
||||
module: wasmer_runtime_core::Module,
|
||||
mapped_dirs: Vec<(String, PathBuf)>,
|
||||
) -> Result<(), String> {
|
||||
let args = if let Some(cn) = &options.command_name {
|
||||
[cn.clone()]
|
||||
} else {
|
||||
[options.path.to_str().unwrap().to_owned()]
|
||||
}
|
||||
.iter()
|
||||
.chain(options.args.iter())
|
||||
.cloned()
|
||||
.map(|arg| arg.into_bytes())
|
||||
.collect();
|
||||
let envs = env_vars
|
||||
.into_iter()
|
||||
.map(|(k, v)| format!("{}={}", k, v).into_bytes())
|
||||
.collect();
|
||||
let preopened_files = options.pre_opened_directories.clone();
|
||||
|
||||
let import_object = wasmer_wasi::generate_import_object_for_version(
|
||||
wasi_version,
|
||||
args,
|
||||
envs,
|
||||
preopened_files,
|
||||
mapped_dirs,
|
||||
);
|
||||
|
||||
#[allow(unused_mut)] // mut used in feature
|
||||
let mut instance = module
|
||||
.instantiate(&import_object)
|
||||
.map_err(|e| format!("Can't instantiate WASI module: {:?}", e))?;
|
||||
|
||||
let start: wasmer_runtime::Func<(), ()> =
|
||||
instance.func("_start").map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
#[cfg(feature = "managed")]
|
||||
{
|
||||
let start_raw: extern "C" fn(&mut wasmer_runtime_core::vm::Ctx) =
|
||||
unsafe { ::std::mem::transmute(start.get_vm_func()) };
|
||||
|
||||
unsafe {
|
||||
run_tiering(
|
||||
module.info(),
|
||||
&wasm_binary,
|
||||
if let Some(ref path) = options.resume {
|
||||
let mut f = File::open(path).unwrap();
|
||||
let mut out: Vec<u8> = vec![];
|
||||
f.read_to_end(&mut out).unwrap();
|
||||
Some(
|
||||
wasmer_runtime_core::state::InstanceImage::from_bytes(&out)
|
||||
.expect("failed to decode image"),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
&import_object,
|
||||
start_raw,
|
||||
&mut instance,
|
||||
options
|
||||
.optimized_backends
|
||||
.iter()
|
||||
.map(|&backend| -> Box<dyn Fn() -> Box<dyn Compiler> + Send> {
|
||||
Box::new(move || get_compiler_by_backend(backend).unwrap())
|
||||
})
|
||||
.collect(),
|
||||
interactive_shell,
|
||||
)?
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "managed"))]
|
||||
{
|
||||
use wasmer_runtime::error::RuntimeError;
|
||||
let result = start.call();
|
||||
|
||||
if let Err(ref err) = result {
|
||||
match err {
|
||||
RuntimeError::Trap { msg } => return Err(format!("wasm trap occured: {}", msg)),
|
||||
#[cfg(feature = "wasi")]
|
||||
RuntimeError::Error { data } => {
|
||||
if let Some(error_code) = data.downcast_ref::<wasmer_wasi::ExitCode>() {
|
||||
std::process::exit(error_code.code as i32)
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "wasi"))]
|
||||
RuntimeError::Error { .. } => (),
|
||||
}
|
||||
return Err(format!("error: {:?}", err));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Execute a wasm/wat file
|
||||
fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
let disable_cache = options.disable_cache;
|
||||
|
||||
let mapped_dirs = get_mapped_dirs(&options.mapped_dirs[..])?;
|
||||
#[cfg(feature = "wasi")]
|
||||
let env_vars = get_env_var_args(&options.env_vars[..])?;
|
||||
let wasm_path = &options.path;
|
||||
|
||||
@ -582,103 +664,22 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
} else {
|
||||
#[cfg(feature = "wasi")]
|
||||
let wasi_version = wasmer_wasi::get_wasi_version(&module);
|
||||
if cfg!(feature = "wasi") && wasi_version.is_some() {
|
||||
let wasi_version = wasi_version.unwrap();
|
||||
let args = if let Some(cn) = &options.command_name {
|
||||
[cn.clone()]
|
||||
} else {
|
||||
[options.path.to_str().unwrap().to_owned()]
|
||||
}
|
||||
.iter()
|
||||
.chain(options.args.iter())
|
||||
.cloned()
|
||||
.map(|arg| arg.into_bytes())
|
||||
.collect();
|
||||
let envs = env_vars
|
||||
.into_iter()
|
||||
.map(|(k, v)| format!("{}={}", k, v).into_bytes())
|
||||
.collect();
|
||||
let preopened_files = options.pre_opened_directories.clone();
|
||||
#[cfg(feature = "wasi")]
|
||||
let is_wasi = wasi_version.is_some();
|
||||
#[cfg(not(feature = "wasi"))]
|
||||
let is_wasi = false;
|
||||
|
||||
let import_object = match wasi_version {
|
||||
wasmer_wasi::WasiVersion::Snapshot0 => {
|
||||
wasmer_wasi::generate_import_object_snapshot0(
|
||||
args,
|
||||
envs,
|
||||
preopened_files,
|
||||
mapped_dirs,
|
||||
)
|
||||
}
|
||||
wasmer_wasi::WasiVersion::Snapshot1 => {
|
||||
wasmer_wasi::generate_import_object(args, envs, preopened_files, mapped_dirs)
|
||||
}
|
||||
};
|
||||
|
||||
#[allow(unused_mut)] // mut used in feature
|
||||
let mut instance = module
|
||||
.instantiate(&import_object)
|
||||
.map_err(|e| format!("Can't instantiate WASI module: {:?}", e))?;
|
||||
|
||||
let start: Func<(), ()> = instance.func("_start").map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
#[cfg(feature = "managed")]
|
||||
{
|
||||
let start_raw: extern "C" fn(&mut wasmer_runtime_core::vm::Ctx) =
|
||||
unsafe { ::std::mem::transmute(start.get_vm_func()) };
|
||||
|
||||
unsafe {
|
||||
run_tiering(
|
||||
module.info(),
|
||||
&wasm_binary,
|
||||
if let Some(ref path) = options.resume {
|
||||
let mut f = File::open(path).unwrap();
|
||||
let mut out: Vec<u8> = vec![];
|
||||
f.read_to_end(&mut out).unwrap();
|
||||
Some(
|
||||
wasmer_runtime_core::state::InstanceImage::from_bytes(&out)
|
||||
.expect("failed to decode image"),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
&import_object,
|
||||
start_raw,
|
||||
&mut instance,
|
||||
options
|
||||
.optimized_backends
|
||||
.iter()
|
||||
.map(|&backend| -> Box<dyn Fn() -> Box<dyn Compiler> + Send> {
|
||||
Box::new(move || get_compiler_by_backend(backend).unwrap())
|
||||
})
|
||||
.collect(),
|
||||
interactive_shell,
|
||||
)?
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "managed"))]
|
||||
{
|
||||
use wasmer_runtime::error::RuntimeError;
|
||||
let result = start.call();
|
||||
|
||||
if let Err(ref err) = result {
|
||||
match err {
|
||||
RuntimeError::Trap { msg } => {
|
||||
return Err(format!("wasm trap occured: {}", msg))
|
||||
}
|
||||
#[cfg(feature = "wasi")]
|
||||
RuntimeError::Error { data } => {
|
||||
if let Some(error_code) = data.downcast_ref::<wasmer_wasi::ExitCode>() {
|
||||
std::process::exit(error_code.code as i32)
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "wasi"))]
|
||||
RuntimeError::Error { .. } => (),
|
||||
}
|
||||
return Err(format!("error: {:?}", err));
|
||||
}
|
||||
}
|
||||
if is_wasi {
|
||||
#[cfg(feature = "wasi")]
|
||||
execute_wasi(
|
||||
wasi_version.unwrap(),
|
||||
options,
|
||||
env_vars,
|
||||
module,
|
||||
mapped_dirs,
|
||||
)?;
|
||||
} else {
|
||||
let import_object = wasmer_runtime_core::import::ImportObject::new();
|
||||
let instance = module
|
||||
|
Loading…
x
Reference in New Issue
Block a user