Implement assert_malformed and assert_invalid.

This commit is contained in:
Dan Gohman
2018-12-12 12:28:51 -08:00
parent 3f24098edc
commit bc4333d857
4 changed files with 49 additions and 16 deletions

View File

@@ -119,6 +119,10 @@ pub enum ActionError {
#[fail(display = "Type error: {}", _0)] #[fail(display = "Type error: {}", _0)]
Type(String), Type(String),
/// The module did not pass validation.
#[fail(display = "Validation error: {}", _0)]
Validate(String),
/// A wasm translation error occured. /// A wasm translation error occured.
#[fail(display = "WebAssembly compilation error: {}", _0)] #[fail(display = "WebAssembly compilation error: {}", _0)]
Compile(CompileError), Compile(CompileError),

View File

@@ -21,6 +21,7 @@ wabt = "0.7"
target-lexicon = "0.2.0" target-lexicon = "0.2.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 } failure_derive = { version = "0.1.3", default-features = false }
wasmparser = { git = "https://github.com/sunfishcode/wasmparser.rs", branch = "export-operator-validator-config" }
[badges] [badges]
maintenance = { status = "experimental" } maintenance = { status = "experimental" }

View File

@@ -31,6 +31,7 @@ extern crate failure;
extern crate failure_derive; extern crate failure_derive;
extern crate target_lexicon; extern crate target_lexicon;
extern crate wabt; extern crate wabt;
extern crate wasmparser;
extern crate wasmtime_environ; extern crate wasmtime_environ;
extern crate wasmtime_execute; extern crate wasmtime_execute;
extern crate wasmtime_runtime; extern crate wasmtime_runtime;

View File

@@ -6,6 +6,7 @@ use std::io::Read;
use std::path::Path; use std::path::Path;
use std::{fmt, fs, io, str}; use std::{fmt, fs, io, str};
use wabt::script::{Action, Command, CommandKind, ModuleBinary, ScriptParser, Value}; use wabt::script::{Action, Command, CommandKind, ModuleBinary, ScriptParser, Value};
use wasmparser::{validate, OperatorValidatorConfig, ValidatingParserConfig};
use wasmtime_execute::{ActionError, ActionOutcome, InstancePlus, JITCode, Resolver, RuntimeValue}; use wasmtime_execute::{ActionError, ActionOutcome, InstancePlus, JITCode, Resolver, RuntimeValue};
use wasmtime_runtime::Export; use wasmtime_runtime::Export;
@@ -121,17 +122,35 @@ impl WastContext {
} }
} }
fn validate(&mut self, data: &[u8]) -> Result<(), ActionError> {
let config = ValidatingParserConfig {
operator_config: OperatorValidatorConfig {
enable_threads: false,
enable_reference_types: false,
},
mutable_global_imports: true,
};
// TODO: Fix Cranelift to be able to perform validation itself, rather
// than calling into wasmparser ourselves here.
if validate(data, Some(config)) {
Ok(())
} else {
// TODO: Work with wasmparser to get better error messages.
Err(ActionError::Validate("module did not validate".to_owned()))
}
}
fn instantiate( fn instantiate(
&mut self, &mut self,
isa: &isa::TargetIsa, isa: &isa::TargetIsa,
module: ModuleBinary, module: ModuleBinary,
) -> Result<InstancePlus, ActionError> { ) -> Result<InstancePlus, ActionError> {
InstancePlus::new( let data = module.into_vec();
&mut self.jit_code,
isa, self.validate(&data)?;
&module.into_vec(),
&mut self.namespace, InstancePlus::new(&mut self.jit_code, isa, &data, &mut self.namespace)
)
} }
fn get_instance(&mut self, module: &Option<String>) -> Result<InstancePlusIndex, WastError> { fn get_instance(&mut self, module: &Option<String>) -> Result<InstancePlusIndex, WastError> {
@@ -465,17 +484,25 @@ impl WastContext {
} }
} }
} }
CommandKind::AssertInvalid { CommandKind::AssertInvalid { module, message } => {
module: _module, self.module(isa, None, module).expect_err(&format!(
message: _message, "{}:{}: invalid module was successfully instantiated",
} => { filename, line
println!("{}:{}: TODO: Implement assert_invalid", filename, line); ));
println!(
"{}:{}: TODO: Check the assert_invalid message: {}",
filename, line, message
);
} }
CommandKind::AssertMalformed { CommandKind::AssertMalformed { module, message } => {
module: _module, self.module(isa, None, module).expect_err(&format!(
message: _message, "{}:{}: malformed module was successfully instantiated",
} => { filename, line
println!("{}:{}: TODO: Implement assert_malformed", filename, line); ));
println!(
"{}:{}: TODO: Check the assert_malformed message: {}",
filename, line, message
);
} }
CommandKind::AssertUninstantiable { module, message } => { CommandKind::AssertUninstantiable { module, message } => {
let _err = self.module(isa, None, module).expect_err(&format!( let _err = self.module(isa, None, module).expect_err(&format!(