Migrate from failure to thiserror and anyhow (#436)

* Migrate from failure to thiserror and anyhow

The failure crate invents its own traits that don't use
std::error::Error (because failure predates certain features added to
Error); this prevents using ? on an error from failure in a function
using Error. The thiserror and anyhow crates integrate with the standard
Error trait instead.

This change does not attempt to semantically change or refactor the
approach to error-handling in any portion of the code, to ensure that
the change remains straightforward to review. Modules using specific
differentiated error types move from failure_derive and derive(Fail) to
thiserror and derive(Error). Modules boxing all errors opaquely move
from failure::Error to anyhow. Modules using String as an error type
continue to do so. Code using unwrap or expect continues to do so.

Drop Display implementations when thiserror can easily derive an
identical instance.

Drop manual traversal of iter_causes; anyhow's Debug instance prints the
chain of causes by default.

Use anyhow's type alias anyhow::Result<T> in place of
std::result::Result<T, anyhow::Error> whenever possible.

* wasm2obj: Simplify error handling using existing messages

handle_module in wasm2obj manually maps
cranelift_codegen::isa::LookupError values to strings, but LookupError
values already have strings that say almost exactly the same thing.
Rely on the strings from cranelift.

* wasmtime: Rely on question-mark-in-main

The main() wrapper around rmain() completely matches the behavior of
question-mark-in-main (print error to stderr and return 1), so switch to
question-mark-in-main.

* Update to walrus 0.13 and wasm-webidl-bindings 0.6

Both crates switched from failure to anyhow; updating lets us avoid a
translation from failure to anyhow within wasmtime-interface-types.
This commit is contained in:
Josh Triplett
2019-11-04 20:43:25 -08:00
committed by Dan Gohman
parent 0108622c7d
commit 56ce6e9c9f
53 changed files with 238 additions and 326 deletions

View File

@@ -11,10 +11,10 @@ edition = "2018"
default-run = "wasmtime" default-run = "wasmtime"
[dependencies] [dependencies]
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
cranelift-native = "0.46.1" cranelift-native = { version = "0.47" }
wasmtime-api = { path = "wasmtime-api" } wasmtime-api = { path = "wasmtime-api" }
wasmtime-debug = { path = "wasmtime-debug" } wasmtime-debug = { path = "wasmtime-debug" }
wasmtime-environ = { path = "wasmtime-environ" } wasmtime-environ = { path = "wasmtime-environ" }
@@ -29,14 +29,14 @@ wasi-common = { git = "https://github.com/CraneStation/wasi-common", rev = "37ce
docopt = "1.0.1" docopt = "1.0.1"
serde = { "version" = "1.0.94", features = ["derive"] } serde = { "version" = "1.0.94", features = ["derive"] }
faerie = "0.11.0" faerie = "0.11.0"
failure = "0.1" anyhow = "1.0.19"
target-lexicon = { version = "0.8.1", default-features = false } target-lexicon = { version = "0.8.1", default-features = false }
pretty_env_logger = "0.3.0" pretty_env_logger = "0.3.0"
file-per-thread-logger = "0.1.1" file-per-thread-logger = "0.1.1"
wat = "1.0.2" wat = "1.0.2"
libc = "0.2.60" libc = "0.2.60"
rayon = "1.1" rayon = "1.1"
wasm-webidl-bindings = "0.5" wasm-webidl-bindings = "0.6"
# build.rs tests whether to enable a workaround for the libc strtof function. # build.rs tests whether to enable a workaround for the libc strtof function.
[target.'cfg(target_os = "linux")'.build-dependencies] [target.'cfg(target_os = "linux")'.build-dependencies]

View File

@@ -11,9 +11,9 @@ cargo-fuzz = true
[dependencies] [dependencies]
wasmtime-environ = { path = "../wasmtime-environ" } wasmtime-environ = { path = "../wasmtime-environ" }
wasmtime-jit = { path = "../wasmtime-jit" } wasmtime-jit = { path = "../wasmtime-jit" }
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
cranelift-native = "0.46.1" cranelift-native = { version = "0.47" }
libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git" } libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git" }
wasmparser = { version = "0.39.2", default-features = false } wasmparser = { version = "0.39.2", default-features = false }
binaryen = "0.5.0" binaryen = "0.5.0"

View File

@@ -17,9 +17,8 @@ wasmparser = "0.39.1"
memoffset = "0.5.1" memoffset = "0.5.1"
itertools = "0.8" itertools = "0.8"
capstone = "0.6.0" capstone = "0.6.0"
failure = "0.1.3" thiserror = "1.0.4"
failure_derive = "0.1.3" cranelift-codegen = { version = "0.47" }
cranelift-codegen = "0.46.1"
multi_mut = "0.1" multi_mut = "0.1"
either = "1.5" either = "1.5"
typemap = "0.3" typemap = "0.3"

View File

@@ -1,15 +1,16 @@
use capstone; use capstone;
use thiserror::Error;
use wasmparser::BinaryReaderError; use wasmparser::BinaryReaderError;
#[derive(Fail, PartialEq, Eq, Clone, Debug)] #[derive(Error, PartialEq, Eq, Clone, Debug)]
pub enum Error { pub enum Error {
#[fail(display = "Disassembler error: {}", _0)] #[error("Disassembler error: {0}")]
Disassembler(String), Disassembler(String),
#[fail(display = "Assembler error: {}", _0)] #[error("Assembler error: {0}")]
Assembler(String), Assembler(String),
#[fail(display = "Input error: {}", _0)] #[error("Input error: {0}")]
Input(String), Input(String),
} }

View File

@@ -5,11 +5,8 @@
extern crate smallvec; extern crate smallvec;
extern crate capstone; extern crate capstone;
extern crate either; extern crate either;
extern crate failure;
pub extern crate wasmparser; pub extern crate wasmparser;
#[macro_use] #[macro_use]
extern crate failure_derive;
#[macro_use]
extern crate memoffset; extern crate memoffset;
extern crate dynasm; extern crate dynasm;
extern crate dynasmrt; extern crate dynasmrt;

View File

@@ -12,17 +12,17 @@ name = "_wasmtime"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
cranelift-codegen = "0.46.1" cranelift-codegen = { version = "0.47" }
cranelift-native = "0.46.1" cranelift-native = { version = "0.47" }
cranelift-entity = "0.46.1" cranelift-entity = { version = "0.47" }
cranelift-wasm = "0.46.1" cranelift-wasm = { version = "0.47" }
cranelift-frontend = "0.46.1" cranelift-frontend = { version = "0.47" }
wasmtime-environ = { path = "../../wasmtime-environ" } wasmtime-environ = { path = "../../wasmtime-environ" }
wasmtime-interface-types = { path = "../../wasmtime-interface-types" } wasmtime-interface-types = { path = "../../wasmtime-interface-types" }
wasmtime-jit = { path = "../../wasmtime-jit" } wasmtime-jit = { path = "../../wasmtime-jit" }
wasmtime-runtime = { path = "../../wasmtime-runtime" } wasmtime-runtime = { path = "../../wasmtime-runtime" }
target-lexicon = { version = "0.8.1", default-features = false } target-lexicon = { version = "0.8.1", default-features = false }
failure = "0.1" anyhow = "1.0.19"
region = "2.0.0" region = "2.0.0"
wasmparser = "0.39.2" wasmparser = "0.39.2"

View File

@@ -18,14 +18,8 @@ mod memory;
mod module; mod module;
mod value; mod value;
fn err2py(err: failure::Error) -> PyErr { fn err2py(err: anyhow::Error) -> PyErr {
let mut desc = err.to_string(); PyErr::new::<Exception, _>(format!("{:?}", err))
for cause in err.iter_causes() {
desc.push_str("\n");
desc.push_str(" caused by: ");
desc.push_str(&cause.to_string());
}
PyErr::new::<Exception, _>(desc)
} }
#[pyclass] #[pyclass]

View File

@@ -12,9 +12,9 @@ test = false
doctest = false doctest = false
[dependencies] [dependencies]
cranelift-codegen = "0.46.1" cranelift-codegen = { version = "0.47" }
cranelift-native = "0.46.1" cranelift-native = { version = "0.47" }
failure = "0.1.5"
wasmtime-interface-types = { path = "../../wasmtime-interface-types" } wasmtime-interface-types = { path = "../../wasmtime-interface-types" }
wasmtime-jit = { path = "../../wasmtime-jit" } wasmtime-jit = { path = "../../wasmtime-jit" }
wasmtime-rust-macro = { path = "./macro" } wasmtime-rust-macro = { path = "./macro" }
anyhow = "1.0.19"

View File

@@ -10,7 +10,7 @@ trait WasmMarkdown {
fn render(&mut self, input: &str) -> String; fn render(&mut self, input: &str) -> String;
} }
fn main() -> Result<(), failure::Error> { fn main() -> anyhow::Result<()> {
let mut markdown = WasmMarkdown::load_file("markdown.wasm")?; let mut markdown = WasmMarkdown::load_file("markdown.wasm")?;
println!("{}", markdown.render("# Hello, Rust!")); println!("{}", markdown.render("# Hello, Rust!"));

View File

@@ -5,7 +5,7 @@ trait WasmMarkdown {
fn render(&mut self, input: &str) -> String; fn render(&mut self, input: &str) -> String;
} }
fn main() -> Result<(), failure::Error> { fn main() -> anyhow::Result<()> {
let mut markdown = WasmMarkdown::load_file("markdown.wasm")?; let mut markdown = WasmMarkdown::load_file("markdown.wasm")?;
println!("{}", markdown.render("# Hello, Rust!")); println!("{}", markdown.render("# Hello, Rust!"));

View File

@@ -46,12 +46,12 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
let name = &item.ident; let name = &item.ident;
let root = root(); let root = root();
Ok(quote! { Ok(quote! {
#vis fn load_file(path: impl AsRef<std::path::Path>) -> Result<#name, #root::failure::Error> { #vis fn load_file(path: impl AsRef<std::path::Path>) -> #root::anyhow::Result<#name> {
let bytes = std::fs::read(path)?; let bytes = std::fs::read(path)?;
let isa = { let isa = {
let isa_builder = #root::cranelift_native::builder() let isa_builder = #root::cranelift_native::builder()
.map_err(|s| #root::failure::format_err!("{}", s))?; .map_err(|s| #root::anyhow::format_err!("{}", s))?;
let flag_builder = #root::cranelift_codegen::settings::builder(); let flag_builder = #root::cranelift_codegen::settings::builder();
isa_builder.finish(#root::cranelift_codegen::settings::Flags::new(flag_builder)) isa_builder.finish(#root::cranelift_codegen::settings::Flags::new(flag_builder))
}; };

View File

@@ -3,9 +3,9 @@ pub use wasmtime_rust_macro::wasmtime;
// modules used by the macro // modules used by the macro
#[doc(hidden)] #[doc(hidden)]
pub mod __rt { pub mod __rt {
pub use anyhow;
pub use cranelift_codegen; pub use cranelift_codegen;
pub use cranelift_native; pub use cranelift_native;
pub use failure;
pub use wasmtime_interface_types; pub use wasmtime_interface_types;
pub use wasmtime_jit; pub use wasmtime_jit;
@@ -13,24 +13,24 @@ pub mod __rt {
use wasmtime_interface_types::Value; use wasmtime_interface_types::Value;
pub trait FromVecValue: Sized { pub trait FromVecValue: Sized {
fn from(list: Vec<Value>) -> Result<Self, failure::Error>; fn from(list: Vec<Value>) -> anyhow::Result<Self>;
} }
macro_rules! tuple { macro_rules! tuple {
($(($($a:ident),*),)*) => ($( ($(($($a:ident),*),)*) => ($(
impl<$($a: TryFrom<Value>),*> FromVecValue for ($($a,)*) impl<$($a: TryFrom<Value>),*> FromVecValue for ($($a,)*)
where $(failure::Error: From<$a::Error>,)* where $(anyhow::Error: From<$a::Error>,)*
{ {
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn from(list: Vec<Value>) -> Result<Self, failure::Error> { fn from(list: Vec<Value>) -> anyhow::Result<Self> {
let mut iter = list.into_iter(); let mut iter = list.into_iter();
$( $(
let $a = iter.next() let $a = iter.next()
.ok_or_else(|| failure::format_err!("not enough values"))? .ok_or_else(|| anyhow::format_err!("not enough values"))?
.try_into()?; .try_into()?;
)* )*
if iter.next().is_some() { if iter.next().is_some() {
failure::format_err!("too many return values"); anyhow::bail!("too many return values");
} }
Ok(($($a,)*)) Ok(($($a,)*))
} }

View File

@@ -203,12 +203,7 @@ fn handle_module(
let isa_builder = match *target { let isa_builder = match *target {
Some(ref target) => { Some(ref target) => {
let target = Triple::from_str(&target).map_err(|_| "could not parse --target")?; let target = Triple::from_str(&target).map_err(|_| "could not parse --target")?;
isa::lookup(target).map_err(|err| match err { isa::lookup(target).map_err(|err| format!("{:?}", err))?
isa::LookupError::SupportDisabled => {
"support for architecture disabled at compile time"
}
isa::LookupError::Unsupported => "unsupported architecture",
})?
} }
None => cranelift_native::builder().unwrap_or_else(|_| { None => cranelift_native::builder().unwrap_or_else(|_| {
panic!("host machine is not a supported target"); panic!("host machine is not a supported target");

View File

@@ -30,10 +30,10 @@
) )
)] )]
use anyhow::{bail, Context as _, Result};
use cranelift_codegen::settings; use cranelift_codegen::settings;
use cranelift_codegen::settings::Configurable; use cranelift_codegen::settings::Configurable;
use docopt::Docopt; use docopt::Docopt;
use failure::{bail, Error, ResultExt};
use pretty_env_logger; use pretty_env_logger;
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap; use std::collections::HashMap;
@@ -185,19 +185,7 @@ fn compute_environ(flag_env: &[String]) -> Vec<(String, String)> {
result result
} }
fn main() { fn main() -> Result<()> {
let err = match rmain() {
Ok(()) => return,
Err(e) => e,
};
eprintln!("error: {}", err);
for cause in err.iter_causes() {
eprintln!(" caused by: {}", cause);
}
exit(1);
}
fn rmain() -> Result<(), Error> {
let version = env!("CARGO_PKG_VERSION"); let version = env!("CARGO_PKG_VERSION");
let args: Args = Docopt::new(USAGE) let args: Args = Docopt::new(USAGE)
.and_then(|d| { .and_then(|d| {
@@ -324,13 +312,13 @@ fn rmain() -> Result<(), Error> {
for filename in &args.flag_preload { for filename in &args.flag_preload {
let path = Path::new(&filename); let path = Path::new(&filename);
instantiate_module(store.clone(), &module_registry, path) instantiate_module(store.clone(), &module_registry, path)
.with_context(|_| format!("failed to process preload at `{}`", path.display()))?; .with_context(|| format!("failed to process preload at `{}`", path.display()))?;
} }
// Load the main wasm module. // Load the main wasm module.
let path = Path::new(&args.arg_file); let path = Path::new(&args.arg_file);
handle_module(store, &module_registry, &args, path) handle_module(store, &module_registry, &args, path)
.with_context(|_| format!("failed to process main module `{}`", path.display()))?; .with_context(|| format!("failed to process main module `{}`", path.display()))?;
Ok(()) Ok(())
} }
@@ -338,7 +326,7 @@ fn instantiate_module(
store: HostRef<Store>, store: HostRef<Store>,
module_registry: &HashMap<String, (Instance, HashMap<String, usize>)>, module_registry: &HashMap<String, (Instance, HashMap<String, usize>)>,
path: &Path, path: &Path,
) -> Result<(HostRef<Instance>, HostRef<Module>, Vec<u8>), Error> { ) -> Result<(HostRef<Instance>, HostRef<Module>, Vec<u8>)> {
// Read the wasm module binary either as `*.wat` or a raw binary // Read the wasm module binary either as `*.wat` or a raw binary
let data = wat::parse_file(path.to_path_buf())?; let data = wat::parse_file(path.to_path_buf())?;
@@ -378,7 +366,7 @@ fn handle_module(
module_registry: &HashMap<String, (Instance, HashMap<String, usize>)>, module_registry: &HashMap<String, (Instance, HashMap<String, usize>)>,
args: &Args, args: &Args,
path: &Path, path: &Path,
) -> Result<(), Error> { ) -> Result<()> {
let (instance, _module, data) = instantiate_module(store.clone(), module_registry, path)?; let (instance, _module, data) = instantiate_module(store.clone(), module_registry, path)?;
// If a function to invoke was given, invoke it. // If a function to invoke was given, invoke it.
@@ -396,7 +384,7 @@ fn invoke_export(
data: &ModuleData, data: &ModuleData,
name: &str, name: &str,
args: &Args, args: &Args,
) -> Result<(), Error> { ) -> Result<()> {
use wasm_webidl_bindings::ast; use wasm_webidl_bindings::ast;
use wasmtime_interface_types::Value; use wasmtime_interface_types::Value;
@@ -445,7 +433,7 @@ fn invoke_export(
let mut context = store.borrow().engine().borrow().create_wasmtime_context(); let mut context = store.borrow().engine().borrow().create_wasmtime_context();
let results = data let results = data
.invoke(&mut context, &mut handle, name, &values) .invoke(&mut context, &mut handle, name, &values)
.with_context(|_| format!("failed to invoke `{}`", name))?; .with_context(|| format!("failed to invoke `{}`", name))?;
if results.len() > 0 { if results.len() > 0 {
eprintln!( eprintln!(
"warning: using `--render` with a function that returns values \ "warning: using `--render` with a function that returns values \

View File

@@ -12,18 +12,18 @@ name = "wasmtime_api"
crate-type = ["lib", "staticlib", "cdylib"] crate-type = ["lib", "staticlib", "cdylib"]
[dependencies] [dependencies]
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-native = "0.46.1" cranelift-native = { version = "0.47" }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
cranelift-frontend = "0.46.1" cranelift-frontend = { version = "0.47" }
wasmtime-runtime = { path="../wasmtime-runtime" } wasmtime-runtime = { path="../wasmtime-runtime" }
wasmtime-environ = { path="../wasmtime-environ" } wasmtime-environ = { path="../wasmtime-environ" }
wasmtime-jit = { path="../wasmtime-jit" } wasmtime-jit = { path="../wasmtime-jit" }
wasmparser = { version = "0.39.2", default-features = false } wasmparser = { version = "0.39.2", default-features = false }
failure = { version = "0.1.3", default-features = false }
failure_derive = { version = "0.1.3", default-features = false }
target-lexicon = { version = "0.8.1", default-features = false } target-lexicon = { version = "0.8.1", default-features = false }
anyhow = "1.0.19"
thiserror = "1.0.4"
region = "2.0.0" region = "2.0.0"
hashbrown = { version = "0.6.0", optional = true } hashbrown = { version = "0.6.0", optional = true }

View File

@@ -1,11 +1,11 @@
//! Example of instantiating of the WebAssembly module and //! Example of instantiating of the WebAssembly module and
//! invoking its exported function. //! invoking its exported function.
use failure::{format_err, Error}; use anyhow::{format_err, Result};
use std::fs::read; use std::fs::read;
use wasmtime_api::*; use wasmtime_api::*;
fn main() -> Result<(), Error> { fn main() -> Result<()> {
let wasm = read("examples/gcd.wasm")?; let wasm = read("examples/gcd.wasm")?;
// Instantiate engine and store. // Instantiate engine and store.

View File

@@ -3,8 +3,8 @@
extern crate alloc; extern crate alloc;
use alloc::rc::Rc; use alloc::rc::Rc;
use anyhow::{ensure, format_err, Context as _, Result};
use core::cell::Ref; use core::cell::Ref;
use failure::{bail, format_err, Error};
use std::fs::read; use std::fs::read;
use wasmtime_api::*; use wasmtime_api::*;
@@ -18,7 +18,7 @@ impl Callable for HelloCallback {
} }
} }
fn main() -> Result<(), Error> { fn main() -> Result<()> {
// Initialize. // Initialize.
println!("Initializing..."); println!("Initializing...");
let engine = HostRef::new(Engine::new(Config::default())); let engine = HostRef::new(Engine::new(Config::default()));
@@ -30,10 +30,8 @@ fn main() -> Result<(), Error> {
// Compile. // Compile.
println!("Compiling module..."); println!("Compiling module...");
let module = HostRef::new( let module =
Module::new(store.clone(), &binary) HostRef::new(Module::new(store.clone(), &binary).context("> Error compiling module!")?);
.map_err(|_| format_err!("> Error compiling module!"))?,
);
// Create external print functions. // Create external print functions.
println!("Creating callback..."); println!("Creating callback...");
@@ -45,24 +43,21 @@ fn main() -> Result<(), Error> {
let imports = vec![hello_func.into()]; let imports = vec![hello_func.into()];
let instance = HostRef::new( let instance = HostRef::new(
Instance::new(store.clone(), module, imports.as_slice()) Instance::new(store.clone(), module, imports.as_slice())
.map_err(|_| format_err!("> Error instantiating module!"))?, .context("> Error instantiating module!")?,
); );
// Extract export. // Extract export.
println!("Extracting export..."); println!("Extracting export...");
let exports = Ref::map(instance.borrow(), |instance| instance.exports()); let exports = Ref::map(instance.borrow(), |instance| instance.exports());
if exports.len() == 0 { ensure!(!exports.is_empty(), "> Error accessing exports!");
bail!("> Error accessing exports!"); let run_func = exports[0].func().context("> Error accessing exports!")?;
}
let run_func = exports[0]
.func()
.ok_or_else(|| format_err!("> Error accessing exports!"))?;
// Call. // Call.
println!("Calling export..."); println!("Calling export...");
if let Err(_) = run_func.borrow().call(&[]) { run_func
bail!("> Error calling function!"); .borrow()
} .call(&[])
.map_err(|e| format_err!("> Error calling function: {:?}", e))?;
// Shut down. // Shut down.
println!("Shutting down..."); println!("Shutting down...");

View File

@@ -1,7 +1,7 @@
//! Translation of the memory example //! Translation of the memory example
use anyhow::{bail, ensure, Context as _, Error};
use core::cell::Ref; use core::cell::Ref;
use failure::{bail, format_err, Error};
use std::fs::read; use std::fs::read;
use wasmtime_api::*; use wasmtime_api::*;
@@ -11,7 +11,7 @@ fn get_export_memory(exports: &[Extern], i: usize) -> Result<HostRef<Memory>, Er
} }
Ok(exports[i] Ok(exports[i]
.memory() .memory()
.ok_or_else(|| format_err!("> Error accessing memory export {}!", i))? .with_context(|| format!("> Error accessing memory export {}!", i))?
.clone()) .clone())
} }
@@ -21,7 +21,7 @@ fn get_export_func(exports: &[Extern], i: usize) -> Result<HostRef<Func>, Error>
} }
Ok(exports[i] Ok(exports[i]
.func() .func()
.ok_or_else(|| format_err!("> Error accessing function export {}!", i))? .with_context(|| format!("> Error accessing function export {}!", i))?
.clone()) .clone())
} }
@@ -73,24 +73,19 @@ fn main() -> Result<(), Error> {
// Compile. // Compile.
println!("Compiling module..."); println!("Compiling module...");
let module = HostRef::new( let module =
Module::new(store.clone(), &binary) HostRef::new(Module::new(store.clone(), &binary).context("> Error compiling module!")?);
.map_err(|_| format_err!("> Error compiling module!"))?,
);
// Instantiate. // Instantiate.
println!("Instantiating module..."); println!("Instantiating module...");
let instance = HostRef::new( let instance = HostRef::new(
Instance::new(store.clone(), module, &[]) Instance::new(store.clone(), module, &[]).context("> Error instantiating module!")?,
.map_err(|_| format_err!("> Error instantiating module!"))?,
); );
// Extract export. // Extract export.
println!("Extracting export..."); println!("Extracting export...");
let exports = Ref::map(instance.borrow(), |instance| instance.exports()); let exports = Ref::map(instance.borrow(), |instance| instance.exports());
if exports.len() == 0 { ensure!(!exports.is_empty(), "> Error accessing exports!");
bail!("> Error accessing exports!");
}
let memory = get_export_memory(&exports, 0)?; let memory = get_export_memory(&exports, 0)?;
let size_func = get_export_func(&exports, 1)?; let size_func = get_export_func(&exports, 1)?;
let load_func = get_export_func(&exports, 2)?; let load_func = get_export_func(&exports, 2)?;

View File

@@ -3,8 +3,8 @@
extern crate alloc; extern crate alloc;
use alloc::rc::Rc; use alloc::rc::Rc;
use anyhow::{ensure, format_err, Context as _, Result};
use core::cell::Ref; use core::cell::Ref;
use failure::{bail, format_err, Error};
use std::fs::read; use std::fs::read;
use wasmtime_api::*; use wasmtime_api::*;
@@ -21,7 +21,7 @@ impl Callable for Callback {
} }
} }
fn main() -> Result<(), Error> { fn main() -> Result<()> {
// Initialize. // Initialize.
println!("Initializing..."); println!("Initializing...");
let engine = HostRef::new(Engine::new(Config::default())); let engine = HostRef::new(Engine::new(Config::default()));
@@ -33,10 +33,8 @@ fn main() -> Result<(), Error> {
// Compile. // Compile.
println!("Compiling module..."); println!("Compiling module...");
let module = HostRef::new( let module =
Module::new(store.clone(), &binary) HostRef::new(Module::new(store.clone(), &binary).context("Error compiling module!")?);
.map_err(|_| format_err!("> Error compiling module!"))?,
);
// Create external print functions. // Create external print functions.
println!("Creating callback..."); println!("Creating callback...");
@@ -51,28 +49,23 @@ fn main() -> Result<(), Error> {
let imports = vec![callback_func.into()]; let imports = vec![callback_func.into()];
let instance = HostRef::new( let instance = HostRef::new(
Instance::new(store.clone(), module, imports.as_slice()) Instance::new(store.clone(), module, imports.as_slice())
.map_err(|_| format_err!("> Error instantiating module!"))?, .context("Error instantiating module!")?,
); );
// Extract export. // Extract export.
println!("Extracting export..."); println!("Extracting export...");
let exports = Ref::map(instance.borrow(), |instance| instance.exports()); let exports = Ref::map(instance.borrow(), |instance| instance.exports());
if exports.len() == 0 { ensure!(!exports.is_empty(), "Error accessing exports!");
bail!("> Error accessing exports!"); let run_func = exports[0].func().context("Error accessing exports!")?;
}
let run_func = exports[0]
.func()
.ok_or_else(|| format_err!("> Error accessing exports!"))?;
// Call. // Call.
println!("Calling export..."); println!("Calling export...");
let args = vec![Val::I32(1), Val::I64(3)]; let args = vec![Val::I32(1), Val::I64(3)];
let results = run_func.borrow().call(&args); let results = run_func
if let Err(_) = results { .borrow()
bail!("> Error calling function!"); .call(&args)
} .map_err(|e| format_err!("> Error calling function: {:?}", e))?;
let results = results.unwrap();
println!("Printing result..."); println!("Printing result...");
println!("> {} {}", results[0].i64(), results[1].i32()); println!("> {} {}", results[0].i64(), results[1].i32());

View File

@@ -9,8 +9,8 @@ use alloc::boxed::Box;
use alloc::rc::Rc; use alloc::rc::Rc;
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};
use alloc::vec::Vec; use alloc::vec::Vec;
use anyhow::Result;
use core::cell::RefCell; use core::cell::RefCell;
use failure::Error;
use wasmtime_jit::{instantiate, Resolver}; use wasmtime_jit::{instantiate, Resolver};
use wasmtime_runtime::{Export, InstanceHandle}; use wasmtime_runtime::{Export, InstanceHandle};
@@ -34,7 +34,7 @@ pub fn instantiate_in_context(
imports: Vec<(String, String, Extern)>, imports: Vec<(String, String, Extern)>,
mut context: Context, mut context: Context,
exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>, exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>,
) -> Result<(InstanceHandle, HashSet<Context>), Error> { ) -> Result<(InstanceHandle, HashSet<Context>)> {
let mut contexts = HashSet::new(); let mut contexts = HashSet::new();
let debug_info = context.debug_info(); let debug_info = context.debug_info();
let mut resolver = SimpleResolver { imports }; let mut resolver = SimpleResolver { imports };
@@ -64,7 +64,7 @@ impl Instance {
store: HostRef<Store>, store: HostRef<Store>,
module: HostRef<Module>, module: HostRef<Module>,
externs: &[Extern], externs: &[Extern],
) -> Result<Instance, Error> { ) -> Result<Instance> {
let context = store.borrow_mut().context().clone(); let context = store.borrow_mut().context().clone();
let exports = store.borrow_mut().global_exports().clone(); let exports = store.borrow_mut().global_exports().clone();
let imports = module let imports = module
@@ -105,7 +105,7 @@ impl Instance {
pub fn from_handle( pub fn from_handle(
store: HostRef<Store>, store: HostRef<Store>,
instance_handle: InstanceHandle, instance_handle: InstanceHandle,
) -> Result<(Instance, HashMap<String, usize>), Error> { ) -> Result<(Instance, HashMap<String, usize>)> {
let contexts = HashSet::new(); let contexts = HashSet::new();
let mut exports = Vec::new(); let mut exports = Vec::new();

View File

@@ -17,8 +17,6 @@ mod values;
#[cfg(feature = "wasm-c-api")] #[cfg(feature = "wasm-c-api")]
pub mod wasm; pub mod wasm;
#[macro_use]
extern crate failure_derive;
#[macro_use] #[macro_use]
extern crate alloc; extern crate alloc;

View File

@@ -7,7 +7,7 @@ use crate::types::{
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::string::String; use alloc::string::String;
use alloc::vec::Vec; use alloc::vec::Vec;
use failure::Error; use anyhow::Result;
use wasmparser::{validate, ExternalKind, ImportSectionEntryType, ModuleReader, SectionCode}; use wasmparser::{validate, ExternalKind, ImportSectionEntryType, ModuleReader, SectionCode};
@@ -61,9 +61,7 @@ fn into_table_type(tt: wasmparser::TableType) -> TableType {
TableType::new(ty, limits) TableType::new(ty, limits)
} }
fn read_imports_and_exports( fn read_imports_and_exports(binary: &[u8]) -> Result<(Box<[ImportType]>, Box<[ExportType]>)> {
binary: &[u8],
) -> Result<(Box<[ImportType]>, Box<[ExportType]>), Error> {
let mut reader = ModuleReader::new(binary)?; let mut reader = ModuleReader::new(binary)?;
let mut imports = Vec::new(); let mut imports = Vec::new();
let mut exports = Vec::new(); let mut exports = Vec::new();
@@ -184,7 +182,7 @@ pub struct Module {
} }
impl Module { impl Module {
pub fn new(store: HostRef<Store>, binary: &[u8]) -> Result<Module, Error> { pub fn new(store: HostRef<Store>, binary: &[u8]) -> Result<Module> {
let (imports, exports) = read_imports_and_exports(binary)?; let (imports, exports) = read_imports_and_exports(binary)?;
Ok(Module { Ok(Module {
store, store,

View File

@@ -1,9 +1,9 @@
//! Support for a calling of an imported function. //! Support for a calling of an imported function.
use anyhow::Result;
use cranelift_entity::PrimaryMap; use cranelift_entity::PrimaryMap;
use cranelift_wasm::DefinedFuncIndex; use cranelift_wasm::DefinedFuncIndex;
//use target_lexicon::HOST; //use target_lexicon::HOST;
use failure::Error;
use wasmtime_environ::Module; use wasmtime_environ::Module;
use wasmtime_runtime::{Imports, InstanceHandle, VMFunctionBody}; use wasmtime_runtime::{Imports, InstanceHandle, VMFunctionBody};
@@ -22,7 +22,7 @@ pub(crate) fn create_handle(
signature_registry: Option<RefMut<Store>>, signature_registry: Option<RefMut<Store>>,
finished_functions: PrimaryMap<DefinedFuncIndex, *const VMFunctionBody>, finished_functions: PrimaryMap<DefinedFuncIndex, *const VMFunctionBody>,
state: Box<dyn Any>, state: Box<dyn Any>,
) -> Result<InstanceHandle, Error> { ) -> Result<InstanceHandle> {
let global_exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>> = let global_exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>> =
Rc::new(RefCell::new(HashMap::new())); Rc::new(RefCell::new(HashMap::new()));

View File

@@ -1,6 +1,7 @@
//! Support for a calling of an imported function. //! Support for a calling of an imported function.
use crate::r#ref::HostRef; use crate::r#ref::HostRef;
use anyhow::Result;
use cranelift_codegen::ir::types; use cranelift_codegen::ir::types;
use cranelift_codegen::ir::{InstBuilder, StackSlotData, StackSlotKind, TrapCode}; use cranelift_codegen::ir::{InstBuilder, StackSlotData, StackSlotKind, TrapCode};
use cranelift_codegen::Context; use cranelift_codegen::Context;
@@ -9,7 +10,6 @@ use cranelift_entity::{EntityRef, PrimaryMap};
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use cranelift_wasm::{DefinedFuncIndex, FuncIndex}; use cranelift_wasm::{DefinedFuncIndex, FuncIndex};
//use target_lexicon::HOST; //use target_lexicon::HOST;
use failure::Error;
use wasmtime_environ::{Export, Module}; use wasmtime_environ::{Export, Module};
use wasmtime_jit::CodeMemory; use wasmtime_jit::CodeMemory;
use wasmtime_runtime::{InstanceHandle, VMContext, VMFunctionBody}; use wasmtime_runtime::{InstanceHandle, VMContext, VMFunctionBody};
@@ -195,7 +195,7 @@ pub fn create_handle_with_function(
ft: &FuncType, ft: &FuncType,
func: &Rc<dyn Callable + 'static>, func: &Rc<dyn Callable + 'static>,
store: &HostRef<Store>, store: &HostRef<Store>,
) -> Result<InstanceHandle, Error> { ) -> Result<InstanceHandle> {
let sig = ft.get_cranelift_signature().clone(); let sig = ft.get_cranelift_signature().clone();
let isa = { let isa = {

View File

@@ -1,6 +1,6 @@
use alloc::boxed::Box; use alloc::boxed::Box;
use anyhow::Result;
use cranelift_entity::PrimaryMap; use cranelift_entity::PrimaryMap;
use failure::Error;
use wasmtime_environ::Module; use wasmtime_environ::Module;
use wasmtime_runtime::{InstanceHandle, VMGlobalDefinition}; use wasmtime_runtime::{InstanceHandle, VMGlobalDefinition};
@@ -13,10 +13,7 @@ pub struct GlobalState {
handle: InstanceHandle, handle: InstanceHandle,
} }
pub fn create_global( pub fn create_global(gt: &GlobalType, val: Val) -> Result<(wasmtime_runtime::Export, GlobalState)> {
gt: &GlobalType,
val: Val,
) -> Result<(wasmtime_runtime::Export, GlobalState), Error> {
let mut definition = Box::new(VMGlobalDefinition::new()); let mut definition = Box::new(VMGlobalDefinition::new());
unsafe { unsafe {
match val { match val {

View File

@@ -1,7 +1,7 @@
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::string::ToString; use alloc::string::ToString;
use anyhow::Result;
use cranelift_entity::PrimaryMap; use cranelift_entity::PrimaryMap;
use failure::Error;
use wasmtime_environ::Module; use wasmtime_environ::Module;
use wasmtime_runtime::InstanceHandle; use wasmtime_runtime::InstanceHandle;
@@ -10,7 +10,7 @@ use crate::MemoryType;
#[allow(dead_code)] #[allow(dead_code)]
pub fn create_handle_with_memory(memory: &MemoryType) -> Result<InstanceHandle, Error> { pub fn create_handle_with_memory(memory: &MemoryType) -> Result<InstanceHandle> {
let mut module = Module::new(); let mut module = Module::new();
let memory = cranelift_wasm::Memory { let memory = cranelift_wasm::Memory {

View File

@@ -8,7 +8,7 @@ mod table;
use crate::r#ref::HostRef; use crate::r#ref::HostRef;
use alloc::rc::Rc; use alloc::rc::Rc;
use failure::Error; use anyhow::Result;
use self::func::create_handle_with_function; use self::func::create_handle_with_function;
use self::global::create_global; use self::global::create_global;
@@ -22,7 +22,7 @@ pub fn generate_func_export(
ft: &FuncType, ft: &FuncType,
func: &Rc<dyn Callable + 'static>, func: &Rc<dyn Callable + 'static>,
store: &HostRef<Store>, store: &HostRef<Store>,
) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export), Error> { ) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export)> {
let mut instance = create_handle_with_function(ft, func, store)?; let mut instance = create_handle_with_function(ft, func, store)?;
let export = instance.lookup("trampoline").expect("trampoline export"); let export = instance.lookup("trampoline").expect("trampoline export");
Ok((instance, export)) Ok((instance, export))
@@ -31,13 +31,13 @@ pub fn generate_func_export(
pub fn generate_global_export( pub fn generate_global_export(
gt: &GlobalType, gt: &GlobalType,
val: Val, val: Val,
) -> Result<(wasmtime_runtime::Export, GlobalState), Error> { ) -> Result<(wasmtime_runtime::Export, GlobalState)> {
create_global(gt, val) create_global(gt, val)
} }
pub fn generate_memory_export( pub fn generate_memory_export(
m: &MemoryType, m: &MemoryType,
) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export), Error> { ) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export)> {
let mut instance = create_handle_with_memory(m)?; let mut instance = create_handle_with_memory(m)?;
let export = instance.lookup("memory").expect("memory export"); let export = instance.lookup("memory").expect("memory export");
Ok((instance, export)) Ok((instance, export))
@@ -45,7 +45,7 @@ pub fn generate_memory_export(
pub fn generate_table_export( pub fn generate_table_export(
t: &TableType, t: &TableType,
) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export), Error> { ) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export)> {
let mut instance = create_handle_with_table(t)?; let mut instance = create_handle_with_table(t)?;
let export = instance.lookup("table").expect("table export"); let export = instance.lookup("table").expect("table export");
Ok((instance, export)) Ok((instance, export))

View File

@@ -1,15 +1,15 @@
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::string::ToString; use alloc::string::ToString;
use anyhow::Result;
use cranelift_entity::PrimaryMap; use cranelift_entity::PrimaryMap;
use cranelift_wasm::TableElementType; use cranelift_wasm::TableElementType;
use failure::Error;
use wasmtime_environ::Module; use wasmtime_environ::Module;
use wasmtime_runtime::InstanceHandle; use wasmtime_runtime::InstanceHandle;
use super::create_handle::create_handle; use super::create_handle::create_handle;
use crate::{TableType, ValType}; use crate::{TableType, ValType};
pub fn create_handle_with_table(table: &TableType) -> Result<InstanceHandle, Error> { pub fn create_handle_with_table(table: &TableType) -> Result<InstanceHandle> {
let mut module = Module::new(); let mut module = Module::new();
let table = cranelift_wasm::Table { let table = cranelift_wasm::Table {

View File

@@ -1,7 +1,8 @@
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};
use thiserror::Error;
#[derive(Fail, Debug)] #[derive(Error, Debug)]
#[fail(display = "Wasm trap")] #[error("Wasm trap: {message}")]
pub struct Trap { pub struct Trap {
message: String, message: String,
} }

View File

@@ -682,7 +682,7 @@ pub unsafe extern "C" fn wasm_instance_new(
} }
Err(_) => { Err(_) => {
if !result.is_null() { if !result.is_null() {
// TODO Unwrap trap from failure::Error // TODO Unwrap trap from error
let trap = Box::new(wasm_trap_t { let trap = Box::new(wasm_trap_t {
trap: HostRef::new(Trap::new("trap during instantiation".to_string())), trap: HostRef::new(Trap::new("trap during instantiation".to_string())),
}); });

View File

@@ -14,15 +14,15 @@ edition = "2018"
[dependencies] [dependencies]
gimli = "0.19.0" gimli = "0.19.0"
wasmparser = "0.39.2" wasmparser = "0.39.2"
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
faerie = "0.11.0" faerie = "0.11.0"
wasmtime-environ = { path = "../wasmtime-environ", default-features = false } wasmtime-environ = { path = "../wasmtime-environ", default-features = false }
target-lexicon = { version = "0.8.1", default-features = false } target-lexicon = { version = "0.8.1", default-features = false }
failure = { version = "0.1.3", default-features = false } failure = { version = "0.1.3", default-features = false }
failure_derive = { version = "0.1.3", default-features = false }
hashbrown = { version = "0.6.0", optional = true } hashbrown = { version = "0.6.0", optional = true }
thiserror = "1.0.4"
[features] [features]
default = ["std"] default = ["std"]

View File

@@ -24,8 +24,6 @@ mod read_debuginfo;
mod transform; mod transform;
mod write_debuginfo; mod write_debuginfo;
#[macro_use]
extern crate failure_derive;
extern crate alloc; extern crate alloc;
struct FunctionRelocResolver {} struct FunctionRelocResolver {}

View File

@@ -4,6 +4,7 @@ use crate::HashSet;
use cranelift_codegen::isa::TargetFrontendConfig; use cranelift_codegen::isa::TargetFrontendConfig;
use failure::Error; use failure::Error;
use simulate::generate_simulated_dwarf; use simulate::generate_simulated_dwarf;
use thiserror::Error;
use wasmtime_environ::{ModuleAddressMap, ModuleVmctxInfo, ValueLabelsRanges}; use wasmtime_environ::{ModuleAddressMap, ModuleVmctxInfo, ValueLabelsRanges};
use gimli; use gimli;
@@ -31,8 +32,8 @@ pub(crate) trait Reader: gimli::Reader<Offset = usize> {}
impl<'input, Endian> Reader for gimli::EndianSlice<'input, Endian> where Endian: gimli::Endianity {} impl<'input, Endian> Reader for gimli::EndianSlice<'input, Endian> where Endian: gimli::Endianity {}
#[derive(Fail, Debug)] #[derive(Error, Debug)]
#[fail(display = "Debug info transform error: {}", _0)] #[error("Debug info transform error: {0}")]
pub struct TransformError(&'static str); pub struct TransformError(&'static str);
pub(crate) struct DebugInputContext<'a, R> pub(crate) struct DebugInputContext<'a, R>

View File

@@ -12,14 +12,13 @@ readme = "README.md"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
lightbeam = { path = "../lightbeam", optional = true } lightbeam = { path = "../lightbeam", optional = true }
failure = { version = "0.1.3", default-features = false }
failure_derive = { version = "0.1.3", default-features = false }
indexmap = "1.0.2" indexmap = "1.0.2"
rayon = "1.1" rayon = "1.1"
thiserror = "1.0.4"
directories = "2.0.1" directories = "2.0.1"
sha2 = "0.8.0" sha2 = "0.8.0"
base64 = "0.10.1" base64 = "0.10.1"
@@ -44,7 +43,7 @@ tempfile = "3"
target-lexicon = { version = "0.8.1", default-features = false } target-lexicon = { version = "0.8.1", default-features = false }
pretty_env_logger = "0.3.0" pretty_env_logger = "0.3.0"
rand = { version = "0.7.0", features = ["small_rng"] } rand = { version = "0.7.0", features = ["small_rng"] }
cranelift-codegen = { version = "0.46.1", features = ["enable-serde", "all-arch"] } cranelift-codegen = { version = "0.47", features = ["enable-serde", "all-arch"] }
filetime = "0.2.7" filetime = "0.2.7"
[features] [features]

View File

@@ -10,6 +10,7 @@ use cranelift_entity::PrimaryMap;
use cranelift_wasm::{DefinedFuncIndex, FuncIndex, ModuleTranslationState, WasmError}; use cranelift_wasm::{DefinedFuncIndex, FuncIndex, ModuleTranslationState, WasmError};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::ops::Range; use std::ops::Range;
use thiserror::Error;
/// Compiled machine code: body and jump table offsets. /// Compiled machine code: body and jump table offsets.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
@@ -144,18 +145,18 @@ pub struct TrapInformation {
pub type Traps = PrimaryMap<DefinedFuncIndex, Vec<TrapInformation>>; pub type Traps = PrimaryMap<DefinedFuncIndex, Vec<TrapInformation>>;
/// An error while compiling WebAssembly to machine code. /// An error while compiling WebAssembly to machine code.
#[derive(Fail, Debug)] #[derive(Error, Debug)]
pub enum CompileError { pub enum CompileError {
/// A wasm translation error occured. /// A wasm translation error occured.
#[fail(display = "WebAssembly translation error: {}", _0)] #[error("WebAssembly translation error: {0}")]
Wasm(WasmError), Wasm(#[from] WasmError),
/// A compilation error occured. /// A compilation error occured.
#[fail(display = "Compilation error: {}", _0)] #[error("Compilation error: {0}")]
Codegen(CodegenError), Codegen(#[from] CodegenError),
/// A compilation error occured. /// A compilation error occured.
#[fail(display = "Debug info is not supported with this configuration")] #[error("Debug info is not supported with this configuration")]
DebugInfoNotSupported, DebugInfoNotSupported,
} }

View File

@@ -226,29 +226,25 @@ impl crate::compilation::Compiler for Cranelift {
context.func.collect_debug_info(); context.func.collect_debug_info();
} }
func_translator func_translator.translate(
.translate(
module_translation, module_translation,
input.data, input.data,
input.module_offset, input.module_offset,
&mut context.func, &mut context.func,
&mut FuncEnvironment::new(isa.frontend_config(), module), &mut FuncEnvironment::new(isa.frontend_config(), module),
) )?;
.map_err(CompileError::Wasm)?;
let mut code_buf: Vec<u8> = Vec::new(); let mut code_buf: Vec<u8> = Vec::new();
let mut reloc_sink = RelocSink::new(func_index); let mut reloc_sink = RelocSink::new(func_index);
let mut trap_sink = TrapSink::new(); let mut trap_sink = TrapSink::new();
let mut stackmap_sink = binemit::NullStackmapSink {}; let mut stackmap_sink = binemit::NullStackmapSink {};
context context.compile_and_emit(
.compile_and_emit(
isa, isa,
&mut code_buf, &mut code_buf,
&mut reloc_sink, &mut reloc_sink,
&mut trap_sink, &mut trap_sink,
&mut stackmap_sink, &mut stackmap_sink,
) )?;
.map_err(CompileError::Codegen)?;
let jt_offsets = context.func.jt_offsets.clone(); let jt_offsets = context.func.jt_offsets.clone();
@@ -260,11 +256,7 @@ impl crate::compilation::Compiler for Cranelift {
}; };
let ranges = if generate_debug_info { let ranges = if generate_debug_info {
Some( Some(context.build_value_labels_ranges(isa)?)
context
.build_value_labels_ranges(isa)
.map_err(CompileError::Codegen)?,
)
} else { } else {
None None
}; };

View File

@@ -27,9 +27,6 @@
extern crate alloc; extern crate alloc;
#[macro_use]
extern crate failure_derive;
mod address_map; mod address_map;
mod compilation; mod compilation;
mod func_environ; mod func_environ;

View File

@@ -11,10 +11,10 @@ readme = "README.md"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
cranelift-codegen = { version = "0.46.1", default-features = false } anyhow = "1.0.19"
failure = { version = "0.1", default-features = false } cranelift-codegen = { version = "0.47", default-features = false }
walrus = "0.12.0" walrus = "0.13"
wasmparser = { version = "0.39.2", default-features = false } wasmparser = { version = "0.39.2", default-features = false }
wasm-webidl-bindings = "0.5.0" wasm-webidl-bindings = "0.6"
wasmtime-jit = { path = '../wasmtime-jit', default-features = false } wasmtime-jit = { path = '../wasmtime-jit', default-features = false }
wasmtime-runtime = { path = '../wasmtime-runtime', default-features = false } wasmtime-runtime = { path = '../wasmtime-runtime', default-features = false }

View File

@@ -13,11 +13,11 @@ extern crate alloc;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::string::ToString; use alloc::string::ToString;
use alloc::vec::Vec; use alloc::vec::Vec;
use anyhow::{bail, format_err, Result};
use core::convert::TryFrom; use core::convert::TryFrom;
use core::slice; use core::slice;
use core::str; use core::str;
use cranelift_codegen::ir; use cranelift_codegen::ir;
use failure::{bail, format_err, Error};
use wasm_webidl_bindings::ast; use wasm_webidl_bindings::ast;
use wasmtime_jit::{ActionOutcome, Context, RuntimeValue}; use wasmtime_jit::{ActionOutcome, Context, RuntimeValue};
use wasmtime_runtime::{Export, InstanceHandle}; use wasmtime_runtime::{Export, InstanceHandle};
@@ -59,7 +59,7 @@ impl ModuleData {
/// interface types. /// interface types.
/// ///
/// Returns an error if the wasm file is malformed. /// Returns an error if the wasm file is malformed.
pub fn new(wasm: &[u8]) -> Result<ModuleData, Error> { pub fn new(wasm: &[u8]) -> Result<ModuleData> {
// Perform a fast search through the module for the right custom // Perform a fast search through the module for the right custom
// section. Actually parsing out the interface types data is currently a // section. Actually parsing out the interface types data is currently a
// pretty expensive operation so we want to only do that if we actually // pretty expensive operation so we want to only do that if we actually
@@ -109,7 +109,7 @@ impl ModuleData {
handle: &mut InstanceHandle, handle: &mut InstanceHandle,
export: &str, export: &str,
args: &[Value], args: &[Value],
) -> Result<Vec<Value>, Error> { ) -> Result<Vec<Value>> {
let binding = self.binding_for_export(handle, export)?; let binding = self.binding_for_export(handle, export)?;
let incoming = binding.param_bindings()?; let incoming = binding.param_bindings()?;
let outgoing = binding.result_bindings()?; let outgoing = binding.result_bindings()?;
@@ -130,7 +130,7 @@ impl ModuleData {
&self, &self,
instance: &mut InstanceHandle, instance: &mut InstanceHandle,
name: &str, name: &str,
) -> Result<ExportBinding<'_>, Error> { ) -> Result<ExportBinding<'_>> {
if let Some(binding) = self.interface_binding_for_export(name) { if let Some(binding) = self.interface_binding_for_export(name) {
return Ok(binding); return Ok(binding);
} }
@@ -170,7 +170,7 @@ impl ModuleData {
impl ExportBinding<'_> { impl ExportBinding<'_> {
/// Returns the list of binding expressions used to create the parameters /// Returns the list of binding expressions used to create the parameters
/// for this binding. /// for this binding.
pub fn param_bindings(&self) -> Result<Vec<ast::IncomingBindingExpression>, Error> { pub fn param_bindings(&self) -> Result<Vec<ast::IncomingBindingExpression>> {
match &self.kind { match &self.kind {
ExportBindingKind::Rich { binding, .. } => Ok(binding.params.bindings.clone()), ExportBindingKind::Rich { binding, .. } => Ok(binding.params.bindings.clone()),
ExportBindingKind::Raw(sig) => sig ExportBindingKind::Raw(sig) => sig
@@ -184,7 +184,7 @@ impl ExportBinding<'_> {
} }
/// Returns the list of scalar types used for this binding /// Returns the list of scalar types used for this binding
pub fn param_types(&self) -> Result<Vec<ast::WebidlScalarType>, Error> { pub fn param_types(&self) -> Result<Vec<ast::WebidlScalarType>> {
match &self.kind { match &self.kind {
ExportBindingKind::Rich { ExportBindingKind::Rich {
binding, section, .. binding, section, ..
@@ -217,7 +217,7 @@ impl ExportBinding<'_> {
/// Returns the list of binding expressions used to extract the return /// Returns the list of binding expressions used to extract the return
/// values of this binding. /// values of this binding.
pub fn result_bindings(&self) -> Result<Vec<ast::OutgoingBindingExpression>, Error> { pub fn result_bindings(&self) -> Result<Vec<ast::OutgoingBindingExpression>> {
match &self.kind { match &self.kind {
ExportBindingKind::Rich { binding, .. } => Ok(binding.result.bindings.clone()), ExportBindingKind::Rich { binding, .. } => Ok(binding.result.bindings.clone()),
ExportBindingKind::Raw(sig) => sig ExportBindingKind::Raw(sig) => sig
@@ -230,10 +230,7 @@ impl ExportBinding<'_> {
} }
} }
fn default_incoming( fn default_incoming(idx: usize, param: &ir::AbiParam) -> Result<ast::IncomingBindingExpression> {
idx: usize,
param: &ir::AbiParam,
) -> Result<ast::IncomingBindingExpression, Error> {
let get = ast::IncomingBindingExpressionGet { idx: idx as u32 }; let get = ast::IncomingBindingExpressionGet { idx: idx as u32 };
let ty = if param.value_type == ir::types::I32 { let ty = if param.value_type == ir::types::I32 {
walrus::ValType::I32 walrus::ValType::I32
@@ -253,10 +250,7 @@ fn default_incoming(
.into()) .into())
} }
fn default_outgoing( fn default_outgoing(idx: usize, param: &ir::AbiParam) -> Result<ast::OutgoingBindingExpression> {
idx: usize,
param: &ir::AbiParam,
) -> Result<ast::OutgoingBindingExpression, Error> {
let ty = abi2ast(param)?; let ty = abi2ast(param)?;
Ok(ast::OutgoingBindingExpressionAs { Ok(ast::OutgoingBindingExpressionAs {
ty: ty.into(), ty: ty.into(),
@@ -265,7 +259,7 @@ fn default_outgoing(
.into()) .into())
} }
fn abi2ast(param: &ir::AbiParam) -> Result<ast::WebidlScalarType, Error> { fn abi2ast(param: &ir::AbiParam) -> Result<ast::WebidlScalarType> {
Ok(if param.value_type == ir::types::I32 { Ok(if param.value_type == ir::types::I32 {
ast::WebidlScalarType::Long ast::WebidlScalarType::Long
} else if param.value_type == ir::types::I64 { } else if param.value_type == ir::types::I64 {
@@ -284,7 +278,7 @@ fn translate_incoming(
handle: &mut InstanceHandle, handle: &mut InstanceHandle,
bindings: &[ast::IncomingBindingExpression], bindings: &[ast::IncomingBindingExpression],
args: &[Value], args: &[Value],
) -> Result<Vec<RuntimeValue>, Error> { ) -> Result<Vec<RuntimeValue>> {
let get = |expr: &ast::IncomingBindingExpression| match expr { let get = |expr: &ast::IncomingBindingExpression| match expr {
ast::IncomingBindingExpression::Get(g) => args ast::IncomingBindingExpression::Get(g) => args
.get(g.idx as usize) .get(g.idx as usize)
@@ -375,7 +369,7 @@ fn translate_outgoing(
handle: &mut InstanceHandle, handle: &mut InstanceHandle,
bindings: &[ast::OutgoingBindingExpression], bindings: &[ast::OutgoingBindingExpression],
args: &[RuntimeValue], args: &[RuntimeValue],
) -> Result<Vec<Value>, Error> { ) -> Result<Vec<Value>> {
let mut values = Vec::new(); let mut values = Vec::new();
let raw_memory = || unsafe { let raw_memory = || unsafe {

View File

@@ -24,12 +24,12 @@ macro_rules! from {
} }
impl TryFrom<Value> for $a { impl TryFrom<Value> for $a {
type Error = failure::Error; type Error = anyhow::Error;
fn try_from(val: Value) -> Result<$a, Self::Error> { fn try_from(val: Value) -> Result<$a, Self::Error> {
match val { match val {
Value::$b(v) => Ok(v), Value::$b(v) => Ok(v),
v => failure::bail!("cannot convert {:?} to {}", v, stringify!($a)), v => anyhow::bail!("cannot convert {:?} to {}", v, stringify!($a)),
} }
} }
} }

View File

@@ -11,16 +11,16 @@ readme = "README.md"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
cranelift-frontend = "0.46.1" cranelift-frontend = { version = "0.47" }
wasmtime-environ = { path = "../wasmtime-environ", default-features = false } wasmtime-environ = { path = "../wasmtime-environ", default-features = false }
wasmtime-runtime = { path = "../wasmtime-runtime", default-features = false } wasmtime-runtime = { path = "../wasmtime-runtime", default-features = false }
wasmtime-debug = { path = "../wasmtime-debug", default-features = false } wasmtime-debug = { path = "../wasmtime-debug", default-features = false }
region = "2.0.0" region = "2.0.0"
failure = { version = "0.1.3", default-features = false } failure = { version = "0.1.3", default-features = false }
failure_derive = { version = "0.1.3", default-features = false } thiserror = "1.0.4"
target-lexicon = { version = "0.8.1", default-features = false } target-lexicon = { version = "0.8.1", default-features = false }
hashbrown = { version = "0.6.0", optional = true } hashbrown = { version = "0.6.0", optional = true }
wasmparser = { version = "0.39.2", default-features = false } wasmparser = { version = "0.39.2", default-features = false }

View File

@@ -7,6 +7,7 @@ use alloc::vec::Vec;
use core::cmp::max; use core::cmp::max;
use core::{fmt, mem, ptr, slice}; use core::{fmt, mem, ptr, slice};
use cranelift_codegen::ir; use cranelift_codegen::ir;
use thiserror::Error;
use wasmtime_runtime::{wasmtime_call_trampoline, Export, InstanceHandle, VMInvokeArgument}; use wasmtime_runtime::{wasmtime_call_trampoline, Export, InstanceHandle, VMInvokeArgument};
/// A runtime value. /// A runtime value.
@@ -110,22 +111,22 @@ pub enum ActionOutcome {
/// An error detected while invoking a wasm function or reading a wasm global. /// An error detected while invoking a wasm function or reading a wasm global.
/// Note that at this level, traps are not reported errors, but are rather /// Note that at this level, traps are not reported errors, but are rather
/// returned through `ActionOutcome`. /// returned through `ActionOutcome`.
#[derive(Fail, Debug)] #[derive(Error, Debug)]
pub enum ActionError { pub enum ActionError {
/// An internal implementation error occurred. /// An internal implementation error occurred.
#[fail(display = "{}", _0)] #[error("{0}")]
Setup(SetupError), Setup(#[from] SetupError),
/// No field with the specified name was present. /// No field with the specified name was present.
#[fail(display = "Unknown field: {}", _0)] #[error("Unknown field: {0}")]
Field(String), Field(String),
/// The field was present but was the wrong kind (eg. function, table, global, or memory). /// The field was present but was the wrong kind (eg. function, table, global, or memory).
#[fail(display = "Kind error: {}", _0)] #[error("Kind error: {0}")]
Kind(String), Kind(String),
/// The field was present but was the wrong type (eg. i32, i64, f32, or f64). /// The field was present but was the wrong type (eg. i32, i64, f32, or f64).
#[fail(display = "Type error: {}", _0)] #[error("Type error: {0}")]
Type(String), Type(String),
} }

View File

@@ -8,38 +8,26 @@ use alloc::boxed::Box;
use alloc::rc::Rc; use alloc::rc::Rc;
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};
use core::cell::RefCell; use core::cell::RefCell;
use core::{fmt, str};
use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::isa::TargetIsa;
use thiserror::Error;
use wasmparser::{validate, OperatorValidatorConfig, ValidatingParserConfig}; use wasmparser::{validate, OperatorValidatorConfig, ValidatingParserConfig};
/// Indicates an unknown instance was specified. /// Indicates an unknown instance was specified.
#[derive(Fail, Debug)] #[derive(Error, Debug)]
#[error("no instance {instance_name} present")]
pub struct UnknownInstance { pub struct UnknownInstance {
instance_name: String, instance_name: String,
} }
impl fmt::Display for UnknownInstance {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "no instance {} present", self.instance_name)
}
}
/// Error message used by `WastContext`. /// Error message used by `WastContext`.
#[derive(Fail, Debug)] #[derive(Error, Debug)]
pub enum ContextError { pub enum ContextError {
/// An unknown instance name was used. /// An unknown instance name was used.
Instance(UnknownInstance), #[error("{0}")]
Instance(#[from] UnknownInstance),
/// An error occured while performing an action. /// An error occured while performing an action.
Action(ActionError), #[error("{0}")]
} Action(#[from] ActionError),
impl fmt::Display for ContextError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ContextError::Instance(ref error) => error.fmt(f),
ContextError::Action(ref error) => error.fmt(f),
}
}
} }
/// The collection of features configurable during compilation /// The collection of features configurable during compilation

View File

@@ -16,6 +16,7 @@ use cranelift_entity::{BoxedSlice, PrimaryMap};
use cranelift_wasm::{DefinedFuncIndex, SignatureIndex}; use cranelift_wasm::{DefinedFuncIndex, SignatureIndex};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::io::Write; use std::io::Write;
use thiserror::Error;
use wasmtime_debug::read_debuginfo; use wasmtime_debug::read_debuginfo;
use wasmtime_environ::{ use wasmtime_environ::{
CompileError, DataInitializer, DataInitializerLocation, Module, ModuleEnvironment, CompileError, DataInitializer, DataInitializerLocation, Module, ModuleEnvironment,
@@ -27,23 +28,23 @@ use wasmtime_runtime::{
/// An error condition while setting up a wasm instance, be it validation, /// An error condition while setting up a wasm instance, be it validation,
/// compilation, or instantiation. /// compilation, or instantiation.
#[derive(Fail, Debug)] #[derive(Error, Debug)]
pub enum SetupError { pub enum SetupError {
/// The module did not pass validation. /// The module did not pass validation.
#[fail(display = "Validation error: {}", _0)] #[error("Validation error: {0}")]
Validate(String), Validate(String),
/// A wasm translation error occured. /// A wasm translation error occured.
#[fail(display = "WebAssembly compilation error: {}", _0)] #[error("WebAssembly compilation error: {0}")]
Compile(CompileError), Compile(#[from] CompileError),
/// Some runtime resource was unavailable or insufficient, or the start function /// Some runtime resource was unavailable or insufficient, or the start function
/// trapped. /// trapped.
#[fail(display = "Instantiation error: {}", _0)] #[error("Instantiation error: {0}")]
Instantiate(InstantiationError), Instantiate(#[from] InstantiationError),
/// Debug information generation error occured. /// Debug information generation error occured.
#[fail(display = "Debug information error: {}", _0)] #[error("Debug information error: {0}")]
DebugInfo(failure::Error), DebugInfo(failure::Error),
} }

View File

@@ -30,9 +30,6 @@ use hashbrown::{hash_map, HashMap, HashSet};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::collections::{hash_map, HashMap, HashSet}; use std::collections::{hash_map, HashMap, HashSet};
#[macro_use]
extern crate failure_derive;
mod action; mod action;
mod code_memory; mod code_memory;
mod compiler; mod compiler;

View File

@@ -11,8 +11,8 @@ readme = "README.md"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
wasmtime-environ = { path = "../wasmtime-environ" } wasmtime-environ = { path = "../wasmtime-environ" }
faerie = "0.11.0" faerie = "0.11.0"

View File

@@ -11,19 +11,18 @@ readme = "README.md"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
wasmtime-environ = { path = "../wasmtime-environ", default-features = false } wasmtime-environ = { path = "../wasmtime-environ", default-features = false }
region = "2.0.0" region = "2.0.0"
lazy_static = "1.2.0" lazy_static = "1.2.0"
libc = { version = "0.2.60", default-features = false } libc = { version = "0.2.60", default-features = false }
memoffset = "0.5.1" memoffset = "0.5.1"
failure = { version = "0.1.3", default-features = false }
failure_derive = { version = "0.1.3", default-features = false }
indexmap = "1.0.2" indexmap = "1.0.2"
hashbrown = { version = "0.6.0", optional = true } hashbrown = { version = "0.6.0", optional = true }
spin = { version = "0.5.2", optional = true } spin = { version = "0.5.2", optional = true }
thiserror = "1.0.4"
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3.7", features = ["winbase", "memoryapi"] } winapi = { version = "0.3.7", features = ["winbase", "memoryapi"] }

View File

@@ -33,6 +33,7 @@ use cranelift_wasm::{
GlobalIndex, GlobalInit, MemoryIndex, SignatureIndex, TableIndex, GlobalIndex, GlobalInit, MemoryIndex, SignatureIndex, TableIndex,
}; };
use indexmap; use indexmap;
use thiserror::Error;
use wasmtime_environ::{DataInitializer, Module, TableElements, VMOffsets}; use wasmtime_environ::{DataInitializer, Module, TableElements, VMOffsets};
fn signature_id( fn signature_id(
@@ -1275,22 +1276,22 @@ fn initialize_globals(instance: &mut Instance) {
} }
/// An link error while instantiating a module. /// An link error while instantiating a module.
#[derive(Fail, Debug)] #[derive(Error, Debug)]
#[fail(display = "Link error: {}", _0)] #[error("Link error: {0}")]
pub struct LinkError(pub String); pub struct LinkError(pub String);
/// An error while instantiating a module. /// An error while instantiating a module.
#[derive(Fail, Debug)] #[derive(Error, Debug)]
pub enum InstantiationError { pub enum InstantiationError {
/// Insufficient resources available for execution. /// Insufficient resources available for execution.
#[fail(display = "Insufficient resources: {}", _0)] #[error("Insufficient resources: {0}")]
Resource(String), Resource(String),
/// A wasm link error occured. /// A wasm link error occured.
#[fail(display = "{}", _0)] #[error("{0}")]
Link(LinkError), Link(#[from] LinkError),
/// A compilation error occured. /// A compilation error occured.
#[fail(display = "Trap occurred while invoking start function: {}", _0)] #[error("Trap occurred while invoking start function: {0}")]
StartTrap(String), StartTrap(String),
} }

View File

@@ -27,8 +27,6 @@
extern crate lazy_static; extern crate lazy_static;
#[macro_use] #[macro_use]
extern crate memoffset; extern crate memoffset;
#[macro_use]
extern crate failure_derive;
extern crate alloc; extern crate alloc;
mod export; mod export;

View File

@@ -13,9 +13,9 @@ edition = "2018"
wasmtime-runtime = { path = "../wasmtime-runtime" } wasmtime-runtime = { path = "../wasmtime-runtime" }
wasmtime-environ = { path = "../wasmtime-environ" } wasmtime-environ = { path = "../wasmtime-environ" }
wasmtime-jit = { path = "../wasmtime-jit" } wasmtime-jit = { path = "../wasmtime-jit" }
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
target-lexicon = "0.8.1" target-lexicon = "0.8.1"
log = { version = "0.4.8", default-features = false } log = { version = "0.4.8", default-features = false }
libc = "0.2.60" libc = "0.2.60"

View File

@@ -14,9 +14,9 @@ wasmtime-runtime = { path = "../wasmtime-runtime" }
wasmtime-environ = { path = "../wasmtime-environ" } wasmtime-environ = { path = "../wasmtime-environ" }
wasmtime-jit = { path = "../wasmtime-jit" } wasmtime-jit = { path = "../wasmtime-jit" }
wasi-common = { git = "https://github.com/CraneStation/wasi-common", rev = "37ce4ba"} wasi-common = { git = "https://github.com/CraneStation/wasi-common", rev = "37ce4ba"}
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
target-lexicon = "0.8.1" target-lexicon = "0.8.1"
log = { version = "0.4.8", default-features = false } log = { version = "0.4.8", default-features = false }

View File

@@ -11,15 +11,15 @@ readme = "README.md"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
cranelift-codegen = { version = "0.46.1", features = ["enable-serde"] } cranelift-codegen = { version = "0.47", features = ["enable-serde"] }
cranelift-entity = { version = "0.46.1", features = ["enable-serde"] } cranelift-entity = { version = "0.47", features = ["enable-serde"] }
cranelift-wasm = { version = "0.46.1", features = ["enable-serde"] } cranelift-wasm = { version = "0.47", features = ["enable-serde"] }
wasmtime-jit = { path = "../wasmtime-jit" } wasmtime-jit = { path = "../wasmtime-jit" }
wasmtime-runtime = { path = "../wasmtime-runtime" } wasmtime-runtime = { path = "../wasmtime-runtime" }
wasmtime-environ = { path = "../wasmtime-environ" } wasmtime-environ = { path = "../wasmtime-environ" }
wast = "3.0.0" wast = "3.0.0"
anyhow = "1.0.19"
target-lexicon = "0.8.1" target-lexicon = "0.8.1"
failure = { version = "0.1.3", default-features = false }
[badges] [badges]
maintenance = { status = "experimental" } maintenance = { status = "experimental" }

View File

@@ -1,5 +1,5 @@
use crate::spectest::instantiate_spectest; use crate::spectest::instantiate_spectest;
use failure::{bail, Error, ResultExt}; use anyhow::{bail, Context as _, Result};
use std::path::Path; use std::path::Path;
use std::str; use std::str;
use wasmtime_jit::{ use wasmtime_jit::{
@@ -51,7 +51,7 @@ impl WastContext {
} }
} }
fn get_instance(&mut self, instance_name: Option<&str>) -> Result<&mut InstanceHandle, Error> { fn get_instance(&mut self, instance_name: Option<&str>) -> Result<&mut InstanceHandle> {
let instance = if let Some(instance_name) = instance_name { let instance = if let Some(instance_name) = instance_name {
self.context self.context
.get_instance(instance_name) .get_instance(instance_name)
@@ -59,21 +59,21 @@ impl WastContext {
} else { } else {
self.current self.current
.as_mut() .as_mut()
.ok_or_else(|| failure::format_err!("no current instance"))? .ok_or_else(|| anyhow::format_err!("no current instance"))?
}; };
Ok(instance) Ok(instance)
} }
/// Register "spectest" which is used by the spec testsuite. /// Register "spectest" which is used by the spec testsuite.
pub fn register_spectest(&mut self) -> Result<(), Error> { pub fn register_spectest(&mut self) -> Result<()> {
let instance = instantiate_spectest()?; let instance = instantiate_spectest()?;
self.context.name_instance("spectest".to_owned(), instance); self.context.name_instance("spectest".to_owned(), instance);
Ok(()) Ok(())
} }
/// Perform the action portion of a command. /// Perform the action portion of a command.
fn perform_execute(&mut self, exec: wast::WastExecute<'_>) -> Result<ActionOutcome, Error> { fn perform_execute(&mut self, exec: wast::WastExecute<'_>) -> Result<ActionOutcome> {
match exec { match exec {
wast::WastExecute::Invoke(invoke) => self.perform_invoke(invoke), wast::WastExecute::Invoke(invoke) => self.perform_invoke(invoke),
wast::WastExecute::Module(mut module) => { wast::WastExecute::Module(mut module) => {
@@ -91,12 +91,12 @@ impl WastContext {
} }
} }
fn perform_invoke(&mut self, exec: wast::WastInvoke<'_>) -> Result<ActionOutcome, Error> { fn perform_invoke(&mut self, exec: wast::WastInvoke<'_>) -> Result<ActionOutcome> {
self.invoke(exec.module.map(|i| i.name()), exec.name, &exec.args) self.invoke(exec.module.map(|i| i.name()), exec.name, &exec.args)
} }
/// Define a module and register it. /// Define a module and register it.
fn module(&mut self, instance_name: Option<&str>, module: &[u8]) -> Result<(), Error> { fn module(&mut self, instance_name: Option<&str>, module: &[u8]) -> Result<()> {
let index = self let index = self
.context .context
.instantiate_module(instance_name.map(|s| s.to_string()), module)?; .instantiate_module(instance_name.map(|s| s.to_string()), module)?;
@@ -105,7 +105,7 @@ impl WastContext {
} }
/// Register an instance to make it available for performing actions. /// Register an instance to make it available for performing actions.
fn register(&mut self, name: Option<&str>, as_name: &str) -> Result<(), Error> { fn register(&mut self, name: Option<&str>, as_name: &str) -> Result<()> {
let instance = self.get_instance(name)?.clone(); let instance = self.get_instance(name)?.clone();
self.context.name_instance(as_name.to_string(), instance); self.context.name_instance(as_name.to_string(), instance);
Ok(()) Ok(())
@@ -117,30 +117,30 @@ impl WastContext {
instance_name: Option<&str>, instance_name: Option<&str>,
field: &str, field: &str,
args: &[wast::Expression], args: &[wast::Expression],
) -> Result<ActionOutcome, Error> { ) -> Result<ActionOutcome> {
let value_args = args.iter().map(runtime_value).collect::<Vec<_>>(); let value_args = args.iter().map(runtime_value).collect::<Vec<_>>();
let mut instance = self.get_instance(instance_name)?.clone(); let mut instance = self.get_instance(instance_name)?.clone();
let result = self let result = self
.context .context
.invoke(&mut instance, field, &value_args) .invoke(&mut instance, field, &value_args)
.with_context(|_| format!("failed to invoke `{}`", field))?; .with_context(|| format!("failed to invoke `{}`", field))?;
Ok(result) Ok(result)
} }
/// Get the value of an exported global from an instance. /// Get the value of an exported global from an instance.
fn get(&mut self, instance_name: Option<&str>, field: &str) -> Result<ActionOutcome, Error> { fn get(&mut self, instance_name: Option<&str>, field: &str) -> Result<ActionOutcome> {
let instance = self let instance = self
.get_instance(instance_name.as_ref().map(|x| &**x))? .get_instance(instance_name.as_ref().map(|x| &**x))?
.clone(); .clone();
let result = self let result = self
.context .context
.get(&instance, field) .get(&instance, field)
.with_context(|_| format!("failed to get field `{}`", field))?; .with_context(|| format!("failed to get field `{}`", field))?;
Ok(result) Ok(result)
} }
/// Run a wast script from a byte buffer. /// Run a wast script from a byte buffer.
pub fn run_buffer(&mut self, filename: &str, wast: &[u8]) -> Result<(), Error> { pub fn run_buffer(&mut self, filename: &str, wast: &[u8]) -> Result<()> {
use wast::WastDirective::*; use wast::WastDirective::*;
let wast = str::from_utf8(wast)?; let wast = str::from_utf8(wast)?;
@@ -163,21 +163,21 @@ impl WastContext {
Module(mut module) => { Module(mut module) => {
let binary = module.encode().map_err(adjust_wast)?; let binary = module.encode().map_err(adjust_wast)?;
self.module(module.name.map(|s| s.name()), &binary) self.module(module.name.map(|s| s.name()), &binary)
.with_context(|_| context(module.span))?; .with_context(|| context(module.span))?;
} }
Register { span, name, module } => { Register { span, name, module } => {
self.register(module.map(|s| s.name()), name) self.register(module.map(|s| s.name()), name)
.with_context(|_| context(span))?; .with_context(|| context(span))?;
} }
Invoke(i) => { Invoke(i) => {
let span = i.span; let span = i.span;
self.perform_invoke(i).with_context(|_| context(span))?; self.perform_invoke(i).with_context(|| context(span))?;
} }
AssertReturn { AssertReturn {
span, span,
exec, exec,
results, results,
} => match self.perform_execute(exec).with_context(|_| context(span))? { } => match self.perform_execute(exec).with_context(|| context(span))? {
ActionOutcome::Returned { values } => { ActionOutcome::Returned { values } => {
for (v, e) in values.iter().zip(results.iter().map(runtime_value)) { for (v, e) in values.iter().zip(results.iter().map(runtime_value)) {
if *v == e { if *v == e {
@@ -194,7 +194,7 @@ impl WastContext {
span, span,
exec, exec,
message, message,
} => match self.perform_execute(exec).with_context(|_| context(span))? { } => match self.perform_execute(exec).with_context(|| context(span))? {
ActionOutcome::Returned { values } => { ActionOutcome::Returned { values } => {
bail!("{}\nexpected trap, got {:?}", context(span), values) bail!("{}\nexpected trap, got {:?}", context(span), values)
} }
@@ -224,7 +224,7 @@ impl WastContext {
span, span,
call, call,
message, message,
} => match self.perform_invoke(call).with_context(|_| context(span))? { } => match self.perform_invoke(call).with_context(|| context(span))? {
ActionOutcome::Returned { values } => { ActionOutcome::Returned { values } => {
bail!("{}\nexpected trap, got {:?}", context(span), values) bail!("{}\nexpected trap, got {:?}", context(span), values)
} }
@@ -243,10 +243,7 @@ impl WastContext {
} }
}, },
AssertReturnCanonicalNan { span, invoke } => { AssertReturnCanonicalNan { span, invoke } => {
match self match self.perform_invoke(invoke).with_context(|| context(span))? {
.perform_invoke(invoke)
.with_context(|_| context(span))?
{
ActionOutcome::Returned { values } => { ActionOutcome::Returned { values } => {
for v in values.iter() { for v in values.iter() {
match v { match v {
@@ -275,10 +272,7 @@ impl WastContext {
} }
} }
AssertReturnArithmeticNan { span, invoke } => { AssertReturnArithmeticNan { span, invoke } => {
match self match self.perform_invoke(invoke).with_context(|| context(span))? {
.perform_invoke(invoke)
.with_context(|_| context(span))?
{
ActionOutcome::Returned { values } => { ActionOutcome::Returned { values } => {
for v in values.iter() { for v in values.iter() {
match v { match v {
@@ -384,9 +378,9 @@ impl WastContext {
} }
/// Run a wast script from a file. /// Run a wast script from a file.
pub fn run_file(&mut self, path: &Path) -> Result<(), Error> { pub fn run_file(&mut self, path: &Path) -> Result<()> {
let bytes = let bytes =
std::fs::read(path).with_context(|_| format!("failed to read `{}`", path.display()))?; std::fs::read(path).with_context(|| format!("failed to read `{}`", path.display()))?;
self.run_buffer(path.to_str().unwrap(), &bytes) self.run_buffer(path.to_str().unwrap(), &bytes)
} }
} }