Files
wasmtime/src/commands/wast.rs
Peter Huene 59258730c2 Use structopt instead of docopt.
This commit refactors the Wasmtime CLI tools to use `structopt` instead of
`docopt`.

The `wasmtime` tool now has the following subcommands:

* `config new` - creates a new Wasmtime configuration file.
* `run` - runs a WebAssembly module.
* `wasm2obj` - translates a Wasm module to native object file.
* `wast` - runs a test script file.

If no subcommand is specified, the `run` subcommand is used. Thus,
`wasmtime foo.wasm` should continue to function as expected.

The `wasm2obj` and `wast` tools still exist, but delegate to the same
implementation as the `wasmtime` subcommands.  The standalone `wasm2obj` and
`wast` tools may be removed in the future in favor of simply using `wasmtime`.

Included in this commit is a breaking change to the default Wasmtime
configuration file: it has been renamed from `wasmtime-cache-config.toml` to
simply `config.toml`.  The new name is less specific which will allow for
additional (non-cache-related) settings in the future.

There are some breaking changes to improve command line UX:

* The `--cache-config` option has been renamed to `--config`.
* The `--create-config-file` option has moved to the `config new` subcommand.
As a result, the `wasm2obj` and `wast` tools cannot be used to create a new
config file.
* The short form of the `--optimize` option has changed from
`-o` to `-O` for consistency.
* The `wasm2obj` command takes the output object file as a
required positional argument rather than the former required output *option*
(e.g. `wasmtime wasm2obj foo.wasm foo.obj`).
2020-01-07 13:15:28 -08:00

84 lines
2.5 KiB
Rust

//! The module that implements the `wasmtime wast` command.
use crate::{init_file_per_thread_logger, pick_compilation_strategy, CommonOptions};
use anyhow::{bail, Context as _, Result};
use std::{fmt::Write, path::PathBuf};
use structopt::{clap::AppSettings, StructOpt};
use wasmtime::{Config, Engine, HostRef, Store};
use wasmtime_environ::cache_init;
use wasmtime_wast::WastContext;
/// Runs a WebAssembly test script file
#[derive(StructOpt)]
#[structopt(
name = "wast",
version = env!("CARGO_PKG_VERSION"),
setting = AppSettings::ColoredHelp,
)]
pub struct WastCommand {
#[structopt(flatten)]
common: CommonOptions,
/// The path of the WebAssembly test script to run
#[structopt(required = true, value_name = "SCRIPT_FILE", parse(from_os_str))]
scripts: Vec<PathBuf>,
}
impl WastCommand {
/// Executes the command.
pub fn execute(&self) -> Result<()> {
let log_config = if self.common.debug {
pretty_env_logger::init();
None
} else {
let prefix = "wast.dbg.";
init_file_per_thread_logger(prefix);
Some(prefix)
};
let errors = cache_init(
!self.common.disable_cache,
self.common.config.as_ref(),
log_config,
);
if !errors.is_empty() {
let mut message = String::new();
writeln!(message, "Cache initialization failed. Errors:")?;
for e in errors {
writeln!(message, " -> {}", e)?;
}
bail!(message);
}
let mut config = Config::new();
config
.cranelift_debug_verifier(cfg!(debug_assertions))
.debug_info(self.common.debug_info)
.wasm_simd(self.common.enable_simd)
.strategy(pick_compilation_strategy(
self.common.cranelift,
self.common.lightbeam,
)?)?;
if self.common.optimize {
config.cranelift_opt_level(wasmtime::OptLevel::Speed);
}
let store = HostRef::new(Store::new(&Engine::new(&config)));
let mut wast_context = WastContext::new(store);
wast_context
.register_spectest()
.expect("error instantiating \"spectest\"");
for script in self.scripts.iter() {
wast_context
.run_file(script)
.with_context(|| format!("failed to run script file '{}'", script.display()))?
}
Ok(())
}
}