From cdbd27275c1eba8f0f49ca52006639b62dd4f3a1 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Thu, 15 Nov 2018 00:50:54 -0800 Subject: [PATCH] Improved errors formatting --- src/main.rs | 14 ++++++-------- src/webassembly/mod.rs | 26 ++++++++++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index a1c4fce10..b711ec1f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,6 @@ extern crate spin; extern crate log; // use libc; -use std::error::Error; use std::fs::File; use std::io; use std::io::Read; @@ -32,7 +31,6 @@ use std::path::PathBuf; use std::process::exit; use structopt::StructOpt; -use wabt::wat2wasm; #[macro_use] mod macros; @@ -62,7 +60,7 @@ struct Run { } /// Read the contents of a file -fn read_file_contents(path: PathBuf) -> Result, io::Error> { +fn read_file_contents(path: &PathBuf) -> Result, io::Error> { let mut buffer: Vec = Vec::new(); let mut file = File::open(path)?; file.read_to_end(&mut buffer)?; @@ -72,15 +70,15 @@ fn read_file_contents(path: PathBuf) -> Result, io::Error> { /// Execute a WASM/WAT file fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { let mut wasm_binary: Vec = - read_file_contents(wasm_path).map_err(|err| String::from(err.description()))?; + read_file_contents(&wasm_path).map_err(|err| format!("Can't read the file {}: {}", wasm_path.as_os_str().to_string_lossy(), err))?; if !webassembly::utils::is_wasm_binary(&wasm_binary) { - wasm_binary = wat2wasm(wasm_binary).map_err(|err| String::from(err.description()))?; + wasm_binary = wabt::wat2wasm(wasm_binary).map_err(|err| format!("Can't convert from wast to wasm: {:?}", err))?; } let import_object = linkers::generate_emscripten_env(); let webassembly::ResultObject { module, instance } = webassembly::instantiate(wasm_binary, import_object) - .map_err(|err| format!("{}", err))?; + .map_err(|err| format!("Can't instantiate the WebAssembly module: {}", err))?; // webassembly::utils::print_instance_offsets(&instance); @@ -99,8 +97,8 @@ fn run(options: Run) { match execute_wasm(options.path.clone()) { Ok(()) => {} Err(message) => { - let name = options.path.as_os_str().to_string_lossy(); - println!("error while executing {}: {}", name, message); + // let name = options.path.as_os_str().to_string_lossy(); + println!("{}", message); exit(1); } } diff --git a/src/webassembly/mod.rs b/src/webassembly/mod.rs index 1508f7516..a3be88647 100644 --- a/src/webassembly/mod.rs +++ b/src/webassembly/mod.rs @@ -10,6 +10,7 @@ use std::panic; use std::str::FromStr; use target_lexicon; use wasmparser; +use wasmparser::WasmDecoder; pub use self::errors::{Error, ErrorKind}; pub use self::import_object::ImportObject; @@ -73,11 +74,8 @@ pub fn instantiate_streaming( /// webassembly::CompileError. pub fn compile(buffer_source: Vec) -> Result { // TODO: This should be automatically validated when creating the Module - let valid = validate(&buffer_source); - debug!("webassembly - valid {:?}", valid); - if !valid { - return Err(ErrorKind::CompileError("Module not valid".to_string())); - } + debug!("webassembly - validating module"); + validate_or_error(&buffer_source)?; debug!("webassembly - creating module"); let module = Module::from_bytes(buffer_source, triple!("x86_64"), None)?; @@ -90,8 +88,20 @@ pub fn compile(buffer_source: Vec) -> Result { /// array of WebAssembly binary code, returning whether the bytes /// form a valid wasm module (true) or not (false). /// Params: -/// * `buffer_source`: A `Vec` containing the +/// * `buffer_source`: A `&[u8]` containing the /// binary code of the .wasm module you want to compile. -pub fn validate(buffer_source: &Vec) -> bool { - wasmparser::validate(buffer_source, None) +pub fn validate(buffer_source: &[u8]) -> bool { + validate_or_error(buffer_source).is_ok() +} + +pub fn validate_or_error(bytes: &[u8]) -> Result<(), ErrorKind> { + let mut parser = wasmparser::ValidatingParser::new(bytes, None); + loop { + let state = parser.read(); + match *state { + wasmparser::ParserState::EndWasm => return Ok(()), + wasmparser::ParserState::Error(err) => return Err(ErrorKind::CompileError(format!("Validation error: {}", err.message))), + _ => (), + } + } }