From 76f479843666259f3f482be247252e9f913cd993 Mon Sep 17 00:00:00 2001 From: Lachlan Sneff Date: Mon, 22 Apr 2019 16:45:36 -0700 Subject: [PATCH] Hook up wasi exit code to wasmer cli --- examples/exit.wat | 11 +++++ src/bin/wasmer.rs | 119 +++++++++++++++++++++++++++------------------- 2 files changed, 82 insertions(+), 48 deletions(-) create mode 100644 examples/exit.wat diff --git a/examples/exit.wat b/examples/exit.wat new file mode 100644 index 00000000000..b2f832cb3b8 --- /dev/null +++ b/examples/exit.wat @@ -0,0 +1,11 @@ +(module + (import "wasi_unstable" "proc_exit" (func $proc_exit (param i32))) + (export "_start" (func $_start)) + + (memory 10) + (export "memory" (memory 0)) + + (func $_start + (call $proc_exit (i32.const 7)) + ) +) diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index b9606a225a7..721192a13b1 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -11,12 +11,14 @@ use std::str::FromStr; use hashbrown::HashMap; use structopt::StructOpt; -use wasmer::webassembly::InstanceABI; use wasmer::*; use wasmer_clif_backend::CraneliftCompiler; #[cfg(feature = "backend:llvm")] use wasmer_llvm_backend::LLVMCompiler; -use wasmer_runtime::cache::{Cache as BaseCache, FileSystemCache, WasmHash, WASMER_VERSION_HASH}; +use wasmer_runtime::{ + cache::{Cache as BaseCache, FileSystemCache, WasmHash, WASMER_VERSION_HASH}, + Func, Value, error::RuntimeError, +}; use wasmer_runtime_core::{ self, backend::{Compiler, CompilerConfig}, @@ -295,60 +297,81 @@ fn execute_wasm(options: &Run) -> Result<(), String> { }; // TODO: refactor this - let (abi, import_object, _em_globals) = if wasmer_emscripten::is_emscripten_module(&module) { + if wasmer_emscripten::is_emscripten_module(&module) { let mut emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new(&module); - ( - InstanceABI::Emscripten, - wasmer_emscripten::generate_emscripten_env(&mut emscripten_globals), - Some(emscripten_globals), // TODO Em Globals is here to extend, lifetime, find better solution + let import_object = wasmer_emscripten::generate_emscripten_env(&mut emscripten_globals); + let mut instance = module + .instantiate(&import_object) + .map_err(|e| format!("Can't instantiate module: {:?}", e))?; + + wasmer_emscripten::run_emscripten_instance( + &module, + &mut instance, + if let Some(cn) = &options.command_name { + cn + } else { + options.path.to_str().unwrap() + }, + options.args.iter().map(|arg| arg.as_str()).collect(), ) + .map_err(|e| format!("{:?}", e))?; } else { if cfg!(feature = "wasi") && wasmer_wasi::is_wasi_module(&module) { - ( - InstanceABI::WASI, - wasmer_wasi::generate_import_object( - 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()) + let import_object = wasmer_wasi::generate_import_object( + 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(), + env::vars() + .map(|(k, v)| format!("{}={}", k, v).into_bytes()) .collect(), - env::vars() - .map(|(k, v)| format!("{}={}", k, v).into_bytes()) - .collect(), - options.pre_opened_directories.clone(), - ), - None, - ) - } else { - ( - InstanceABI::None, - wasmer_runtime_core::import::ImportObject::new(), - None, - ) - } - }; + options.pre_opened_directories.clone(), + ); - let mut instance = module - .instantiate(&import_object) - .map_err(|e| format!("Can't instantiate module: {:?}", e))?; + let instance = module + .instantiate(&import_object) + .map_err(|e| format!("Can't instantiate module: {:?}", e))?; - webassembly::run_instance( - &module, - &mut instance, - abi, - if let Some(cn) = &options.command_name { - cn + let start: Func<(), ()> = instance.func("_start").map_err(|e| format!("{:?}", e))?; + + let result = start.call(); + + if let Err(ref err) = result { + match err { + RuntimeError::Trap { msg } => panic!("wasm trap occured: {}", msg), + RuntimeError::Error { data } => { + if let Some(error_code) = data.downcast_ref::() { + std::process::exit(error_code.code as i32) + } + } + } + panic!("error: {:?}", err) + } } else { - options.path.to_str().unwrap() - }, - options.args.iter().map(|arg| arg.as_str()).collect(), - ) - .map_err(|e| format!("{:?}", e))?; + let import_object = wasmer_runtime_core::import::ImportObject::new(); + let instance = module + .instantiate(&import_object) + .map_err(|e| format!("Can't instantiate module: {:?}", e))?; + + let args: Vec = options + .args + .iter() + .map(|arg| arg.as_str()) + .map(|x| Value::I32(x.parse().unwrap())) + .collect(); + instance + .dyn_func("main") + .map_err(|e| format!("{:?}", e))? + .call(&args) + .map_err(|e| format!("{:?}", e))?; + } + } Ok(()) }