1 use cranelift_codegen::isa;
2 use cranelift_codegen::print_errors::pretty_verifier_error;
3 use cranelift_codegen::settings::{self, Flags};
4 use cranelift_codegen::verifier;
5 use cranelift_wasm::{translate_module, DummyEnvironment, FuncIndex, ReturnMode};
6 use std::fs;
7 use std::fs::File;
8 use std::io;
9 use std::io::prelude::*;
10 use std::path::Path;
11 use std::str::FromStr;
12 use target_lexicon::triple;
13 
14 #[test]
testsuite()15 fn testsuite() {
16     let mut paths: Vec<_> = fs::read_dir("../wasmtests")
17         .unwrap()
18         .map(|r| r.unwrap())
19         .filter(|p| {
20             // Ignore files starting with `.`, which could be editor temporary files
21             if let Some(stem) = p.path().file_stem() {
22                 if let Some(stemstr) = stem.to_str() {
23                     return !stemstr.starts_with('.');
24                 }
25             }
26             false
27         })
28         .collect();
29     paths.sort_by_key(|dir| dir.path());
30     let flags = Flags::new(settings::builder());
31     for path in paths {
32         let path = path.path();
33         println!("=== {} ===", path.display());
34         let data = read_module(&path);
35         handle_module(data, &flags, ReturnMode::NormalReturns);
36     }
37 }
38 
39 #[test]
use_fallthrough_return()40 fn use_fallthrough_return() {
41     let flags = Flags::new(settings::builder());
42     let path = Path::new("../wasmtests/use_fallthrough_return.wat");
43     let data = read_module(&path);
44     handle_module(data, &flags, ReturnMode::FallthroughReturn);
45 }
46 
47 #[test]
use_name_section()48 fn use_name_section() {
49     let data = wat::parse_str(
50         r#"
51         (module $module_name
52             (func $func_name (local $loc_name i32)
53             )
54         )"#,
55     )
56     .unwrap();
57 
58     let flags = Flags::new(settings::builder());
59     let triple = triple!("riscv64");
60     let isa = isa::lookup(triple).unwrap().finish(flags.clone());
61     let return_mode = ReturnMode::NormalReturns;
62     let mut dummy_environ = DummyEnvironment::new(isa.frontend_config(), return_mode, false);
63 
64     translate_module(data.as_ref(), &mut dummy_environ).unwrap();
65 
66     assert_eq!(
67         dummy_environ.get_func_name(FuncIndex::from_u32(0)).unwrap(),
68         "func_name"
69     );
70 }
71 
read_file(path: &Path) -> io::Result<Vec<u8>>72 fn read_file(path: &Path) -> io::Result<Vec<u8>> {
73     let mut buf: Vec<u8> = Vec::new();
74     let mut file = File::open(path)?;
75     file.read_to_end(&mut buf)?;
76     Ok(buf)
77 }
78 
read_module(path: &Path) -> Vec<u8>79 fn read_module(path: &Path) -> Vec<u8> {
80     match path.extension() {
81         None => {
82             panic!("the file extension is not wasm or wat");
83         }
84         Some(ext) => match ext.to_str() {
85             Some("wasm") => read_file(path).expect("error reading wasm file"),
86             Some("wat") => wat::parse_file(path).expect("failed to parse wat"),
87             None | Some(&_) => panic!("the file extension for {:?} is not wasm or wat", path),
88         },
89     }
90 }
91 
handle_module(data: Vec<u8>, flags: &Flags, return_mode: ReturnMode)92 fn handle_module(data: Vec<u8>, flags: &Flags, return_mode: ReturnMode) {
93     let triple = triple!("riscv64");
94     let isa = isa::lookup(triple).unwrap().finish(flags.clone());
95     let mut dummy_environ = DummyEnvironment::new(isa.frontend_config(), return_mode, false);
96 
97     translate_module(&data, &mut dummy_environ).unwrap();
98 
99     for func in dummy_environ.info.function_bodies.values() {
100         verifier::verify_function(func, &*isa)
101             .map_err(|errors| panic!(pretty_verifier_error(func, Some(&*isa), None, errors)))
102             .unwrap();
103     }
104 }
105