Integrated wasm test suite translation as cretonne test
This commit is contained in:
@@ -420,8 +420,8 @@ fn translate_operator(op: &Operator,
|
|||||||
// We take the control frame pushed by the if, use its ebb as the else body
|
// We take the control frame pushed by the if, use its ebb as the else body
|
||||||
// and push a new control frame with a new ebb for the code after the if/then/else
|
// and push a new control frame with a new ebb for the code after the if/then/else
|
||||||
// At the end of the then clause we jump to the destination
|
// At the end of the then clause we jump to the destination
|
||||||
let (destination, return_values, branch_inst) = match &control_stack[control_stack.len() -
|
let i = control_stack.len() - 1;
|
||||||
1] {
|
let (destination, return_values, branch_inst) = match &control_stack[i] {
|
||||||
&ControlStackFrame::If {
|
&ControlStackFrame::If {
|
||||||
destination,
|
destination,
|
||||||
ref return_values,
|
ref return_values,
|
||||||
|
|||||||
@@ -239,7 +239,8 @@ pub fn parse_data_section(parser: &mut Parser,
|
|||||||
let offset = match *parser.read() {
|
let offset = match *parser.read() {
|
||||||
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
|
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
|
||||||
if value < 0 {
|
if value < 0 {
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from("negative offset value",),),);
|
return Err(SectionParsingError::WrongSectionContent(String::from("negative \
|
||||||
|
offset value")));
|
||||||
} else {
|
} else {
|
||||||
value as usize
|
value as usize
|
||||||
}
|
}
|
||||||
@@ -248,13 +249,15 @@ pub fn parse_data_section(parser: &mut Parser,
|
|||||||
match globals[global_index as usize].initializer {
|
match globals[global_index as usize].initializer {
|
||||||
GlobalInit::I32Const(value) => {
|
GlobalInit::I32Const(value) => {
|
||||||
if value < 0 {
|
if value < 0 {
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from("negative offset value",),),);
|
return Err(SectionParsingError::WrongSectionContent(String::from("\
|
||||||
|
negative offset value")));
|
||||||
} else {
|
} else {
|
||||||
value as usize
|
value as usize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlobalInit::Import() => {
|
GlobalInit::Import() => {
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from("imported globals not supported",),),)
|
return Err(SectionParsingError::WrongSectionContent(String::from("\
|
||||||
|
imported globals not supported")))
|
||||||
} // TODO: add runtime support
|
} // TODO: add runtime support
|
||||||
_ => panic!("should not happen"),
|
_ => panic!("should not happen"),
|
||||||
}
|
}
|
||||||
@@ -326,7 +329,8 @@ pub fn parse_elements_section(parser: &mut Parser,
|
|||||||
let offset = match *parser.read() {
|
let offset = match *parser.read() {
|
||||||
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
|
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
|
||||||
if value < 0 {
|
if value < 0 {
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from("negative offset value",),),);
|
return Err(SectionParsingError::WrongSectionContent(String::from("negative \
|
||||||
|
offset value")));
|
||||||
} else {
|
} else {
|
||||||
value as usize
|
value as usize
|
||||||
}
|
}
|
||||||
@@ -335,7 +339,8 @@ pub fn parse_elements_section(parser: &mut Parser,
|
|||||||
match globals[global_index as usize].initializer {
|
match globals[global_index as usize].initializer {
|
||||||
GlobalInit::I32Const(value) => {
|
GlobalInit::I32Const(value) => {
|
||||||
if value < 0 {
|
if value < 0 {
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from("negative offset value",),),);
|
return Err(SectionParsingError::WrongSectionContent(String::from("\
|
||||||
|
negative offset value")));
|
||||||
} else {
|
} else {
|
||||||
value as usize
|
value as usize
|
||||||
}
|
}
|
||||||
|
|||||||
102
lib/wasm2cretonne/tests/testsuite.rs
Normal file
102
lib/wasm2cretonne/tests/testsuite.rs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
extern crate wasm2cretonne;
|
||||||
|
extern crate cretonne;
|
||||||
|
|
||||||
|
use wasm2cretonne::{translate_module, FunctionTranslation, DummyRuntime, WasmRuntime};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::fs;
|
||||||
|
use cretonne::ir;
|
||||||
|
use cretonne::ir::entities::AnyEntity;
|
||||||
|
use cretonne::isa::TargetIsa;
|
||||||
|
use cretonne::verifier;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testsuite() {
|
||||||
|
let mut paths: Vec<_> = fs::read_dir("testsuite")
|
||||||
|
.unwrap()
|
||||||
|
.map(|r| r.unwrap())
|
||||||
|
.collect();
|
||||||
|
paths.sort_by_key(|dir| dir.path());
|
||||||
|
for path in paths {
|
||||||
|
let path = path.path();
|
||||||
|
match handle_module(path) {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(message) => println!("{}", message),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_wasm_file(path: PathBuf) -> Result<Vec<u8>, io::Error> {
|
||||||
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
|
let file = File::open(path)?;
|
||||||
|
let mut buf_reader = BufReader::new(file);
|
||||||
|
buf_reader.read_to_end(&mut buf)?;
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_module(path: PathBuf) -> Result<(), String> {
|
||||||
|
let data = match path.extension() {
|
||||||
|
None => {
|
||||||
|
return Err(String::from("the file extension is not wasm or wast"));
|
||||||
|
}
|
||||||
|
Some(ext) => {
|
||||||
|
match ext.to_str() {
|
||||||
|
Some("wasm") => {
|
||||||
|
match read_wasm_file(path.clone()) {
|
||||||
|
Ok(data) => data,
|
||||||
|
Err(err) => {
|
||||||
|
return Err(String::from(err.description()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None | Some(&_) => {
|
||||||
|
return Err(String::from("the file extension is not wasm or wast"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut dummy_runtime = DummyRuntime::new();
|
||||||
|
let translation = {
|
||||||
|
let mut runtime: &mut WasmRuntime = &mut dummy_runtime;
|
||||||
|
match translate_module(&data, runtime) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(string) => {
|
||||||
|
return Err(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for func in translation.functions.iter() {
|
||||||
|
let il = match func {
|
||||||
|
&FunctionTranslation::Import() => continue,
|
||||||
|
&FunctionTranslation::Code { ref il, .. } => il.clone(),
|
||||||
|
};
|
||||||
|
match verifier::verify_function(&il, None) {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(err) => return Err(pretty_verifier_error(&il, None, err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Pretty-print a verifier error.
|
||||||
|
pub fn pretty_verifier_error(func: &ir::Function,
|
||||||
|
isa: Option<&TargetIsa>,
|
||||||
|
err: verifier::Error)
|
||||||
|
-> String {
|
||||||
|
let msg = err.to_string();
|
||||||
|
let str1 = match err.location {
|
||||||
|
AnyEntity::Inst(inst) => {
|
||||||
|
format!("{}\n{}: {}\n\n",
|
||||||
|
msg,
|
||||||
|
inst,
|
||||||
|
func.dfg.display_inst(inst, isa))
|
||||||
|
}
|
||||||
|
_ => String::from(format!("{}\n", msg)),
|
||||||
|
};
|
||||||
|
format!("{}{}", str1, func.display(isa))
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user