Disconnects Store state fields from Compiler (#1761)

*  Moves CodeMemory, VMInterrupts and SignatureRegistry from Compiler
*  CompiledModule holds CodeMemory and GdbJitImageRegistration
*  Store keeps track of its JIT code
*  Makes "jit_int.rs" stuff Send+Sync
*  Adds the threads example.
This commit is contained in:
Yury Delendik
2020-06-02 13:44:39 -05:00
committed by GitHub
parent b41330393d
commit 15c68f2cc1
61 changed files with 982 additions and 663 deletions

View File

@@ -90,8 +90,8 @@ mod tests {
fn test_custom_signal_handler_single_instance() -> Result<()> {
let engine = Engine::new(&Config::default());
let store = Store::new(&engine);
let module = Module::new(&store, WAT1)?;
let instance = Instance::new(&module, &[])?;
let module = Module::new(&engine, WAT1)?;
let instance = Instance::new(&store, &module, &[])?;
let (base, length) = set_up_memory(&instance);
unsafe {
@@ -150,11 +150,11 @@ mod tests {
fn test_custom_signal_handler_multiple_instances() -> Result<()> {
let engine = Engine::new(&Config::default());
let store = Store::new(&engine);
let module = Module::new(&store, WAT1)?;
let module = Module::new(&engine, WAT1)?;
// Set up multiple instances
let instance1 = Instance::new(&module, &[])?;
let instance1 = Instance::new(&store, &module, &[])?;
let instance1_handler_triggered = Rc::new(AtomicBool::new(false));
unsafe {
@@ -196,7 +196,7 @@ mod tests {
);
}
let instance2 = Instance::new(&module, &[]).expect("failed to instantiate module");
let instance2 = Instance::new(&store, &module, &[]).expect("failed to instantiate module");
let instance2_handler_triggered = Rc::new(AtomicBool::new(false));
unsafe {
@@ -244,8 +244,8 @@ mod tests {
let store = Store::new(&engine);
// instance1 which defines 'read'
let module1 = Module::new(&store, WAT1)?;
let instance1 = Instance::new(&module1, &[])?;
let module1 = Module::new(&engine, WAT1)?;
let instance1 = Instance::new(&store, &module1, &[])?;
let (base1, length1) = set_up_memory(&instance1);
unsafe {
store.set_signal_handler(move |signum, siginfo, _| {
@@ -258,8 +258,8 @@ mod tests {
let instance1_read = instance1_exports.next().unwrap();
// instance2 which calls 'instance1.read'
let module2 = Module::new(&store, WAT2)?;
let instance2 = Instance::new(&module2, &[instance1_read.into_extern()])?;
let module2 = Module::new(&engine, WAT2)?;
let instance2 = Instance::new(&store, &module2, &[instance1_read.into_extern()])?;
// since 'instance2.run' calls 'instance1.read' we need to set up the signal handler to handle
// SIGSEGV originating from within the memory of instance1
unsafe {

View File

@@ -57,8 +57,9 @@ fn bad_tables() {
fn cross_store() -> anyhow::Result<()> {
let mut cfg = Config::new();
cfg.wasm_reference_types(true);
let store1 = Store::new(&Engine::new(&cfg));
let store2 = Store::new(&Engine::new(&cfg));
let engine = Engine::new(&cfg);
let store1 = Store::new(&engine);
let store2 = Store::new(&engine);
// ============ Cross-store instantiation ==============
@@ -70,17 +71,17 @@ fn cross_store() -> anyhow::Result<()> {
let ty = TableType::new(ValType::FuncRef, Limits::new(1, None));
let table = Table::new(&store2, ty, Val::ExternRef(None))?;
let need_func = Module::new(&store1, r#"(module (import "" "" (func)))"#)?;
assert!(Instance::new(&need_func, &[func.into()]).is_err());
let need_func = Module::new(&engine, r#"(module (import "" "" (func)))"#)?;
assert!(Instance::new(&store1, &need_func, &[func.into()]).is_err());
let need_global = Module::new(&store1, r#"(module (import "" "" (global i32)))"#)?;
assert!(Instance::new(&need_global, &[global.into()]).is_err());
let need_global = Module::new(&engine, r#"(module (import "" "" (global i32)))"#)?;
assert!(Instance::new(&store1, &need_global, &[global.into()]).is_err());
let need_table = Module::new(&store1, r#"(module (import "" "" (table 1 funcref)))"#)?;
assert!(Instance::new(&need_table, &[table.into()]).is_err());
let need_table = Module::new(&engine, r#"(module (import "" "" (table 1 funcref)))"#)?;
assert!(Instance::new(&store1, &need_table, &[table.into()]).is_err());
let need_memory = Module::new(&store1, r#"(module (import "" "" (memory 1)))"#)?;
assert!(Instance::new(&need_memory, &[memory.into()]).is_err());
let need_memory = Module::new(&engine, r#"(module (import "" "" (memory 1)))"#)?;
assert!(Instance::new(&store1, &need_memory, &[memory.into()]).is_err());
// ============ Cross-store globals ==============
@@ -106,7 +107,7 @@ fn cross_store() -> anyhow::Result<()> {
// ============ Cross-store funcs ==============
// TODO: need to actually fill this out once we support externref params/locals
// let module = Module::new(&store1, r#"(module (func (export "a") (param funcref)))"#)?;
// let module = Module::new(&engine, r#"(module (func (export "a") (param funcref)))"#)?;
Ok(())
}

View File

@@ -61,8 +61,8 @@ fn dtor_delayed() -> Result<()> {
assert_eq!(HITS.load(SeqCst), 0);
let wasm = wat::parse_str(r#"(import "" "" (func))"#)?;
let module = Module::new(&store, &wasm)?;
let instance = Instance::new(&module, &[func.into()])?;
let module = Module::new(store.engine(), &wasm)?;
let instance = Instance::new(&store, &module, &[func.into()])?;
assert_eq!(HITS.load(SeqCst), 0);
drop((instance, module, store));
assert_eq!(HITS.load(SeqCst), 1);
@@ -142,8 +142,9 @@ fn import_works() -> Result<()> {
"#,
)?;
let store = Store::default();
let module = Module::new(&store, &wasm)?;
let module = Module::new(store.engine(), &wasm)?;
Instance::new(
&store,
&module,
&[
Func::wrap(&store, || {
@@ -195,8 +196,9 @@ fn trap_import() -> Result<()> {
"#,
)?;
let store = Store::default();
let module = Module::new(&store, &wasm)?;
let module = Module::new(store.engine(), &wasm)?;
let trap = Instance::new(
&store,
&module,
&[Func::wrap(&store, || -> Result<(), Trap> { Err(Trap::new("foo")) }).into()],
)
@@ -261,7 +263,7 @@ fn get_from_signature() {
fn get_from_module() -> anyhow::Result<()> {
let store = Store::default();
let module = Module::new(
&store,
store.engine(),
r#"
(module
(func (export "f0"))
@@ -272,7 +274,7 @@ fn get_from_module() -> anyhow::Result<()> {
"#,
)?;
let instance = Instance::new(&module, &[])?;
let instance = Instance::new(&store, &module, &[])?;
let f0 = instance.get_func("f0").unwrap();
assert!(f0.get0::<()>().is_ok());
assert!(f0.get0::<i32>().is_err());
@@ -340,7 +342,7 @@ fn caller_memory() -> anyhow::Result<()> {
assert!(c.get_export("x").is_none());
});
let module = Module::new(
&store,
store.engine(),
r#"
(module
(import "" "" (func $f))
@@ -349,13 +351,13 @@ fn caller_memory() -> anyhow::Result<()> {
"#,
)?;
Instance::new(&module, &[f.into()])?;
Instance::new(&store, &module, &[f.into()])?;
let f = Func::wrap(&store, |c: Caller<'_>| {
assert!(c.get_export("memory").is_some());
});
let module = Module::new(
&store,
store.engine(),
r#"
(module
(import "" "" (func $f))
@@ -365,7 +367,7 @@ fn caller_memory() -> anyhow::Result<()> {
"#,
)?;
Instance::new(&module, &[f.into()])?;
Instance::new(&store, &module, &[f.into()])?;
let f = Func::wrap(&store, |c: Caller<'_>| {
assert!(c.get_export("m").is_some());
@@ -374,7 +376,7 @@ fn caller_memory() -> anyhow::Result<()> {
assert!(c.get_export("t").is_none());
});
let module = Module::new(
&store,
store.engine(),
r#"
(module
(import "" "" (func $f))
@@ -387,7 +389,7 @@ fn caller_memory() -> anyhow::Result<()> {
"#,
)?;
Instance::new(&module, &[f.into()])?;
Instance::new(&store, &module, &[f.into()])?;
Ok(())
}

View File

@@ -63,19 +63,19 @@ fn mutability() -> anyhow::Result<()> {
fn use_after_drop() -> anyhow::Result<()> {
let store = Store::default();
let module = Module::new(
&store,
store.engine(),
r#"
(module
(global (export "foo") (mut i32) (i32.const 100)))
"#,
)?;
let instance = Instance::new(&module, &[])?;
let instance = Instance::new(&store, &module, &[])?;
let g = instance.get_global("foo").unwrap();
assert_eq!(g.get().i32(), Some(100));
g.set(101.into())?;
drop(instance);
assert_eq!(g.get().i32(), Some(101));
Instance::new(&module, &[])?;
Instance::new(&store, &module, &[])?;
assert_eq!(g.get().i32(), Some(101));
drop(module);
assert_eq!(g.get().i32(), Some(101));

View File

@@ -19,14 +19,14 @@ fn hugely_recursive_module(store: &Store) -> anyhow::Result<Module> {
}
wat.push_str("(func call 0)\n");
Module::new(&store, &wat)
Module::new(store.engine(), &wat)
}
#[test]
fn loops_interruptable() -> anyhow::Result<()> {
let store = interruptable_store();
let module = Module::new(&store, r#"(func (export "loop") (loop br 0))"#)?;
let instance = Instance::new(&module, &[])?;
let module = Module::new(store.engine(), r#"(func (export "loop") (loop br 0))"#)?;
let instance = Instance::new(&store, &module, &[])?;
let iloop = instance.get_func("loop").unwrap().get0::<()>()?;
store.interrupt_handle()?.interrupt();
let trap = iloop().unwrap_err();
@@ -39,7 +39,7 @@ fn functions_interruptable() -> anyhow::Result<()> {
let store = interruptable_store();
let module = hugely_recursive_module(&store)?;
let func = Func::wrap(&store, || {});
let instance = Instance::new(&module, &[func.into()])?;
let instance = Instance::new(&store, &module, &[func.into()])?;
let iloop = instance.get_func("loop").unwrap().get0::<()>()?;
store.interrupt_handle()?.interrupt();
let trap = iloop().unwrap_err();
@@ -59,7 +59,7 @@ fn loop_interrupt_from_afar() -> anyhow::Result<()> {
static HITS: AtomicUsize = AtomicUsize::new(0);
let store = interruptable_store();
let module = Module::new(
&store,
store.engine(),
r#"
(import "" "" (func))
@@ -73,7 +73,7 @@ fn loop_interrupt_from_afar() -> anyhow::Result<()> {
let func = Func::wrap(&store, || {
HITS.fetch_add(1, SeqCst);
});
let instance = Instance::new(&module, &[func.into()])?;
let instance = Instance::new(&store, &module, &[func.into()])?;
// Use the instance's interrupt handle to wait for it to enter the loop long
// enough and then we signal an interrupt happens.
@@ -109,7 +109,7 @@ fn function_interrupt_from_afar() -> anyhow::Result<()> {
let func = Func::wrap(&store, || {
HITS.fetch_add(1, SeqCst);
});
let instance = Instance::new(&module, &[func.into()])?;
let instance = Instance::new(&store, &module, &[func.into()])?;
// Use the instance's interrupt handle to wait for it to enter the loop long
// enough and then we signal an interrupt happens.

View File

@@ -17,7 +17,7 @@ fn test_import_calling_export() {
"#;
let store = Store::default();
let module = Module::new(&store, WAT).expect("failed to create module");
let module = Module::new(store.engine(), WAT).expect("failed to create module");
let other = Rc::new(RefCell::new(None::<Func>));
let other2 = Rc::downgrade(&other);
@@ -40,7 +40,7 @@ fn test_import_calling_export() {
let imports = vec![callback_func.into()];
let instance =
Instance::new(&module, imports.as_slice()).expect("failed to instantiate module");
Instance::new(&store, &module, imports.as_slice()).expect("failed to instantiate module");
let run_func = instance
.get_func("run")
@@ -67,7 +67,7 @@ fn test_returns_incorrect_type() -> Result<()> {
"#;
let store = Store::default();
let module = Module::new(&store, WAT)?;
let module = Module::new(store.engine(), WAT)?;
let callback_func = Func::new(
&store,
@@ -80,7 +80,7 @@ fn test_returns_incorrect_type() -> Result<()> {
);
let imports = vec![callback_func.into()];
let instance = Instance::new(&module, imports.as_slice())?;
let instance = Instance::new(&store, &module, imports.as_slice())?;
let run_func = instance
.get_func("run")

View File

@@ -15,7 +15,7 @@ fn same_import_names_still_distinct() -> anyhow::Result<()> {
"#;
let store = Store::default();
let module = Module::new(&store, WAT)?;
let module = Module::new(store.engine(), WAT)?;
let imports = [
Func::new(
@@ -41,7 +41,7 @@ fn same_import_names_still_distinct() -> anyhow::Result<()> {
)
.into(),
];
let instance = Instance::new(&module, &imports)?;
let instance = Instance::new(&store, &module, &imports)?;
let func = instance.get_func("foo").unwrap();
let results = func.call(&[])?;

View File

@@ -4,10 +4,10 @@ use wasmtime::*;
#[test]
fn wrong_import_numbers() -> Result<()> {
let store = Store::default();
let module = Module::new(&store, r#"(module (import "" "" (func)))"#)?;
let module = Module::new(store.engine(), r#"(module (import "" "" (func)))"#)?;
assert!(Instance::new(&module, &[]).is_err());
assert!(Instance::new(&store, &module, &[]).is_err());
let func = Func::wrap(&store, || {});
assert!(Instance::new(&module, &[func.clone().into(), func.into()]).is_err());
assert!(Instance::new(&store, &module, &[func.clone().into(), func.into()]).is_err());
Ok(())
}

View File

@@ -13,8 +13,8 @@ fn test_invoke_func_via_table() -> Result<()> {
(elem (i32.const 0) $f)
)
"#;
let module = Module::new(&store, wat).context("> Error compiling module!")?;
let instance = Instance::new(&module, &[]).context("> Error instantiating module!")?;
let module = Module::new(store.engine(), wat).context("> Error compiling module!")?;
let instance = Instance::new(&store, &module, &[]).context("> Error instantiating module!")?;
let f = instance
.get_table("table")

View File

@@ -5,13 +5,16 @@ use wasmtime::*;
fn link_undefined() -> Result<()> {
let store = Store::default();
let linker = Linker::new(&store);
let module = Module::new(&store, r#"(module (import "" "" (func)))"#)?;
let module = Module::new(store.engine(), r#"(module (import "" "" (func)))"#)?;
assert!(linker.instantiate(&module).is_err());
let module = Module::new(&store, r#"(module (import "" "" (global i32)))"#)?;
let module = Module::new(store.engine(), r#"(module (import "" "" (global i32)))"#)?;
assert!(linker.instantiate(&module).is_err());
let module = Module::new(&store, r#"(module (import "" "" (memory 1)))"#)?;
let module = Module::new(store.engine(), r#"(module (import "" "" (memory 1)))"#)?;
assert!(linker.instantiate(&module).is_err());
let module = Module::new(&store, r#"(module (import "" "" (table 1 funcref)))"#)?;
let module = Module::new(
store.engine(),
r#"(module (import "" "" (table 1 funcref)))"#,
)?;
assert!(linker.instantiate(&module).is_err());
Ok(())
}
@@ -71,7 +74,7 @@ fn function_interposition() -> Result<()> {
let mut linker = Linker::new(&store);
linker.allow_shadowing(true);
let mut module = Module::new(
&store,
store.engine(),
r#"(module (func (export "green") (result i32) (i32.const 7)))"#,
)?;
for _ in 0..4 {
@@ -82,7 +85,7 @@ fn function_interposition() -> Result<()> {
instance.get_export("green").unwrap().clone(),
)?;
module = Module::new(
&store,
store.engine(),
r#"(module
(import "red" "green" (func (result i32)))
(func (export "green") (result i32) (i32.mul (call 0) (i32.const 2)))
@@ -104,7 +107,7 @@ fn function_interposition_renamed() -> Result<()> {
let mut linker = Linker::new(&store);
linker.allow_shadowing(true);
let mut module = Module::new(
&store,
store.engine(),
r#"(module (func (export "export") (result i32) (i32.const 7)))"#,
)?;
for _ in 0..4 {
@@ -115,7 +118,7 @@ fn function_interposition_renamed() -> Result<()> {
instance.get_export("export").unwrap().clone(),
)?;
module = Module::new(
&store,
store.engine(),
r#"(module
(import "red" "green" (func (result i32)))
(func (export "export") (result i32) (i32.mul (call 0) (i32.const 2)))
@@ -137,14 +140,14 @@ fn module_interposition() -> Result<()> {
let mut linker = Linker::new(&store);
linker.allow_shadowing(true);
let mut module = Module::new(
&store,
store.engine(),
r#"(module (func (export "export") (result i32) (i32.const 7)))"#,
)?;
for _ in 0..4 {
let instance = linker.instantiate(&module)?;
linker.instance("instance", &instance)?;
module = Module::new(
&store,
store.engine(),
r#"(module
(import "instance" "export" (func (result i32)))
(func (export "export") (result i32) (i32.mul (call 0) (i32.const 2)))

View File

@@ -143,14 +143,14 @@ mod not_for_windows {
fn host_memory() -> anyhow::Result<()> {
let (store, mem_creator) = config();
let module = Module::new(
&store,
store.engine(),
r#"
(module
(memory (export "memory") 1)
)
"#,
)?;
Instance::new(&module, &[])?;
Instance::new(&store, &module, &[])?;
assert_eq!(*mem_creator.num_created_memories.lock().unwrap(), 1);
@@ -161,7 +161,7 @@ mod not_for_windows {
fn host_memory_grow() -> anyhow::Result<()> {
let (store, mem_creator) = config();
let module = Module::new(
&store,
store.engine(),
r#"
(module
(func $f (drop (memory.grow (i32.const 1))))
@@ -171,8 +171,8 @@ mod not_for_windows {
"#,
)?;
let instance1 = Instance::new(&module, &[])?;
let instance2 = Instance::new(&module, &[])?;
let instance1 = Instance::new(&store, &module, &[])?;
let instance2 = Instance::new(&store, &module, &[])?;
assert_eq!(*mem_creator.num_created_memories.lock().unwrap(), 2);

View File

@@ -2,14 +2,14 @@ use wasmtime::*;
#[test]
fn test_module_no_name() -> anyhow::Result<()> {
let store = Store::default();
let engine = Engine::default();
let wat = r#"
(module
(func (export "run") (nop))
)
"#;
let module = Module::new(&store, wat)?;
let module = Module::new(&engine, wat)?;
assert_eq!(module.name(), None);
Ok(())
@@ -17,17 +17,17 @@ fn test_module_no_name() -> anyhow::Result<()> {
#[test]
fn test_module_name() -> anyhow::Result<()> {
let store = Store::default();
let engine = Engine::default();
let wat = r#"
(module $from_name_section
(func (export "run") (nop))
)
"#;
let module = Module::new(&store, wat)?;
let module = Module::new(&engine, wat)?;
assert_eq!(module.name(), Some("from_name_section"));
let module = Module::new_with_name(&store, wat, "override")?;
let module = Module::new_with_name(&engine, wat, "override")?;
assert_eq!(module.name(), Some("override"));
Ok(())

View File

@@ -12,7 +12,7 @@ fn host_always_has_some_stack() -> anyhow::Result<()> {
// Create a module that's infinitely recursive, but calls the host on each
// level of wasm stack to always test how much host stack we have left.
let module = Module::new(
&store,
store.engine(),
r#"
(module
(import "" "" (func $host))
@@ -23,7 +23,7 @@ fn host_always_has_some_stack() -> anyhow::Result<()> {
"#,
)?;
let func = Func::wrap(&store, test_host_stack);
let instance = Instance::new(&module, &[func.into()])?;
let instance = Instance::new(&store, &module, &[func.into()])?;
let foo = instance.get_func("foo").unwrap().get0::<()>()?;
// Make sure that our function traps and the trap says that the call stack

View File

@@ -12,11 +12,11 @@ fn test_trap_return() -> Result<()> {
)
"#;
let module = Module::new(&store, wat)?;
let module = Module::new(store.engine(), wat)?;
let hello_type = FuncType::new(Box::new([]), Box::new([]));
let hello_func = Func::new(&store, hello_type, |_, _, _| Err(Trap::new("test 123")));
let instance = Instance::new(&module, &[hello_func.into()])?;
let instance = Instance::new(&store, &module, &[hello_func.into()])?;
let run_func = instance.get_func("run").expect("expected function export");
let e = run_func
@@ -41,8 +41,8 @@ fn test_trap_trace() -> Result<()> {
)
"#;
let module = Module::new(&store, wat)?;
let instance = Instance::new(&module, &[])?;
let module = Module::new(store.engine(), wat)?;
let instance = Instance::new(&store, &module, &[])?;
let run_func = instance.get_func("run").expect("expected function export");
let e = run_func
@@ -87,8 +87,8 @@ fn test_trap_trace_cb() -> Result<()> {
let fn_type = FuncType::new(Box::new([]), Box::new([]));
let fn_func = Func::new(&store, fn_type, |_, _, _| Err(Trap::new("cb throw")));
let module = Module::new(&store, wat)?;
let instance = Instance::new(&module, &[fn_func.into()])?;
let module = Module::new(store.engine(), wat)?;
let instance = Instance::new(&store, &module, &[fn_func.into()])?;
let run_func = instance.get_func("run").expect("expected function export");
let e = run_func
@@ -118,8 +118,8 @@ fn test_trap_stack_overflow() -> Result<()> {
)
"#;
let module = Module::new(&store, wat)?;
let instance = Instance::new(&module, &[])?;
let module = Module::new(store.engine(), wat)?;
let instance = Instance::new(&store, &module, &[])?;
let run_func = instance.get_func("run").expect("expected function export");
let e = run_func
@@ -153,8 +153,8 @@ fn trap_display_pretty() -> Result<()> {
)
"#;
let module = Module::new(&store, wat)?;
let instance = Instance::new(&module, &[])?;
let module = Module::new(store.engine(), wat)?;
let instance = Instance::new(&store, &module, &[])?;
let run_func = instance.get_func("bar").expect("expected function export");
let e = run_func.call(&[]).err().expect("error calling function");
@@ -185,8 +185,8 @@ fn trap_display_multi_module() -> Result<()> {
)
"#;
let module = Module::new(&store, wat)?;
let instance = Instance::new(&module, &[])?;
let module = Module::new(store.engine(), wat)?;
let instance = Instance::new(&store, &module, &[])?;
let bar = instance.get_export("bar").unwrap();
let wat = r#"
@@ -196,8 +196,8 @@ fn trap_display_multi_module() -> Result<()> {
(func (export "bar2") call $middle)
)
"#;
let module = Module::new(&store, wat)?;
let instance = Instance::new(&module, &[bar])?;
let module = Module::new(store.engine(), wat)?;
let instance = Instance::new(&store, &module, &[bar])?;
let bar2 = instance.get_func("bar2").expect("expected function export");
let e = bar2.call(&[]).err().expect("error calling function");
@@ -230,10 +230,12 @@ fn trap_start_function_import() -> Result<()> {
"#,
)?;
let module = Module::new(&store, &binary)?;
let module = Module::new(store.engine(), &binary)?;
let sig = FuncType::new(Box::new([]), Box::new([]));
let func = Func::new(&store, sig, |_, _, _| Err(Trap::new("user trap")));
let err = Instance::new(&module, &[func.into()]).err().unwrap();
let err = Instance::new(&store, &module, &[func.into()])
.err()
.unwrap();
assert!(err
.downcast_ref::<Trap>()
.unwrap()
@@ -257,10 +259,11 @@ fn rust_panic_import() -> Result<()> {
"#,
)?;
let module = Module::new(&store, &binary)?;
let module = Module::new(store.engine(), &binary)?;
let sig = FuncType::new(Box::new([]), Box::new([]));
let func = Func::new(&store, sig, |_, _, _| panic!("this is a panic"));
let instance = Instance::new(
&store,
&module,
&[
func.into(),
@@ -299,18 +302,18 @@ fn rust_panic_start_function() -> Result<()> {
"#,
)?;
let module = Module::new(&store, &binary)?;
let module = Module::new(store.engine(), &binary)?;
let sig = FuncType::new(Box::new([]), Box::new([]));
let func = Func::new(&store, sig, |_, _, _| panic!("this is a panic"));
let err = panic::catch_unwind(AssertUnwindSafe(|| {
drop(Instance::new(&module, &[func.into()]));
drop(Instance::new(&store, &module, &[func.into()]));
}))
.unwrap_err();
assert_eq!(err.downcast_ref::<&'static str>(), Some(&"this is a panic"));
let func = Func::wrap(&store, || panic!("this is another panic"));
let err = panic::catch_unwind(AssertUnwindSafe(|| {
drop(Instance::new(&module, &[func.into()]));
drop(Instance::new(&store, &module, &[func.into()]));
}))
.unwrap_err();
assert_eq!(
@@ -332,8 +335,8 @@ fn mismatched_arguments() -> Result<()> {
"#,
)?;
let module = Module::new(&store, &binary)?;
let instance = Instance::new(&module, &[])?;
let module = Module::new(store.engine(), &binary)?;
let instance = Instance::new(&store, &module, &[])?;
let func = instance.get_func("foo").unwrap();
assert_eq!(
func.call(&[]).unwrap_err().to_string(),
@@ -371,8 +374,8 @@ fn call_signature_mismatch() -> Result<()> {
"#,
)?;
let module = Module::new(&store, &binary)?;
let err = Instance::new(&module, &[])
let module = Module::new(store.engine(), &binary)?;
let err = Instance::new(&store, &module, &[])
.err()
.unwrap()
.downcast::<Trap>()
@@ -397,8 +400,8 @@ fn start_trap_pretty() -> Result<()> {
)
"#;
let module = Module::new(&store, wat)?;
let e = match Instance::new(&module, &[]) {
let module = Module::new(store.engine(), wat)?;
let e = match Instance::new(&store, &module, &[]) {
Ok(_) => panic!("expected failure"),
Err(e) => e.downcast::<Trap>()?,
};
@@ -420,8 +423,8 @@ wasm backtrace:
#[test]
fn present_after_module_drop() -> Result<()> {
let store = Store::default();
let module = Module::new(&store, r#"(func (export "foo") unreachable)"#)?;
let instance = Instance::new(&module, &[])?;
let module = Module::new(store.engine(), r#"(func (export "foo") unreachable)"#)?;
let instance = Instance::new(&store, &module, &[])?;
let func = instance.get_func("foo").unwrap();
println!("asserting before we drop modules");

View File

@@ -48,22 +48,25 @@ fn main() {
let tests: &[(&str, fn())] = &[
("normal segfault", || segfault()),
("make instance then segfault", || {
let store = Store::default();
let module = Module::new(&store, "(module)").unwrap();
let _instance = Instance::new(&module, &[]).unwrap();
let engine = Engine::default();
let store = Store::new(&engine);
let module = Module::new(&engine, "(module)").unwrap();
let _instance = Instance::new(&store, &module, &[]).unwrap();
segfault();
}),
("make instance then overrun the stack", || {
let store = Store::default();
let module = Module::new(&store, "(module)").unwrap();
let _instance = Instance::new(&module, &[]).unwrap();
let engine = Engine::default();
let store = Store::new(&engine);
let module = Module::new(&engine, "(module)").unwrap();
let _instance = Instance::new(&store, &module, &[]).unwrap();
println!("stack overrun: {}", overrun_the_stack());
}),
("segfault in a host function", || {
let store = Store::default();
let module = Module::new(&store, r#"(import "" "" (func)) (start 0)"#).unwrap();
let engine = Engine::default();
let store = Store::new(&engine);
let module = Module::new(&engine, r#"(import "" "" (func)) (start 0)"#).unwrap();
let segfault = Func::wrap(&store, || segfault());
Instance::new(&module, &[segfault.into()]).unwrap();
Instance::new(&store, &module, &[segfault.into()]).unwrap();
}),
];
match env::var(VAR_NAME) {