mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-25 10:22:19 +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/wasi-tests",
|
||||||
"lib/emscripten-tests",
|
"lib/emscripten-tests",
|
||||||
"lib/middleware-common-tests",
|
"lib/middleware-common-tests",
|
||||||
"examples/plugin-for-example",
|
|
||||||
"examples/parallel",
|
"examples/parallel",
|
||||||
|
"examples/plugin-for-example",
|
||||||
"examples/parallel-guest",
|
"examples/parallel-guest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -16,7 +16,13 @@ fn serializing_works() {
|
|||||||
b"GOROOT=$HOME/.cargo/bin".into_iter().cloned().collect(),
|
b"GOROOT=$HOME/.cargo/bin".into_iter().cloned().collect(),
|
||||||
];
|
];
|
||||||
let wasm_binary = include_bytes!("../wasitests/fd_read.wasm");
|
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(),
|
args.clone(),
|
||||||
envs.clone(),
|
envs.clone(),
|
||||||
vec![],
|
vec![],
|
||||||
@ -25,9 +31,6 @@ fn serializing_works() {
|
|||||||
std::path::PathBuf::from("wasitests/test_fs/hamlet"),
|
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 state_bytes = {
|
||||||
let instance = module.instantiate(&import_object).unwrap();
|
let instance = module.instantiate(&import_object).unwrap();
|
||||||
|
@ -21,8 +21,3 @@ wasmer-runtime-core = { path = "../runtime-core", version = "0.10.1" }
|
|||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.3"
|
winapi = "0.3"
|
||||||
|
|
||||||
[features]
|
|
||||||
# Enable support for the older snapshot0 WASI modules
|
|
||||||
snapshot0 = []
|
|
||||||
default = ["snapshot0"]
|
|
@ -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`].
|
/// Creates a legacy Wasi [`ImportObject`] with [`WasiState`].
|
||||||
pub fn generate_import_object_snapshot0(
|
fn generate_import_object_snapshot0(
|
||||||
args: Vec<Vec<u8>>,
|
args: Vec<Vec<u8>>,
|
||||||
envs: Vec<Vec<u8>>,
|
envs: Vec<Vec<u8>>,
|
||||||
preopened_files: Vec<PathBuf>,
|
preopened_files: Vec<PathBuf>,
|
||||||
|
@ -2,5 +2,4 @@
|
|||||||
//!
|
//!
|
||||||
//! If you are relying on legacy WASI, please upgrade for the best experience.
|
//! If you are relying on legacy WASI, please upgrade for the best experience.
|
||||||
|
|
||||||
#[cfg(feature = "snapshot0")]
|
|
||||||
pub mod snapshot0;
|
pub mod snapshot0;
|
||||||
|
@ -5,7 +5,6 @@ pub mod unix;
|
|||||||
#[cfg(any(target_os = "windows"))]
|
#[cfg(any(target_os = "windows"))]
|
||||||
pub mod windows;
|
pub mod windows;
|
||||||
|
|
||||||
#[cfg(any(feature = "snapshot0"))]
|
|
||||||
pub mod legacy;
|
pub mod legacy;
|
||||||
|
|
||||||
use self::types::*;
|
use self::types::*;
|
||||||
|
@ -26,7 +26,7 @@ use wasmer_clif_backend::CraneliftCompiler;
|
|||||||
use wasmer_llvm_backend::{LLVMCompiler, LLVMOptions};
|
use wasmer_llvm_backend::{LLVMCompiler, LLVMOptions};
|
||||||
use wasmer_runtime::{
|
use wasmer_runtime::{
|
||||||
cache::{Cache as BaseCache, FileSystemCache, WasmHash},
|
cache::{Cache as BaseCache, FileSystemCache, WasmHash},
|
||||||
Func, Value, VERSION,
|
Value, VERSION,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "managed")]
|
#[cfg(feature = "managed")]
|
||||||
use wasmer_runtime_core::tiering::{run_tiering, InteractiveShellContext, ShellExitOperation};
|
use wasmer_runtime_core::tiering::{run_tiering, InteractiveShellContext, ShellExitOperation};
|
||||||
@ -41,25 +41,6 @@ use wasmer_singlepass_backend::SinglePassCompiler;
|
|||||||
#[cfg(feature = "wasi")]
|
#[cfg(feature = "wasi")]
|
||||||
use wasmer_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)]
|
#[derive(Debug, StructOpt)]
|
||||||
#[structopt(name = "wasmer", about = "Wasm execution runtime.", author)]
|
#[structopt(name = "wasmer", about = "Wasm execution runtime.", author)]
|
||||||
/// The options for the wasmer Command Line Interface
|
/// 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)
|
Ok(md)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "wasi")]
|
||||||
fn get_env_var_args(input: &[String]) -> Result<Vec<(&str, &str)>, String> {
|
fn get_env_var_args(input: &[String]) -> Result<Vec<(&str, &str)>, String> {
|
||||||
let mut ev = vec![];
|
let mut ev = vec![];
|
||||||
for entry in input.iter() {
|
for entry in input.iter() {
|
||||||
@ -323,11 +305,111 @@ fn get_env_var_args(input: &[String]) -> Result<Vec<(&str, &str)>, String> {
|
|||||||
Ok(ev)
|
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
|
/// Execute a wasm/wat file
|
||||||
fn execute_wasm(options: &Run) -> Result<(), String> {
|
fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||||
let disable_cache = options.disable_cache;
|
let disable_cache = options.disable_cache;
|
||||||
|
|
||||||
let mapped_dirs = get_mapped_dirs(&options.mapped_dirs[..])?;
|
let mapped_dirs = get_mapped_dirs(&options.mapped_dirs[..])?;
|
||||||
|
#[cfg(feature = "wasi")]
|
||||||
let env_vars = get_env_var_args(&options.env_vars[..])?;
|
let env_vars = get_env_var_args(&options.env_vars[..])?;
|
||||||
let wasm_path = &options.path;
|
let wasm_path = &options.path;
|
||||||
|
|
||||||
@ -582,103 +664,22 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
)
|
)
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{:?}", e))?;
|
||||||
} else {
|
} else {
|
||||||
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();
|
|
||||||
|
|
||||||
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")]
|
#[cfg(feature = "wasi")]
|
||||||
RuntimeError::Error { data } => {
|
let wasi_version = wasmer_wasi::get_wasi_version(&module);
|
||||||
if let Some(error_code) = data.downcast_ref::<wasmer_wasi::ExitCode>() {
|
#[cfg(feature = "wasi")]
|
||||||
std::process::exit(error_code.code as i32)
|
let is_wasi = wasi_version.is_some();
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "wasi"))]
|
#[cfg(not(feature = "wasi"))]
|
||||||
RuntimeError::Error { .. } => (),
|
let is_wasi = false;
|
||||||
}
|
|
||||||
return Err(format!("error: {:?}", err));
|
if is_wasi {
|
||||||
}
|
#[cfg(feature = "wasi")]
|
||||||
}
|
execute_wasi(
|
||||||
|
wasi_version.unwrap(),
|
||||||
|
options,
|
||||||
|
env_vars,
|
||||||
|
module,
|
||||||
|
mapped_dirs,
|
||||||
|
)?;
|
||||||
} else {
|
} else {
|
||||||
let import_object = wasmer_runtime_core::import::ImportObject::new();
|
let import_object = wasmer_runtime_core::import::ImportObject::new();
|
||||||
let instance = module
|
let instance = module
|
||||||
|
Loading…
x
Reference in New Issue
Block a user