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:
@@ -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 {
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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(&[])?;
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user