Use wabt, and make the wasm subcommand optional. (#347)
* Use wabt for wasm testing. * Use wabt in cton-util. * Make the wasm subcommand optional.
This commit is contained in:
@@ -85,11 +85,6 @@ You can then run tests with::
|
|||||||
|
|
||||||
./test-all.sh
|
./test-all.sh
|
||||||
|
|
||||||
You may need to install the *wat2wasm* tool from the `wabt
|
|
||||||
<https://github.com/WebAssembly/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`
|
Building with `no_std`
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,11 @@ name = "cton-util"
|
|||||||
path = "src/cton-util.rs"
|
path = "src/cton-util.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
cfg-if = "0.1"
|
||||||
cretonne-codegen = { path = "lib/codegen", version = "0.8.0" }
|
cretonne-codegen = { path = "lib/codegen", version = "0.8.0" }
|
||||||
cretonne-reader = { path = "lib/reader", version = "0.8.0" }
|
cretonne-reader = { path = "lib/reader", version = "0.8.0" }
|
||||||
cretonne-frontend = { path = "lib/frontend", 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-native = { path = "lib/native", version = "0.8.0" }
|
||||||
cretonne-filetests = { path = "lib/filetests", version = "0.8.0" }
|
cretonne-filetests = { path = "lib/filetests", version = "0.8.0" }
|
||||||
cretonne-module = { path = "lib/module", version = "0.8.0" }
|
cretonne-module = { path = "lib/module", version = "0.8.0" }
|
||||||
@@ -27,9 +28,13 @@ filecheck = "0.3.0"
|
|||||||
docopt = "1"
|
docopt = "1"
|
||||||
serde = "1.0.8"
|
serde = "1.0.8"
|
||||||
serde_derive = "1.0.8"
|
serde_derive = "1.0.8"
|
||||||
tempdir = "0.3.5"
|
|
||||||
term = "0.5.1"
|
term = "0.5.1"
|
||||||
capstone = "0.3.1"
|
capstone = "0.3.1"
|
||||||
|
wabt = { version = "0.3", optional = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["wasm"]
|
||||||
|
wasm = ["wabt", "cretonne-wasm"]
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![deny(trivial_numeric_casts, unused_extern_crates)]
|
#![deny(trivial_numeric_casts)]
|
||||||
#![warn(unused_import_braces, unstable_features)]
|
#![warn(unused_import_braces, unstable_features, unused_extern_crates)]
|
||||||
#![cfg_attr(feature="cargo-clippy", warn(
|
#![cfg_attr(feature="cargo-clippy", warn(
|
||||||
float_arithmetic,
|
float_arithmetic,
|
||||||
mut_mut,
|
mut_mut,
|
||||||
@@ -10,17 +10,25 @@
|
|||||||
use_self,
|
use_self,
|
||||||
))]
|
))]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate cfg_if;
|
||||||
extern crate cretonne_codegen;
|
extern crate cretonne_codegen;
|
||||||
extern crate cretonne_filetests;
|
extern crate cretonne_filetests;
|
||||||
extern crate cretonne_reader;
|
extern crate cretonne_reader;
|
||||||
extern crate cretonne_wasm;
|
|
||||||
extern crate docopt;
|
extern crate docopt;
|
||||||
extern crate filecheck;
|
extern crate filecheck;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
extern crate tempdir;
|
|
||||||
extern crate term;
|
|
||||||
extern crate capstone;
|
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 cretonne_codegen::{timing, VERSION};
|
||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
@@ -32,7 +40,6 @@ mod compile;
|
|||||||
mod print_cfg;
|
mod print_cfg;
|
||||||
mod rsfilecheck;
|
mod rsfilecheck;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod wasm;
|
|
||||||
|
|
||||||
const USAGE: &str = "
|
const USAGE: &str = "
|
||||||
Cretonne code generator utility
|
Cretonne code generator utility
|
||||||
@@ -114,7 +121,8 @@ fn cton_util() -> CommandResult {
|
|||||||
&args.flag_isa,
|
&args.flag_isa,
|
||||||
)
|
)
|
||||||
} else if args.cmd_wasm {
|
} else if args.cmd_wasm {
|
||||||
wasm::run(
|
#[cfg(feature = "wasm")]
|
||||||
|
let result = wasm::run(
|
||||||
args.arg_file,
|
args.arg_file,
|
||||||
args.flag_verbose,
|
args.flag_verbose,
|
||||||
args.flag_just_decode,
|
args.flag_just_decode,
|
||||||
@@ -123,7 +131,14 @@ fn cton_util() -> CommandResult {
|
|||||||
&args.flag_set,
|
&args.flag_set,
|
||||||
&args.flag_isa,
|
&args.flag_isa,
|
||||||
args.flag_print_size,
|
args.flag_print_size,
|
||||||
)
|
);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "wasm"))]
|
||||||
|
let result = Err(
|
||||||
|
"Error: cton-util was compiled without wasm support.".to_owned(),
|
||||||
|
);
|
||||||
|
|
||||||
|
result
|
||||||
} else {
|
} else {
|
||||||
// Debugging / shouldn't happen with proper command line handling above.
|
// Debugging / shouldn't happen with proper command line handling above.
|
||||||
Err(format!("Unhandled args: {:?}", args))
|
Err(format!("Unhandled args: {:?}", args))
|
||||||
|
|||||||
@@ -9,14 +9,11 @@ use cretonne_codegen::print_errors::{pretty_error, pretty_verifier_error};
|
|||||||
use cretonne_codegen::settings::FlagsOrIsa;
|
use cretonne_codegen::settings::FlagsOrIsa;
|
||||||
use cretonne_wasm::{translate_module, DummyEnvironment, ModuleEnvironment};
|
use cretonne_wasm::{translate_module, DummyEnvironment, ModuleEnvironment};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs::File;
|
|
||||||
use std::io;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
|
||||||
use tempdir::TempDir;
|
|
||||||
use term;
|
use term;
|
||||||
use utils::{parse_sets_and_isa, read_to_end};
|
use utils::{parse_sets_and_isa, read_to_end};
|
||||||
|
use wabt::wat2wasm;
|
||||||
|
|
||||||
macro_rules! vprintln {
|
macro_rules! vprintln {
|
||||||
($x: expr, $($tts:tt)*) => {
|
($x: expr, $($tts:tt)*) => {
|
||||||
@@ -85,23 +82,12 @@ fn handle_module(
|
|||||||
let mut data = read_to_end(path.clone()).map_err(|err| {
|
let mut data = read_to_end(path.clone()).map_err(|err| {
|
||||||
String::from(err.description())
|
String::from(err.description())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if !data.starts_with(&[b'\0', b'a', b's', b'm']) {
|
if !data.starts_with(&[b'\0', b'a', b's', b'm']) {
|
||||||
let tmp_dir = TempDir::new("cretonne-wasm").unwrap();
|
data = match wat2wasm(&data) {
|
||||||
let file_path = tmp_dir.path().join("module.wasm");
|
Ok(data) => data,
|
||||||
File::create(file_path.clone()).unwrap();
|
Err(e) => return Err(String::from(e.description())),
|
||||||
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()),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut dummy_environ = DummyEnvironment::with_flags(fisa.flags.clone());
|
let mut dummy_environ = DummyEnvironment::with_flags(fisa.flags.clone());
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ failure = { version = "0.1.1", default-features = false, features = ["derive"] }
|
|||||||
failure_derive = { version = "0.1.1", default-features = false }
|
failure_derive = { version = "0.1.1", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempdir = "0.3.5"
|
wabt = "0.3"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
extern crate cretonne_codegen;
|
extern crate cretonne_codegen;
|
||||||
extern crate cretonne_wasm;
|
extern crate cretonne_wasm;
|
||||||
extern crate tempdir;
|
extern crate wabt;
|
||||||
|
|
||||||
use cretonne_codegen::print_errors::pretty_verifier_error;
|
use cretonne_codegen::print_errors::pretty_verifier_error;
|
||||||
use cretonne_codegen::settings::{self, Configurable, Flags};
|
use cretonne_codegen::settings::{self, Configurable, Flags};
|
||||||
use cretonne_codegen::verifier;
|
use cretonne_codegen::verifier;
|
||||||
use cretonne_wasm::{translate_module, DummyEnvironment};
|
use cretonne_wasm::{translate_module, DummyEnvironment};
|
||||||
use std::error::Error;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::path::PathBuf;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use wabt::wat2wasm;
|
||||||
use std::str;
|
|
||||||
use tempdir::TempDir;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn testsuite() {
|
fn testsuite() {
|
||||||
@@ -44,57 +41,33 @@ fn return_at_end() {
|
|||||||
let mut flag_builder = settings::builder();
|
let mut flag_builder = settings::builder();
|
||||||
flag_builder.enable("return_at_end").unwrap();
|
flag_builder.enable("return_at_end").unwrap();
|
||||||
let flags = Flags::new(flag_builder);
|
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<Vec<u8>, io::Error> {
|
fn read_file(path: &Path) -> Result<Vec<u8>, io::Error> {
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
let mut file = File::open(path)?;
|
let mut file = File::open(path)?;
|
||||||
file.read_to_end(&mut buf)?;
|
file.read_to_end(&mut buf)?;
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_module(path: &PathBuf, flags: &Flags) {
|
fn handle_module(path: &Path, flags: &Flags) {
|
||||||
let data = match path.extension() {
|
let data = match path.extension() {
|
||||||
None => {
|
None => {
|
||||||
panic!("the file extension is not wasm or wat");
|
panic!("the file extension is not wasm or wat");
|
||||||
}
|
}
|
||||||
Some(ext) => {
|
Some(ext) => {
|
||||||
match ext.to_str() {
|
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") => {
|
Some("wat") => {
|
||||||
let tmp_dir = TempDir::new("cretonne-wasm").unwrap();
|
let wat = read_file(path).expect("error reading wat file");
|
||||||
let file_path = tmp_dir.path().join("module.wasm");
|
match wat2wasm(&wat) {
|
||||||
File::create(file_path.clone()).unwrap();
|
Ok(wasm) => wasm,
|
||||||
let result_output = Command::new("wat2wasm")
|
|
||||||
.arg(path.clone())
|
|
||||||
.arg("-o")
|
|
||||||
.arg(file_path.to_str().unwrap())
|
|
||||||
.output();
|
|
||||||
match result_output {
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if e.kind() == io::ErrorKind::NotFound {
|
panic!("error converting wat to wasm: {:?}", e);
|
||||||
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",
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_wasm_file(file_path).expect("error reading converted wasm file")
|
|
||||||
}
|
|
||||||
None | Some(&_) => panic!("the file extension for {:?} is not wasm or wat", path),
|
None | Some(&_) => panic!("the file extension for {:?} is not wasm or wat", path),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user