Fix a "trampoline missing" panic with components (#4296)
One test case I wrote recently was to import a lowered function into a wasm module and then immediately export it. This previously didn't work because trampoline lookup would fail as the original `VMCallerCheckedAnyfunc` function pointer points into the `trampoline_obj` of a component which wasn't registered with the `ModuleRegistry`. This plumbs through the necessary configuration to get that all hooked up.
This commit is contained in:
@@ -3,7 +3,7 @@ use anyhow::Result;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use wasmtime::component::*;
|
||||
use wasmtime::{Store, Trap, TrapCode};
|
||||
use wasmtime::{Store, StoreContextMut, Trap, TrapCode};
|
||||
|
||||
const CANON_32BIT_NAN: u32 = 0b01111111110000000000000000000000;
|
||||
const CANON_64BIT_NAN: u64 = 0b0111111111111000000000000000000000000000000000000000000000000000;
|
||||
@@ -1858,3 +1858,58 @@ fn invalid_alignment() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drop_component_still_works() -> Result<()> {
|
||||
let component = r#"
|
||||
(component
|
||||
(import "f" (func $f))
|
||||
|
||||
(core func $f_lower
|
||||
(canon lower (func $f))
|
||||
)
|
||||
(core module $m
|
||||
(import "" "" (func $f))
|
||||
|
||||
(func $f2
|
||||
call $f
|
||||
call $f
|
||||
)
|
||||
|
||||
(export "f" (func $f2))
|
||||
)
|
||||
(core instance $i (instantiate $m
|
||||
(with "" (instance
|
||||
(export "" (func $f_lower))
|
||||
))
|
||||
))
|
||||
(func (export "f")
|
||||
(canon lift
|
||||
(core func $i "f")
|
||||
)
|
||||
)
|
||||
)
|
||||
"#;
|
||||
|
||||
let (mut store, instance) = {
|
||||
let engine = super::engine();
|
||||
let component = Component::new(&engine, component)?;
|
||||
let mut store = Store::new(&engine, 0);
|
||||
let mut linker = Linker::new(&engine);
|
||||
linker
|
||||
.root()
|
||||
.func_wrap("f", |mut store: StoreContextMut<'_, u32>| -> Result<()> {
|
||||
*store.data_mut() += 1;
|
||||
Ok(())
|
||||
})?;
|
||||
let instance = linker.instantiate(&mut store, &component)?;
|
||||
(store, instance)
|
||||
};
|
||||
|
||||
let f = instance.get_typed_func::<(), (), _>(&mut store, "f")?;
|
||||
assert_eq!(*store.data(), 0);
|
||||
f.call(&mut store, ())?;
|
||||
assert_eq!(*store.data(), 2);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -614,3 +614,50 @@ fn bad_import_alignment() -> Result<()> {
|
||||
assert!(trap.to_string().contains("pointer not aligned"), "{}", trap);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_actual_wasm_code() -> Result<()> {
|
||||
let component = r#"
|
||||
(component
|
||||
(import "f" (func $f))
|
||||
|
||||
(core func $f_lower
|
||||
(canon lower (func $f))
|
||||
)
|
||||
(core module $m
|
||||
(import "" "" (func $f))
|
||||
(export "f" (func $f))
|
||||
)
|
||||
(core instance $i (instantiate $m
|
||||
(with "" (instance
|
||||
(export "" (func $f_lower))
|
||||
))
|
||||
))
|
||||
(func (export "thunk")
|
||||
(canon lift
|
||||
(core func $i "f")
|
||||
)
|
||||
)
|
||||
)
|
||||
"#;
|
||||
|
||||
let engine = super::engine();
|
||||
let component = Component::new(&engine, component)?;
|
||||
let mut store = Store::new(&engine, 0);
|
||||
let mut linker = Linker::new(&engine);
|
||||
linker
|
||||
.root()
|
||||
.func_wrap("f", |mut store: StoreContextMut<'_, u32>| -> Result<()> {
|
||||
*store.data_mut() += 1;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
let instance = linker.instantiate(&mut store, &component)?;
|
||||
let thunk = instance.get_typed_func::<(), (), _>(&mut store, "thunk")?;
|
||||
|
||||
assert_eq!(*store.data(), 0);
|
||||
thunk.call(&mut store, ())?;
|
||||
assert_eq!(*store.data(), 1);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user