Add a verifier
The current implementation only performs a few basic checks.
This commit is contained in:
3
cranelift/src/tools/Cargo.lock
generated
3
cranelift/src/tools/Cargo.lock
generated
@@ -21,6 +21,9 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cretonne"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"regex 0.1.71 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cretonne-reader"
|
||||
|
||||
66
cranelift/src/tools/tests/verifier.rs
Normal file
66
cranelift/src/tools/tests/verifier.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
extern crate cretonne;
|
||||
extern crate cton_reader;
|
||||
extern crate glob;
|
||||
extern crate regex;
|
||||
|
||||
use std::env;
|
||||
use glob::glob;
|
||||
use regex::Regex;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use self::cton_reader::parser::Parser;
|
||||
use self::cretonne::verifier::Verifier;
|
||||
|
||||
/// Compile a function and run verifier tests based on specially formatted
|
||||
/// comments in the [function's] source.
|
||||
fn verifier_tests_from_source(function_source: &str) {
|
||||
let func_re = Regex::new("^[ \t]*function.*").unwrap();
|
||||
let err_re = Regex::new(";[ \t]*Err\\((.*)+\\)").unwrap();
|
||||
|
||||
// Each entry corresponds to an optional regular expression, where
|
||||
// the index corresponds to the function offset in our source code.
|
||||
// If no error is expected for a given function its entry will be
|
||||
// set to None.
|
||||
let mut verifier_results = Vec::new();
|
||||
for line in function_source.lines() {
|
||||
if func_re.is_match(line) {
|
||||
match err_re.captures(line) {
|
||||
Some(caps) => {
|
||||
verifier_results.push(Some(Regex::new(caps.at(1).unwrap()).unwrap()));
|
||||
},
|
||||
None => {
|
||||
verifier_results.push(None);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Run the verifier against each function and compare the output
|
||||
// with the expected result (as determined above).
|
||||
for (i, func) in Parser::parse(function_source).unwrap().into_iter().enumerate() {
|
||||
let result = Verifier::new(&func).run();
|
||||
match verifier_results[i] {
|
||||
Some(ref re) => {
|
||||
assert_eq!(re.is_match(&result.err().unwrap()), true);
|
||||
},
|
||||
None => {
|
||||
assert_eq!(result, Ok(()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all() {
|
||||
let testdir = format!("{}/tests/verifier_testdata/*.cton",
|
||||
env::current_dir().unwrap().display());
|
||||
|
||||
for entry in glob(&testdir).unwrap() {
|
||||
let path = entry.unwrap();
|
||||
println!("Testing {:?}", path);
|
||||
let mut file = File::open(&path).unwrap();
|
||||
let mut buffer = String::new();
|
||||
file.read_to_string(&mut buffer).unwrap();
|
||||
verifier_tests_from_source(&buffer);
|
||||
}
|
||||
}
|
||||
17
cranelift/src/tools/tests/verifier_testdata/bad_layout.cton
Normal file
17
cranelift/src/tools/tests/verifier_testdata/bad_layout.cton
Normal file
@@ -0,0 +1,17 @@
|
||||
function test(i32) { ; Err(terminating)
|
||||
ebb0(v0: i32):
|
||||
jump ebb1
|
||||
return
|
||||
ebb1:
|
||||
jump ebb2
|
||||
brz v0, ebb3
|
||||
ebb2:
|
||||
jump ebb3
|
||||
ebb3:
|
||||
return
|
||||
}
|
||||
|
||||
function test(i32) { ; Ok
|
||||
ebb0(v0: i32):
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user