diff --git a/crates/wasmtime/src/runtime.rs b/crates/wasmtime/src/runtime.rs index cbba86eafa98..94eea934c9af 100644 --- a/crates/wasmtime/src/runtime.rs +++ b/crates/wasmtime/src/runtime.rs @@ -609,6 +609,12 @@ impl Config { .finish(settings::Flags::new(self.flags.clone())) } + pub(crate) fn target_isa_with_reference_types(&self) -> Box { + let mut flags = self.flags.clone(); + flags.set("enable_safepoints", "true").unwrap(); + self.isa_flags.clone().finish(settings::Flags::new(flags)) + } + pub(crate) fn validator(&self) -> Validator { let mut ret = Validator::new(); ret.wasm_threads(self.wasm_threads) diff --git a/crates/wasmtime/src/trampoline/func.rs b/crates/wasmtime/src/trampoline/func.rs index a8fe766cca84..2ba739da5c38 100644 --- a/crates/wasmtime/src/trampoline/func.rs +++ b/crates/wasmtime/src/trampoline/func.rs @@ -206,7 +206,10 @@ pub fn create_handle_with_function( func: Box Result<(), Trap>>, store: &Store, ) -> Result<(StoreInstanceHandle, VMTrampoline)> { - let isa = store.engine().config().target_isa(); + // Note that we specifically enable reference types here in our ISA because + // `Func::new` is intended to be infallible, but our signature may use + // reference types which requires safepoints. + let isa = store.engine().config().target_isa_with_reference_types(); let pointer_type = isa.pointer_type(); let sig = ft.get_wasmtime_signature(pointer_type); diff --git a/tests/all/func.rs b/tests/all/func.rs index 76019e70b514..ddce6b1e68ef 100644 --- a/tests/all/func.rs +++ b/tests/all/func.rs @@ -507,3 +507,18 @@ fn pass_cross_store_arg() -> anyhow::Result<()> { Ok(()) } + +#[test] +fn externref_signature_no_reference_types() -> anyhow::Result<()> { + let store = Store::default(); + Func::wrap(&store, |_: Option| {}); + Func::new( + &store, + FuncType::new( + Box::new([ValType::FuncRef, ValType::ExternRef]), + Box::new([ValType::FuncRef, ValType::ExternRef]), + ), + |_, _, _| Ok(()), + ); + Ok(()) +}