Use Linker in *.wast testing (#1391)

* Use `Linker` in `*.wast` testing

By default `Linker` disallows shadowing previously defined items, but it
looks like the `*.wast` test suites rely on this so this commit adds a
boolean flag to `Linker` as well indicating whether duplicates are
allowed.

* Review comments

* Add a test with a number of recursive instances

* Deny warnings in doctests

* No tabs
This commit is contained in:
Alex Crichton
2020-03-24 17:37:32 -05:00
committed by GitHub
parent b214804850
commit c241f18b81
7 changed files with 133 additions and 86 deletions

View File

@@ -1,61 +1,46 @@
use std::collections::HashMap;
use anyhow::Result;
use wasmtime::*;
/// Return an instance implementing the "spectest" interface used in the
/// spec testsuite.
pub fn instantiate_spectest(store: &Store) -> HashMap<&'static str, Extern> {
let mut ret = HashMap::new();
let func = Func::wrap(store, || {});
ret.insert("print", Extern::Func(func));
let func = Func::wrap(store, |val: i32| println!("{}: i32", val));
ret.insert("print_i32", Extern::Func(func));
let func = Func::wrap(store, |val: i64| println!("{}: i64", val));
ret.insert("print_i64", Extern::Func(func));
let func = Func::wrap(store, |val: f32| println!("{}: f32", val));
ret.insert("print_f32", Extern::Func(func));
let func = Func::wrap(store, |val: f64| println!("{}: f64", val));
ret.insert("print_f64", Extern::Func(func));
let func = Func::wrap(store, |i: i32, f: f32| {
pub fn link_spectest(linker: &mut Linker) -> Result<()> {
linker.func("spectest", "print", || {})?;
linker.func("spectest", "print_i32", |val: i32| println!("{}: i32", val))?;
linker.func("spectest", "print_i64", |val: i64| println!("{}: i64", val))?;
linker.func("spectest", "print_f32", |val: f32| println!("{}: f32", val))?;
linker.func("spectest", "print_f64", |val: f64| println!("{}: f64", val))?;
linker.func("spectest", "print_i32_f32", |i: i32, f: f32| {
println!("{}: i32", i);
println!("{}: f32", f);
});
ret.insert("print_i32_f32", Extern::Func(func));
let func = Func::wrap(store, |f1: f64, f2: f64| {
})?;
linker.func("spectest", "print_f64_f64", |f1: f64, f2: f64| {
println!("{}: f64", f1);
println!("{}: f64", f2);
});
ret.insert("print_f64_f64", Extern::Func(func));
})?;
let ty = GlobalType::new(ValType::I32, Mutability::Const);
let g = Global::new(store, ty, Val::I32(666)).unwrap();
ret.insert("global_i32", Extern::Global(g));
let g = Global::new(linker.store(), ty, Val::I32(666))?;
linker.define("spectest", "global_i32", g)?;
let ty = GlobalType::new(ValType::I64, Mutability::Const);
let g = Global::new(store, ty, Val::I64(666)).unwrap();
ret.insert("global_i64", Extern::Global(g));
let g = Global::new(linker.store(), ty, Val::I64(666))?;
linker.define("spectest", "global_i64", g)?;
let ty = GlobalType::new(ValType::F32, Mutability::Const);
let g = Global::new(store, ty, Val::F32(0x4426_8000)).unwrap();
ret.insert("global_f32", Extern::Global(g));
let g = Global::new(linker.store(), ty, Val::F32(0x4426_8000))?;
linker.define("spectest", "global_f32", g)?;
let ty = GlobalType::new(ValType::F64, Mutability::Const);
let g = Global::new(store, ty, Val::F64(0x4084_d000_0000_0000)).unwrap();
ret.insert("global_f64", Extern::Global(g));
let g = Global::new(linker.store(), ty, Val::F64(0x4084_d000_0000_0000))?;
linker.define("spectest", "global_f64", g)?;
let ty = TableType::new(ValType::FuncRef, Limits::new(10, Some(20)));
let table = Table::new(store, ty, Val::AnyRef(AnyRef::Null)).unwrap();
ret.insert("table", Extern::Table(table));
let table = Table::new(linker.store(), ty, Val::AnyRef(AnyRef::Null))?;
linker.define("spectest", "table", table)?;
let ty = MemoryType::new(Limits::new(1, Some(2)));
let memory = Memory::new(store, ty);
ret.insert("memory", Extern::Memory(memory));
let memory = Memory::new(linker.store(), ty);
linker.define("spectest", "memory", memory)?;
return ret;
Ok(())
}