From 4afb28ef598f996fe1afb33fd7b2daf25562b7fb Mon Sep 17 00:00:00 2001 From: Ram Date: Fri, 25 May 2018 01:23:00 +1000 Subject: [PATCH] Use wabt, and make the wasm subcommand optional. (#347) * Use wabt for wasm testing. * Use wabt in cton-util. * Make the wasm subcommand optional. --- README.rst | 5 ---- cranelift/Cargo.toml | 9 ++++-- cranelift/src/cton-util.rs | 31 ++++++++++++++------ cranelift/src/wasm.rs | 26 ++++------------- lib/wasm/Cargo.toml | 2 +- lib/wasm/tests/wasm_testsuite.rs | 49 +++++++------------------------- 6 files changed, 48 insertions(+), 74 deletions(-) diff --git a/README.rst b/README.rst index 0e30d5aa13..24a601cba4 100644 --- a/README.rst +++ b/README.rst @@ -85,11 +85,6 @@ You can then run tests with:: ./test-all.sh -You may need to install the *wat2wasm* tool from the `wabt -`_ project in order to run all of the -WebAssembly tests. Tests requiring wat2wasm are ignored if the tool is not -installed. - Building with `no_std` ---------------------- diff --git a/cranelift/Cargo.toml b/cranelift/Cargo.toml index b807c2fe01..993c96166d 100644 --- a/cranelift/Cargo.toml +++ b/cranelift/Cargo.toml @@ -13,10 +13,11 @@ name = "cton-util" path = "src/cton-util.rs" [dependencies] +cfg-if = "0.1" cretonne-codegen = { path = "lib/codegen", version = "0.8.0" } cretonne-reader = { path = "lib/reader", version = "0.8.0" } cretonne-frontend = { path = "lib/frontend", version = "0.8.0" } -cretonne-wasm = { path = "lib/wasm", version = "0.8.0" } +cretonne-wasm = { path = "lib/wasm", version = "0.8.0", optional = true } cretonne-native = { path = "lib/native", version = "0.8.0" } cretonne-filetests = { path = "lib/filetests", version = "0.8.0" } cretonne-module = { path = "lib/module", version = "0.8.0" } @@ -27,9 +28,13 @@ filecheck = "0.3.0" docopt = "1" serde = "1.0.8" serde_derive = "1.0.8" -tempdir = "0.3.5" term = "0.5.1" capstone = "0.3.1" +wabt = { version = "0.3", optional = true } + +[features] +default = ["wasm"] +wasm = ["wabt", "cretonne-wasm"] [workspace] diff --git a/cranelift/src/cton-util.rs b/cranelift/src/cton-util.rs index 0010034a0a..1ae6991dfb 100644 --- a/cranelift/src/cton-util.rs +++ b/cranelift/src/cton-util.rs @@ -1,5 +1,5 @@ -#![deny(trivial_numeric_casts, unused_extern_crates)] -#![warn(unused_import_braces, unstable_features)] +#![deny(trivial_numeric_casts)] +#![warn(unused_import_braces, unstable_features, unused_extern_crates)] #![cfg_attr(feature="cargo-clippy", warn( float_arithmetic, mut_mut, @@ -10,17 +10,25 @@ use_self, ))] +#[macro_use] +extern crate cfg_if; extern crate cretonne_codegen; extern crate cretonne_filetests; extern crate cretonne_reader; -extern crate cretonne_wasm; extern crate docopt; extern crate filecheck; #[macro_use] extern crate serde_derive; -extern crate tempdir; -extern crate term; extern crate capstone; +extern crate term; + +cfg_if! { + if #[cfg(feature = "wasm")] { + extern crate cretonne_wasm; + extern crate wabt; + mod wasm; + } +} use cretonne_codegen::{timing, VERSION}; use docopt::Docopt; @@ -32,7 +40,6 @@ mod compile; mod print_cfg; mod rsfilecheck; mod utils; -mod wasm; const USAGE: &str = " Cretonne code generator utility @@ -114,7 +121,8 @@ fn cton_util() -> CommandResult { &args.flag_isa, ) } else if args.cmd_wasm { - wasm::run( + #[cfg(feature = "wasm")] + let result = wasm::run( args.arg_file, args.flag_verbose, args.flag_just_decode, @@ -123,7 +131,14 @@ fn cton_util() -> CommandResult { &args.flag_set, &args.flag_isa, args.flag_print_size, - ) + ); + + #[cfg(not(feature = "wasm"))] + let result = Err( + "Error: cton-util was compiled without wasm support.".to_owned(), + ); + + result } else { // Debugging / shouldn't happen with proper command line handling above. Err(format!("Unhandled args: {:?}", args)) diff --git a/cranelift/src/wasm.rs b/cranelift/src/wasm.rs index 4f44afa6f6..4c1907b6ce 100644 --- a/cranelift/src/wasm.rs +++ b/cranelift/src/wasm.rs @@ -9,14 +9,11 @@ use cretonne_codegen::print_errors::{pretty_error, pretty_verifier_error}; use cretonne_codegen::settings::FlagsOrIsa; use cretonne_wasm::{translate_module, DummyEnvironment, ModuleEnvironment}; use std::error::Error; -use std::fs::File; -use std::io; use std::path::Path; use std::path::PathBuf; -use std::process::Command; -use tempdir::TempDir; use term; use utils::{parse_sets_and_isa, read_to_end}; +use wabt::wat2wasm; macro_rules! vprintln { ($x: expr, $($tts:tt)*) => { @@ -85,23 +82,12 @@ fn handle_module( let mut data = read_to_end(path.clone()).map_err(|err| { String::from(err.description()) })?; + if !data.starts_with(&[b'\0', b'a', b's', b'm']) { - let tmp_dir = TempDir::new("cretonne-wasm").unwrap(); - let file_path = tmp_dir.path().join("module.wasm"); - File::create(file_path.clone()).unwrap(); - Command::new("wat2wasm") - .arg(path.clone()) - .arg("-o") - .arg(file_path.to_str().unwrap()) - .output() - .or_else(|e| if let io::ErrorKind::NotFound = e.kind() { - return Err(String::from("wat2wasm not found")); - } else { - return Err(String::from(e.description())); - })?; - data = read_to_end(file_path).map_err( - |err| String::from(err.description()), - )?; + data = match wat2wasm(&data) { + Ok(data) => data, + Err(e) => return Err(String::from(e.description())), + }; } let mut dummy_environ = DummyEnvironment::with_flags(fisa.flags.clone()); diff --git a/lib/wasm/Cargo.toml b/lib/wasm/Cargo.toml index f1ad6b726c..3882a850cb 100644 --- a/lib/wasm/Cargo.toml +++ b/lib/wasm/Cargo.toml @@ -17,7 +17,7 @@ failure = { version = "0.1.1", default-features = false, features = ["derive"] } failure_derive = { version = "0.1.1", default-features = false } [dev-dependencies] -tempdir = "0.3.5" +wabt = "0.3" [features] default = ["std"] diff --git a/lib/wasm/tests/wasm_testsuite.rs b/lib/wasm/tests/wasm_testsuite.rs index 1871b4d781..3492c7bd89 100644 --- a/lib/wasm/tests/wasm_testsuite.rs +++ b/lib/wasm/tests/wasm_testsuite.rs @@ -1,20 +1,17 @@ extern crate cretonne_codegen; extern crate cretonne_wasm; -extern crate tempdir; +extern crate wabt; use cretonne_codegen::print_errors::pretty_verifier_error; use cretonne_codegen::settings::{self, Configurable, Flags}; use cretonne_codegen::verifier; use cretonne_wasm::{translate_module, DummyEnvironment}; -use std::error::Error; use std::fs; use std::fs::File; use std::io; use std::io::prelude::*; -use std::path::PathBuf; -use std::process::Command; -use std::str; -use tempdir::TempDir; +use std::path::Path; +use wabt::wat2wasm; #[test] fn testsuite() { @@ -44,56 +41,32 @@ fn return_at_end() { let mut flag_builder = settings::builder(); flag_builder.enable("return_at_end").unwrap(); let flags = Flags::new(flag_builder); - handle_module(&PathBuf::from("../../wasmtests/return_at_end.wat"), &flags); + handle_module(Path::new("../../wasmtests/return_at_end.wat"), &flags); } -fn read_wasm_file(path: PathBuf) -> Result, io::Error> { +fn read_file(path: &Path) -> Result, io::Error> { let mut buf: Vec = Vec::new(); let mut file = File::open(path)?; file.read_to_end(&mut buf)?; Ok(buf) } -fn handle_module(path: &PathBuf, flags: &Flags) { +fn handle_module(path: &Path, flags: &Flags) { let data = match path.extension() { None => { panic!("the file extension is not wasm or wat"); } Some(ext) => { match ext.to_str() { - Some("wasm") => read_wasm_file(path.clone()).expect("error reading wasm file"), + Some("wasm") => read_file(path).expect("error reading wasm file"), Some("wat") => { - let tmp_dir = TempDir::new("cretonne-wasm").unwrap(); - let file_path = tmp_dir.path().join("module.wasm"); - File::create(file_path.clone()).unwrap(); - let result_output = Command::new("wat2wasm") - .arg(path.clone()) - .arg("-o") - .arg(file_path.to_str().unwrap()) - .output(); - match result_output { + let wat = read_file(path).expect("error reading wat file"); + match wat2wasm(&wat) { + Ok(wasm) => wasm, Err(e) => { - if e.kind() == io::ErrorKind::NotFound { - println!( - "wat2wasm not found; disabled test {}", - path.to_str().unwrap() - ); - return; - } - panic!("error convering wat file: {}", e.description()); - } - Ok(output) => { - if !output.status.success() { - panic!( - "error running wat2wasm: {}", - str::from_utf8(&output.stderr).expect( - "wat2wasm's error message should be valid UTF-8", - ) - ); - } + panic!("error converting wat to wasm: {:?}", e); } } - read_wasm_file(file_path).expect("error reading converted wasm file") } None | Some(&_) => panic!("the file extension for {:?} is not wasm or wat", path), }