xref: /wasmtime-44.0.1/tests/all/func.rs (revision fee9be21)
1 use anyhow::bail;
2 use std::sync::Arc;
3 use std::sync::atomic::Ordering;
4 use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst};
5 use wasmtime::*;
6 use wasmtime_test_macros::wasmtime_test;
7 
8 #[wasmtime_test]
9 #[cfg_attr(miri, ignore)]
10 fn call_wasm_to_wasm(config: &mut Config) -> Result<()> {
11     let wasm = wat::parse_str(
12         r#"
13           (module
14             (func (result i32 i32 i32)
15               i32.const 1
16               i32.const 2
17               i32.const 3
18             )
19             (func (export "run") (result i32 i32 i32)
20                 call 0
21             )
22           )
23         "#,
24     )?;
25     let engine = Engine::new(&config)?;
26     let mut store = Store::<()>::new(&engine, ());
27     let module = Module::new(store.engine(), &wasm)?;
28     let instance = Instance::new(&mut store, &module, &[])?;
29     let func = instance
30         .get_typed_func::<(), (i32, i32, i32)>(&mut store, "run")
31         .unwrap();
32     let results = func.call(&mut store, ())?;
33     assert_eq!(results, (1, 2, 3));
34     Ok(())
35 }
36 
37 #[wasmtime_test]
38 #[cfg_attr(miri, ignore)]
39 fn call_wasm_to_native(config: &mut Config) -> Result<()> {
40     let wasm = wat::parse_str(
41         r#"
42           (module
43             (import "" "" (func (result i32 i32 i32)))
44             (func (export "run") (result i32 i32 i32)
45                 call 0
46             )
47           )
48         "#,
49     )?;
50     let engine = Engine::new(&config)?;
51     let mut store = Store::<()>::new(&engine, ());
52     let module = Module::new(store.engine(), &wasm)?;
53     let import_func = Func::wrap(&mut store, || (1_i32, 2_i32, 3_i32));
54     let instance = Instance::new(&mut store, &module, &[import_func.into()])?;
55     let func = instance
56         .get_typed_func::<(), (i32, i32, i32)>(&mut store, "run")
57         .unwrap();
58     let results = func.call(&mut store, ())?;
59     assert_eq!(results, (1, 2, 3));
60     Ok(())
61 }
62 
63 #[wasmtime_test]
64 #[cfg_attr(miri, ignore)]
65 fn call_wasm_to_array(config: &mut Config) -> Result<()> {
66     let wasm = wat::parse_str(
67         r#"
68           (module
69             (import "" "" (func (result i32 i32 i32)))
70             (func (export "run") (result i32 i32 i32)
71                 call 0
72             )
73           )
74         "#,
75     )?;
76     let engine = Engine::new(&config)?;
77     let mut store = Store::<()>::new(&engine, ());
78     let module = Module::new(store.engine(), &wasm)?;
79     let func_ty = FuncType::new(
80         store.engine(),
81         vec![],
82         vec![ValType::I32, ValType::I32, ValType::I32],
83     );
84     let import_func = Func::new(&mut store, func_ty, |_, _params, results| {
85         results[0] = Val::I32(1);
86         results[1] = Val::I32(2);
87         results[2] = Val::I32(3);
88         Ok(())
89     });
90     let instance = Instance::new(&mut store, &module, &[import_func.into()])?;
91     let func = instance
92         .get_typed_func::<(), (i32, i32, i32)>(&mut store, "run")
93         .unwrap();
94     let results = func.call(&mut store, ())?;
95     assert_eq!(results, (1, 2, 3));
96     Ok(())
97 }
98 
99 #[wasmtime_test]
100 #[cfg_attr(miri, ignore)]
101 fn call_native_to_wasm(config: &mut Config) -> Result<()> {
102     let wasm = wat::parse_str(
103         r#"
104           (module
105             (func (export "run") (result i32 i32 i32)
106                 i32.const 42
107                 i32.const 420
108                 i32.const 4200
109             )
110           )
111         "#,
112     )?;
113     let engine = Engine::new(&config)?;
114     let mut store = Store::<()>::new(&engine, ());
115     let module = Module::new(store.engine(), &wasm)?;
116     let instance = Instance::new(&mut store, &module, &[])?;
117     let func = instance
118         .get_typed_func::<(), (i32, i32, i32)>(&mut store, "run")
119         .unwrap();
120     let results = func.call(&mut store, ())?;
121     assert_eq!(results, (42, 420, 4200));
122     Ok(())
123 }
124 
125 #[test]
126 fn call_native_to_native() -> Result<()> {
127     let mut store = Store::<()>::default();
128 
129     let func = Func::wrap(&mut store, |a: i32, b: i32, c: i32| -> (i32, i32, i32) {
130         (b, c, a)
131     });
132     let func = func.typed::<(i32, i32, i32), (i32, i32, i32)>(&store)?;
133     let results = func.call(&mut store, (1, 2, 3))?;
134     assert_eq!(results, (2, 3, 1));
135     Ok(())
136 }
137 
138 #[test]
139 #[cfg_attr(miri, ignore)]
140 fn call_native_to_array() -> Result<()> {
141     let mut store = Store::<()>::default();
142 
143     let func_ty = FuncType::new(
144         store.engine(),
145         [ValType::I32, ValType::I32, ValType::I32],
146         [ValType::I32, ValType::I32, ValType::I32],
147     );
148     let func = Func::new(&mut store, func_ty, |_caller, params, results| {
149         results[0] = params[2];
150         results[1] = params[0];
151         results[2] = params[1];
152         Ok(())
153     });
154     let func = func.typed::<(i32, i32, i32), (i32, i32, i32)>(&store)?;
155     let results = func.call(&mut store, (1, 2, 3))?;
156     assert_eq!(results, (3, 1, 2));
157     Ok(())
158 }
159 
160 #[wasmtime_test]
161 #[cfg_attr(miri, ignore)]
162 fn call_array_to_wasm(config: &mut Config) -> Result<()> {
163     let wasm = wat::parse_str(
164         r#"
165           (module
166             (func (export "run") (param i32 i32 i32) (result i32 i32 i32)
167               local.get 1
168               local.get 2
169               local.get 0
170             )
171           )
172         "#,
173     )?;
174     let engine = Engine::new(&config)?;
175     let mut store = Store::<()>::new(&engine, ());
176     let module = Module::new(store.engine(), &wasm)?;
177     let instance = Instance::new(&mut store, &module, &[])?;
178     let func = instance.get_func(&mut store, "run").unwrap();
179     let mut results = [Val::I32(0), Val::I32(0), Val::I32(0)];
180     func.call(
181         &mut store,
182         &[Val::I32(10), Val::I32(20), Val::I32(30)],
183         &mut results,
184     )?;
185     assert_eq!(results[0].i32(), Some(20));
186     assert_eq!(results[1].i32(), Some(30));
187     assert_eq!(results[2].i32(), Some(10));
188     Ok(())
189 }
190 
191 #[test]
192 fn call_array_to_native() -> Result<()> {
193     let mut store = Store::<()>::default();
194     let func = Func::wrap(&mut store, |a: i32, b: i32, c: i32| -> (i32, i32, i32) {
195         (a * 10, b * 10, c * 10)
196     });
197     let mut results = [Val::I32(0), Val::I32(0), Val::I32(0)];
198     func.call(
199         &mut store,
200         &[Val::I32(10), Val::I32(20), Val::I32(30)],
201         &mut results,
202     )?;
203     assert_eq!(results[0].i32(), Some(100));
204     assert_eq!(results[1].i32(), Some(200));
205     assert_eq!(results[2].i32(), Some(300));
206     Ok(())
207 }
208 
209 #[test]
210 #[cfg_attr(miri, ignore)]
211 fn call_array_to_array() -> Result<()> {
212     let mut store = Store::<()>::default();
213     let func_ty = FuncType::new(
214         store.engine(),
215         [ValType::I32, ValType::I32, ValType::I32],
216         [ValType::I32, ValType::I32, ValType::I32],
217     );
218     let func = Func::new(&mut store, func_ty, |_caller, params, results| {
219         results[0] = params[2];
220         results[1] = params[0];
221         results[2] = params[1];
222         Ok(())
223     });
224     let mut results = [Val::I32(0), Val::I32(0), Val::I32(0)];
225     func.call(
226         &mut store,
227         &[Val::I32(10), Val::I32(20), Val::I32(30)],
228         &mut results,
229     )?;
230     assert_eq!(results[0].i32(), Some(30));
231     assert_eq!(results[1].i32(), Some(10));
232     assert_eq!(results[2].i32(), Some(20));
233     Ok(())
234 }
235 
236 #[wasmtime_test(wasm_features(reference_types))]
237 #[cfg_attr(miri, ignore)]
238 fn call_indirect_native_from_wasm_import_global(config: &mut Config) -> Result<()> {
239     let wasm = wat::parse_str(
240         r#"
241           (module
242             (import "" "" (global funcref))
243             (table 1 1 funcref)
244             (func (export "run") (result i32 i32 i32)
245                 i32.const 0
246                 global.get 0
247                 table.set
248                 i32.const 0
249                 call_indirect (result i32 i32 i32)
250             )
251           )
252         "#,
253     )?;
254     let engine = Engine::new(&config)?;
255     let mut store = Store::<()>::new(&engine, ());
256     let module = Module::new(store.engine(), &wasm)?;
257     let func = Func::wrap(&mut store, || -> (i32, i32, i32) { (10, 20, 30) });
258     let global = Global::new(
259         &mut store,
260         GlobalType::new(ValType::FUNCREF, Mutability::Const),
261         Val::FuncRef(Some(func)),
262     )?;
263     let instance = Instance::new(&mut store, &module, &[global.into()])?;
264     let func = instance.get_typed_func::<(), (i32, i32, i32)>(&mut store, "run")?;
265     let results = func.call(&mut store, ())?;
266     assert_eq!(results, (10, 20, 30));
267     Ok(())
268 }
269 
270 #[wasmtime_test]
271 #[cfg_attr(miri, ignore)]
272 fn call_indirect_native_from_wasm_import_table(config: &mut Config) -> Result<()> {
273     let wasm = wat::parse_str(
274         r#"
275           (module
276             (import "" "" (table 1 1 funcref))
277             (func (export "run") (result i32 i32 i32)
278                 i32.const 0
279                 call_indirect (result i32 i32 i32)
280             )
281           )
282         "#,
283     )?;
284     let engine = Engine::new(&config)?;
285     let mut store = Store::<()>::new(&engine, ());
286     let module = Module::new(store.engine(), &wasm)?;
287     let func = Func::wrap(&mut store, || -> (i32, i32, i32) { (10, 20, 30) });
288     let table = Table::new(
289         &mut store,
290         TableType::new(RefType::FUNCREF, 1, Some(1)),
291         Ref::Func(Some(func)),
292     )?;
293     let instance = Instance::new(&mut store, &module, &[table.into()])?;
294     let func = instance.get_typed_func::<(), (i32, i32, i32)>(&mut store, "run")?;
295     let results = func.call(&mut store, ())?;
296     assert_eq!(results, (10, 20, 30));
297     Ok(())
298 }
299 
300 #[wasmtime_test(wasm_features(reference_types))]
301 #[cfg_attr(miri, ignore)]
302 fn call_indirect_native_from_wasm_import_func_returns_funcref(config: &mut Config) -> Result<()> {
303     let wasm = wat::parse_str(
304         r#"
305           (module
306             (import "" "" (func (result funcref)))
307             (table 1 1 funcref)
308             (func (export "run") (result i32 i32 i32)
309                 i32.const 0
310                 call 0
311                 table.set
312                 i32.const 0
313                 call_indirect (result i32 i32 i32)
314             )
315           )
316         "#,
317     )?;
318     let engine = Engine::new(&config)?;
319     let mut store = Store::<()>::new(&engine, ());
320     let module = Module::new(store.engine(), &wasm)?;
321     let func = Func::wrap(&mut store, || -> (i32, i32, i32) { (10, 20, 30) });
322     let get_func = Func::wrap(&mut store, move || -> Option<Func> { Some(func) });
323     let instance = Instance::new(&mut store, &module, &[get_func.into()])?;
324     let func = instance.get_typed_func::<(), (i32, i32, i32)>(&mut store, "run")?;
325     let results = func.call(&mut store, ())?;
326     assert_eq!(results, (10, 20, 30));
327     Ok(())
328 }
329 
330 #[wasmtime_test]
331 #[cfg_attr(miri, ignore)]
332 fn call_indirect_native_from_exported_table(config: &mut Config) -> Result<()> {
333     let wasm = wat::parse_str(
334         r#"
335           (module
336             (table (export "table") 1 1 funcref)
337             (func (export "run") (result i32 i32 i32)
338                 i32.const 0
339                 call_indirect (result i32 i32 i32)
340             )
341           )
342         "#,
343     )?;
344     let engine = Engine::new(&config)?;
345     let mut store = Store::<()>::new(&engine, ());
346     let module = Module::new(store.engine(), &wasm)?;
347     let func = Func::wrap(&mut store, || -> (i32, i32, i32) { (10, 20, 30) });
348     let instance = Instance::new(&mut store, &module, &[])?;
349     let table = instance.get_table(&mut store, "table").unwrap();
350     table.set(&mut store, 0, func.into())?;
351     let run = instance.get_typed_func::<(), (i32, i32, i32)>(&mut store, "run")?;
352     let results = run.call(&mut store, ())?;
353     assert_eq!(results, (10, 20, 30));
354     Ok(())
355 }
356 
357 // wasm exports global, host puts native-call funcref in global, wasm calls funcref
358 #[wasmtime_test(wasm_features(reference_types))]
359 #[cfg_attr(miri, ignore)]
360 fn call_indirect_native_from_exported_global(config: &mut Config) -> Result<()> {
361     let wasm = wat::parse_str(
362         r#"
363           (module
364             (global (export "global") (mut funcref) (ref.null func))
365             (table 1 1 funcref)
366             (func (export "run") (result i32 i32 i32)
367                 i32.const 0
368                 global.get 0
369                 table.set
370                 i32.const 0
371                 call_indirect (result i32 i32 i32)
372             )
373           )
374         "#,
375     )?;
376     let engine = Engine::new(&config)?;
377     let mut store = Store::<()>::new(&engine, ());
378     let module = Module::new(store.engine(), &wasm)?;
379     let func = Func::wrap(&mut store, || -> (i32, i32, i32) { (10, 20, 30) });
380     let instance = Instance::new(&mut store, &module, &[])?;
381     let global = instance.get_global(&mut store, "global").unwrap();
382     global.set(&mut store, func.into())?;
383     let run = instance.get_typed_func::<(), (i32, i32, i32)>(&mut store, "run")?;
384     let results = run.call(&mut store, ())?;
385     assert_eq!(results, (10, 20, 30));
386     Ok(())
387 }
388 
389 #[test]
390 fn func_constructors() {
391     let mut store = Store::<()>::default();
392     Func::wrap(&mut store, || {});
393     Func::wrap(&mut store, |_: i32| {});
394     Func::wrap(&mut store, |_: i32, _: i64| {});
395     Func::wrap(&mut store, |_: f32, _: f64| {});
396     Func::wrap(&mut store, || -> i32 { 0 });
397     Func::wrap(&mut store, || -> i64 { 0 });
398     Func::wrap(&mut store, || -> f32 { 0.0 });
399     Func::wrap(&mut store, || -> f64 { 0.0 });
400     Func::wrap(&mut store, || -> Rooted<ExternRef> {
401         loop {}
402     });
403     Func::wrap(&mut store, || -> Option<Rooted<ExternRef>> { None });
404     Func::wrap(&mut store, || -> OwnedRooted<ExternRef> {
405         loop {}
406     });
407     Func::wrap(&mut store, || -> Option<OwnedRooted<ExternRef>> { None });
408     Func::wrap(&mut store, || -> Rooted<AnyRef> {
409         loop {}
410     });
411     Func::wrap(&mut store, || -> Option<Rooted<AnyRef>> { None });
412     Func::wrap(&mut store, || -> OwnedRooted<AnyRef> {
413         loop {}
414     });
415     Func::wrap(&mut store, || -> Option<OwnedRooted<AnyRef>> { None });
416     Func::wrap(&mut store, || -> I31 {
417         loop {}
418     });
419     Func::wrap(&mut store, || -> Option<I31> { None });
420     Func::wrap(&mut store, || -> Func {
421         loop {}
422     });
423     Func::wrap(&mut store, || -> Option<Func> { None });
424     Func::wrap(&mut store, || -> NoFunc {
425         loop {}
426     });
427     Func::wrap(&mut store, || -> Option<NoFunc> { None });
428     Func::wrap(&mut store, || -> NoExtern {
429         loop {}
430     });
431     Func::wrap(&mut store, || -> Option<NoExtern> { None });
432     Func::wrap(&mut store, || -> NoneRef {
433         loop {}
434     });
435     Func::wrap(&mut store, || -> Option<NoneRef> { None });
436 
437     Func::wrap(&mut store, || -> Result<()> {
438         loop {}
439     });
440     Func::wrap(&mut store, || -> Result<i32> {
441         loop {}
442     });
443     Func::wrap(&mut store, || -> Result<i64> {
444         loop {}
445     });
446     Func::wrap(&mut store, || -> Result<f32> {
447         loop {}
448     });
449     Func::wrap(&mut store, || -> Result<f64> {
450         loop {}
451     });
452     Func::wrap(&mut store, || -> Result<Rooted<ExternRef>> {
453         loop {}
454     });
455     Func::wrap(&mut store, || -> Result<Option<Rooted<ExternRef>>> {
456         loop {}
457     });
458     Func::wrap(&mut store, || -> Result<OwnedRooted<ExternRef>> {
459         loop {}
460     });
461     Func::wrap(&mut store, || -> Result<Option<OwnedRooted<ExternRef>>> {
462         loop {}
463     });
464     Func::wrap(&mut store, || -> Result<Rooted<AnyRef>> {
465         loop {}
466     });
467     Func::wrap(&mut store, || -> Result<Option<Rooted<AnyRef>>> {
468         loop {}
469     });
470     Func::wrap(&mut store, || -> Result<OwnedRooted<AnyRef>> {
471         loop {}
472     });
473     Func::wrap(&mut store, || -> Result<Option<OwnedRooted<AnyRef>>> {
474         loop {}
475     });
476     Func::wrap(&mut store, || -> Result<I31> {
477         loop {}
478     });
479     Func::wrap(&mut store, || -> Result<Option<I31>> {
480         loop {}
481     });
482     Func::wrap(&mut store, || -> Result<Func> {
483         loop {}
484     });
485     Func::wrap(&mut store, || -> Result<Option<Func>> {
486         loop {}
487     });
488     Func::wrap(&mut store, || -> Result<NoFunc> {
489         loop {}
490     });
491     Func::wrap(&mut store, || -> Result<Option<NoFunc>> {
492         loop {}
493     });
494     Func::wrap(&mut store, || -> Result<NoExtern> {
495         loop {}
496     });
497     Func::wrap(&mut store, || -> Result<Option<NoExtern>> {
498         loop {}
499     });
500     Func::wrap(&mut store, || -> Result<NoneRef> {
501         loop {}
502     });
503     Func::wrap(&mut store, || -> Result<Option<NoneRef>> {
504         loop {}
505     });
506 }
507 
508 #[test]
509 fn dtor_runs() {
510     static HITS: AtomicUsize = AtomicUsize::new(0);
511 
512     struct A;
513 
514     impl Drop for A {
515         fn drop(&mut self) {
516             HITS.fetch_add(1, SeqCst);
517         }
518     }
519 
520     let mut store = Store::<()>::default();
521     let a = A;
522     assert_eq!(HITS.load(SeqCst), 0);
523     Func::wrap(&mut store, move || {
524         let _ = &a;
525     });
526     drop(store);
527     assert_eq!(HITS.load(SeqCst), 1);
528 }
529 
530 #[test]
531 #[cfg_attr(miri, ignore)]
532 fn dtor_delayed() -> Result<()> {
533     static HITS: AtomicUsize = AtomicUsize::new(0);
534 
535     struct A;
536 
537     impl Drop for A {
538         fn drop(&mut self) {
539             HITS.fetch_add(1, SeqCst);
540         }
541     }
542 
543     let mut store = Store::<()>::default();
544     let a = A;
545     let func = Func::wrap(&mut store, move || {
546         let _ = &a;
547     });
548 
549     assert_eq!(HITS.load(SeqCst), 0);
550     let wasm = wat::parse_str(r#"(import "" "" (func))"#)?;
551     let module = Module::new(store.engine(), &wasm)?;
552     let _instance = Instance::new(&mut store, &module, &[func.into()])?;
553     assert_eq!(HITS.load(SeqCst), 0);
554     drop(store);
555     assert_eq!(HITS.load(SeqCst), 1);
556     Ok(())
557 }
558 
559 #[test]
560 fn signatures_match() {
561     let mut store = Store::<()>::default();
562 
563     let f = Func::wrap(&mut store, || {});
564     assert_eq!(f.ty(&store).params().len(), 0);
565     assert_eq!(f.ty(&store).results().len(), 0);
566 
567     let f = Func::wrap(&mut store, || -> i32 {
568         loop {}
569     });
570     assert_eq!(f.ty(&store).params().len(), 0);
571     assert_eq!(f.ty(&store).results().len(), 1);
572     assert!(f.ty(&store).results().nth(0).unwrap().is_i32());
573 
574     let f = Func::wrap(&mut store, || -> i64 {
575         loop {}
576     });
577     assert_eq!(f.ty(&store).params().len(), 0);
578     assert_eq!(f.ty(&store).results().len(), 1);
579     assert!(f.ty(&store).results().nth(0).unwrap().is_i64());
580 
581     let f = Func::wrap(&mut store, || -> f32 {
582         loop {}
583     });
584     assert_eq!(f.ty(&store).params().len(), 0);
585     assert_eq!(f.ty(&store).results().len(), 1);
586     assert!(f.ty(&store).results().nth(0).unwrap().is_f32());
587 
588     let f = Func::wrap(&mut store, || -> f64 {
589         loop {}
590     });
591     assert_eq!(f.ty(&store).params().len(), 0);
592     assert_eq!(f.ty(&store).results().len(), 1);
593     assert!(f.ty(&store).results().nth(0).unwrap().is_f64());
594 
595     let f = Func::wrap(
596         &mut store,
597         |_: f32,
598          _: f64,
599          _: i32,
600          _: i64,
601          _: i32,
602          _: Option<Rooted<ExternRef>>,
603          _: Option<OwnedRooted<ExternRef>>,
604          _: Option<Rooted<AnyRef>>,
605          _: Option<OwnedRooted<AnyRef>>,
606          _: Option<Func>|
607          -> f64 { loop {} },
608     );
609 
610     assert_eq!(f.ty(&store).params().len(), 10);
611     assert!(f.ty(&store).params().nth(0).unwrap().is_f32());
612     assert!(f.ty(&store).params().nth(1).unwrap().is_f64());
613     assert!(f.ty(&store).params().nth(2).unwrap().is_i32());
614     assert!(f.ty(&store).params().nth(3).unwrap().is_i64());
615     assert!(f.ty(&store).params().nth(4).unwrap().is_i32());
616     assert!(f.ty(&store).params().nth(5).unwrap().is_externref());
617     assert!(f.ty(&store).params().nth(6).unwrap().is_externref());
618     assert!(f.ty(&store).params().nth(7).unwrap().is_anyref());
619     assert!(f.ty(&store).params().nth(8).unwrap().is_anyref());
620     assert!(f.ty(&store).params().nth(9).unwrap().is_funcref());
621 
622     assert_eq!(f.ty(&store).results().len(), 1);
623     assert!(f.ty(&store).results().nth(0).unwrap().is_f64());
624 }
625 
626 #[test]
627 #[cfg_attr(miri, ignore)]
628 fn import_works() -> Result<()> {
629     let _ = env_logger::try_init();
630 
631     static HITS: AtomicUsize = AtomicUsize::new(0);
632 
633     let wasm = wat::parse_str(
634         r#"
635             (import "" "" (func))
636             (import "" "" (func (param i32) (result i32)))
637             (import "" "" (func (param i32) (param i64)))
638             (import "" "" (func (param i32 i64 i32 f32 f64 externref externref funcref anyref anyref i31ref)))
639 
640             (func (export "run") (param externref externref funcref)
641                 call 0
642                 i32.const 0
643                 call 1
644                 i32.const 1
645                 i32.add
646                 i64.const 3
647                 call 2
648 
649                 i32.const 100
650                 i64.const 200
651                 i32.const 300
652                 f32.const 400
653                 f64.const 500
654                 local.get 0
655                 local.get 1
656                 local.get 2
657                 (ref.i31 (i32.const 36))
658                 (ref.i31 (i32.const 42))
659                 (ref.i31 (i32.const 0x1234))
660                 call 3
661             )
662         "#,
663     )?;
664 
665     let mut config = Config::new();
666     config.wasm_reference_types(true);
667     config.wasm_function_references(true);
668     config.wasm_gc(true);
669 
670     let engine = Engine::new(&config)?;
671     let mut store = Store::new(&engine, ());
672     let module = Module::new(&engine, &wasm)?;
673 
674     let imports = [
675         Func::wrap(&mut store, || {
676             assert_eq!(HITS.fetch_add(1, SeqCst), 0);
677         })
678         .into(),
679         Func::wrap(&mut store, |x: i32| -> i32 {
680             assert_eq!(x, 0);
681             assert_eq!(HITS.fetch_add(1, SeqCst), 1);
682             1
683         })
684         .into(),
685         Func::wrap(&mut store, |x: i32, y: i64| {
686             assert_eq!(x, 2);
687             assert_eq!(y, 3);
688             assert_eq!(HITS.fetch_add(1, SeqCst), 2);
689         })
690         .into(),
691         Func::wrap(
692             &mut store,
693             |mut caller: Caller<'_, ()>,
694              a: i32,
695              b: i64,
696              c: i32,
697              d: f32,
698              e: f64,
699              f: Option<Rooted<ExternRef>>,
700              g: Option<OwnedRooted<ExternRef>>,
701              h: Option<Func>,
702              i: Option<Rooted<AnyRef>>,
703              j: Option<OwnedRooted<AnyRef>>,
704              k: Option<I31>|
705              -> Result<()> {
706                 assert_eq!(a, 100);
707                 assert_eq!(b, 200);
708                 assert_eq!(c, 300);
709                 assert_eq!(d, 400.0);
710                 assert_eq!(e, 500.0);
711                 assert_eq!(
712                     f.as_ref()
713                         .unwrap()
714                         .data(&caller)?
715                         .unwrap()
716                         .downcast_ref::<String>()
717                         .unwrap(),
718                     "hello"
719                 );
720                 assert_eq!(
721                     g.as_ref()
722                         .unwrap()
723                         .data(&caller)?
724                         .unwrap()
725                         .downcast_ref::<String>()
726                         .unwrap(),
727                     "goodbye"
728                 );
729                 assert_eq!(
730                     i.unwrap().as_i31(&caller).unwrap().unwrap(),
731                     I31::wrapping_u32(36)
732                 );
733                 assert_eq!(
734                     j.unwrap().as_i31(&caller).unwrap().unwrap(),
735                     I31::wrapping_u32(42)
736                 );
737                 assert_eq!(k, Some(I31::wrapping_u32(0x1234)));
738                 let mut results = [Val::I32(0)];
739                 h.as_ref()
740                     .unwrap()
741                     .call(&mut caller, &[], &mut results)
742                     .unwrap();
743                 assert_eq!(results[0].unwrap_i32(), 42);
744                 assert_eq!(HITS.fetch_add(1, SeqCst), 3);
745                 Ok(())
746             },
747         )
748         .into(),
749     ];
750 
751     let instance = Instance::new(&mut store, &module, &imports)?;
752     let run = instance.get_func(&mut store, "run").unwrap();
753     let hello = Val::ExternRef(Some(ExternRef::new(&mut store, "hello".to_string())?));
754     let goodbye = Val::ExternRef(Some(ExternRef::new(&mut store, "goodbye".to_string())?));
755     let funcref = Val::FuncRef(Some(Func::wrap(&mut store, || -> i32 { 42 })));
756     run.call(&mut store, &[hello, goodbye, funcref], &mut [])?;
757 
758     assert_eq!(HITS.load(SeqCst), 4);
759     Ok(())
760 }
761 
762 #[test]
763 #[cfg_attr(miri, ignore)]
764 fn trap_smoke() -> Result<()> {
765     let mut store = Store::<()>::default();
766     let f = Func::wrap(&mut store, || -> Result<()> { bail!("test") });
767     let err = f.call(&mut store, &[], &mut []).unwrap_err();
768     assert!(err.to_string().contains("test"));
769     Ok(())
770 }
771 
772 #[wasmtime_test]
773 #[cfg_attr(miri, ignore)]
774 fn trap_import(config: &mut Config) -> Result<()> {
775     let wasm = wat::parse_str(
776         r#"
777             (import "" "" (func))
778             (start 0)
779         "#,
780     )?;
781     let engine = Engine::new(&config)?;
782     let mut store = Store::<()>::new(&engine, ());
783     let module = Module::new(store.engine(), &wasm)?;
784     let import = Func::wrap(&mut store, || -> Result<()> { bail!("foo") });
785     let trap = Instance::new(&mut store, &module, &[import.into()]).unwrap_err();
786     assert!(trap.to_string().contains("foo"));
787     Ok(())
788 }
789 
790 #[test]
791 fn get_from_wrapper() {
792     let mut store = Store::<()>::default();
793     let f = Func::wrap(&mut store, || {});
794     assert!(f.typed::<(), ()>(&store).is_ok());
795     assert!(f.typed::<(), i32>(&store).is_err());
796     assert!(f.typed::<(), ()>(&store).is_ok());
797     assert!(f.typed::<i32, ()>(&store).is_err());
798     assert!(f.typed::<i32, i32>(&store).is_err());
799     assert!(f.typed::<(i32, i32), ()>(&store).is_err());
800     assert!(f.typed::<(i32, i32), i32>(&store).is_err());
801 
802     let f = Func::wrap(&mut store, || -> i32 {
803         loop {}
804     });
805     assert!(f.typed::<(), i32>(&store).is_ok());
806     let f = Func::wrap(&mut store, || -> f32 {
807         loop {}
808     });
809     assert!(f.typed::<(), f32>(&store).is_ok());
810     let f = Func::wrap(&mut store, || -> f64 {
811         loop {}
812     });
813     assert!(f.typed::<(), f64>(&store).is_ok());
814     let f = Func::wrap(&mut store, || -> Rooted<ExternRef> {
815         loop {}
816     });
817     assert!(f.typed::<(), Rooted<ExternRef>>(&store).is_ok());
818     let f = Func::wrap(&mut store, || -> Option<Rooted<ExternRef>> {
819         loop {}
820     });
821     assert!(f.typed::<(), Option<Rooted<ExternRef>>>(&store).is_ok());
822     let f = Func::wrap(&mut store, || -> OwnedRooted<ExternRef> {
823         loop {}
824     });
825     assert!(f.typed::<(), OwnedRooted<ExternRef>>(&store).is_ok());
826     let f = Func::wrap(&mut store, || -> Option<OwnedRooted<ExternRef>> {
827         loop {}
828     });
829     assert!(
830         f.typed::<(), Option<OwnedRooted<ExternRef>>>(&store)
831             .is_ok()
832     );
833     let f = Func::wrap(&mut store, || -> Rooted<AnyRef> {
834         loop {}
835     });
836     assert!(f.typed::<(), Rooted<AnyRef>>(&store).is_ok());
837     let f = Func::wrap(&mut store, || -> Option<Rooted<AnyRef>> {
838         loop {}
839     });
840     assert!(f.typed::<(), Option<Rooted<AnyRef>>>(&store).is_ok());
841     let f = Func::wrap(&mut store, || -> OwnedRooted<AnyRef> {
842         loop {}
843     });
844     assert!(f.typed::<(), OwnedRooted<AnyRef>>(&store).is_ok());
845     let f = Func::wrap(&mut store, || -> Option<OwnedRooted<AnyRef>> {
846         loop {}
847     });
848     assert!(f.typed::<(), Option<OwnedRooted<AnyRef>>>(&store).is_ok());
849     let f = Func::wrap(&mut store, || -> I31 {
850         loop {}
851     });
852     assert!(f.typed::<(), I31>(&store).is_ok());
853     let f = Func::wrap(&mut store, || -> Option<I31> {
854         loop {}
855     });
856     assert!(f.typed::<(), Option<I31>>(&store).is_ok());
857     let f = Func::wrap(&mut store, || -> Func {
858         loop {}
859     });
860     assert!(f.typed::<(), Func>(&store).is_ok());
861     let f = Func::wrap(&mut store, || -> Option<Func> {
862         loop {}
863     });
864     assert!(f.typed::<(), Option<Func>>(&store).is_ok());
865 
866     let f = Func::wrap(&mut store, |_: i32| {});
867     assert!(f.typed::<i32, ()>(&store).is_ok());
868     assert!(f.typed::<i64, ()>(&store).is_err());
869     assert!(f.typed::<f32, ()>(&store).is_err());
870     assert!(f.typed::<f64, ()>(&store).is_err());
871     let f = Func::wrap(&mut store, |_: i64| {});
872     assert!(f.typed::<i64, ()>(&store).is_ok());
873     let f = Func::wrap(&mut store, |_: f32| {});
874     assert!(f.typed::<f32, ()>(&store).is_ok());
875     let f = Func::wrap(&mut store, |_: f64| {});
876     assert!(f.typed::<f64, ()>(&store).is_ok());
877     let f = Func::wrap(&mut store, |_: Rooted<ExternRef>| {});
878     assert!(f.typed::<Rooted<ExternRef>, ()>(&store).is_ok());
879     let f = Func::wrap(&mut store, |_: Option<Rooted<ExternRef>>| {});
880     assert!(f.typed::<Option<Rooted<ExternRef>>, ()>(&store).is_ok());
881     let f = Func::wrap(&mut store, |_: OwnedRooted<ExternRef>| {});
882     assert!(f.typed::<OwnedRooted<ExternRef>, ()>(&store).is_ok());
883     let f = Func::wrap(&mut store, |_: Option<OwnedRooted<ExternRef>>| {});
884     assert!(
885         f.typed::<Option<OwnedRooted<ExternRef>>, ()>(&store)
886             .is_ok()
887     );
888     let f = Func::wrap(&mut store, |_: Rooted<AnyRef>| {});
889     assert!(f.typed::<Rooted<AnyRef>, ()>(&store).is_ok());
890     let f = Func::wrap(&mut store, |_: Option<Rooted<AnyRef>>| {});
891     assert!(f.typed::<Option<Rooted<AnyRef>>, ()>(&store).is_ok());
892     let f = Func::wrap(&mut store, |_: OwnedRooted<AnyRef>| {});
893     assert!(f.typed::<OwnedRooted<AnyRef>, ()>(&store).is_ok());
894     let f = Func::wrap(&mut store, |_: Option<OwnedRooted<AnyRef>>| {});
895     assert!(f.typed::<Option<OwnedRooted<AnyRef>>, ()>(&store).is_ok());
896     let f = Func::wrap(&mut store, |_: I31| {});
897     assert!(f.typed::<I31, ()>(&store).is_ok());
898     let f = Func::wrap(&mut store, |_: Option<I31>| {});
899     assert!(f.typed::<Option<I31>, ()>(&store).is_ok());
900     let f = Func::wrap(&mut store, |_: Func| {});
901     assert!(f.typed::<Func, ()>(&store).is_ok());
902     let f = Func::wrap(&mut store, |_: Option<Func>| {});
903     assert!(f.typed::<Option<Func>, ()>(&store).is_ok());
904 }
905 
906 #[test]
907 #[cfg_attr(miri, ignore)]
908 fn get_from_signature() {
909     let mut store = Store::<()>::default();
910     let ty = FuncType::new(store.engine(), None, None);
911     let f = Func::new(&mut store, ty, |_, _, _| panic!());
912     assert!(f.typed::<(), ()>(&store).is_ok());
913     assert!(f.typed::<(), i32>(&store).is_err());
914     assert!(f.typed::<i32, ()>(&store).is_err());
915 
916     let ty = FuncType::new(store.engine(), Some(ValType::I32), Some(ValType::F64));
917     let f = Func::new(&mut store, ty, |_, _, _| panic!());
918     assert!(f.typed::<(), ()>(&store).is_err());
919     assert!(f.typed::<(), i32>(&store).is_err());
920     assert!(f.typed::<i32, ()>(&store).is_err());
921     assert!(f.typed::<i32, f64>(&store).is_ok());
922 }
923 
924 #[wasmtime_test]
925 #[cfg_attr(miri, ignore)]
926 fn get_from_module(config: &mut Config) -> anyhow::Result<()> {
927     let engine = Engine::new(&config)?;
928     let mut store = Store::<()>::new(&engine, ());
929     let module = Module::new(
930         store.engine(),
931         r#"
932             (module
933                 (func (export "f0"))
934                 (func (export "f1") (param i32))
935                 (func (export "f2") (result i32)
936                     i32.const 0)
937             )
938 
939         "#,
940     )?;
941     let instance = Instance::new(&mut store, &module, &[])?;
942     let f0 = instance.get_func(&mut store, "f0").unwrap();
943     assert!(f0.typed::<(), ()>(&store).is_ok());
944     assert!(f0.typed::<(), i32>(&store).is_err());
945     let f1 = instance.get_func(&mut store, "f1").unwrap();
946     assert!(f1.typed::<(), ()>(&store).is_err());
947     assert!(f1.typed::<i32, ()>(&store).is_ok());
948     assert!(f1.typed::<i32, f32>(&store).is_err());
949     let f2 = instance.get_func(&mut store, "f2").unwrap();
950     assert!(f2.typed::<(), ()>(&store).is_err());
951     assert!(f2.typed::<(), i32>(&store).is_ok());
952     assert!(f2.typed::<i32, ()>(&store).is_err());
953     assert!(f2.typed::<i32, f32>(&store).is_err());
954     Ok(())
955 }
956 
957 #[test]
958 fn call_wrapped_func() -> Result<()> {
959     let mut store = Store::<()>::default();
960     let f = Func::wrap(&mut store, |a: i32, b: i64, c: f32, d: f64| {
961         assert_eq!(a, 1);
962         assert_eq!(b, 2);
963         assert_eq!(c, 3.0);
964         assert_eq!(d, 4.0);
965     });
966     f.call(
967         &mut store,
968         &[Val::I32(1), Val::I64(2), 3.0f32.into(), 4.0f64.into()],
969         &mut [],
970     )?;
971     f.typed::<(i32, i64, f32, f64), ()>(&store)?
972         .call(&mut store, (1, 2, 3.0, 4.0))?;
973 
974     let mut results = [Val::I32(0)];
975     let f = Func::wrap(&mut store, || 1i32);
976     f.call(&mut store, &[], &mut results)?;
977     assert_eq!(results[0].unwrap_i32(), 1);
978     assert_eq!(f.typed::<(), i32>(&store)?.call(&mut store, ())?, 1);
979 
980     let f = Func::wrap(&mut store, || 2i64);
981     f.call(&mut store, &[], &mut results)?;
982     assert_eq!(results[0].unwrap_i64(), 2);
983     assert_eq!(f.typed::<(), i64>(&store)?.call(&mut store, ())?, 2);
984 
985     let f = Func::wrap(&mut store, || 3.0f32);
986     f.call(&mut store, &[], &mut results)?;
987     assert_eq!(results[0].unwrap_f32(), 3.0);
988     assert_eq!(f.typed::<(), f32>(&store)?.call(&mut store, ())?, 3.0);
989 
990     let f = Func::wrap(&mut store, || 4.0f64);
991     f.call(&mut store, &[], &mut results)?;
992     assert_eq!(results[0].unwrap_f64(), 4.0);
993     assert_eq!(f.typed::<(), f64>(&store)?.call(&mut store, ())?, 4.0);
994     Ok(())
995 }
996 
997 #[wasmtime_test]
998 #[cfg_attr(miri, ignore)]
999 fn caller_memory(config: &mut Config) -> anyhow::Result<()> {
1000     let engine = Engine::new(config)?;
1001     let mut store = Store::<()>::new(&engine, ());
1002     let f = Func::wrap(&mut store, |mut c: Caller<'_, ()>| {
1003         assert!(c.get_export("x").is_none());
1004         assert!(c.get_export("y").is_none());
1005         assert!(c.get_export("z").is_none());
1006     });
1007     f.call(&mut store, &[], &mut [])?;
1008 
1009     let f = Func::wrap(&mut store, |mut c: Caller<'_, ()>| {
1010         assert!(c.get_export("x").is_none());
1011     });
1012     let module = Module::new(
1013         store.engine(),
1014         r#"
1015             (module
1016                 (import "" "" (func $f))
1017                 (start $f)
1018             )
1019 
1020         "#,
1021     )?;
1022     Instance::new(&mut store, &module, &[f.into()])?;
1023 
1024     let f = Func::wrap(&mut store, |mut c: Caller<'_, ()>| {
1025         assert!(c.get_export("memory").is_some());
1026     });
1027     let module = Module::new(
1028         store.engine(),
1029         r#"
1030             (module
1031                 (import "" "" (func $f))
1032                 (memory (export "memory") 1)
1033                 (start $f)
1034             )
1035 
1036         "#,
1037     )?;
1038     Instance::new(&mut store, &module, &[f.into()])?;
1039 
1040     let f = Func::wrap(&mut store, |mut c: Caller<'_, ()>| {
1041         assert!(c.get_export("m").is_some());
1042         assert!(c.get_export("f").is_some());
1043         assert!(c.get_export("g").is_some());
1044         assert!(c.get_export("t").is_some());
1045     });
1046     let module = Module::new(
1047         store.engine(),
1048         r#"
1049             (module
1050                 (import "" "" (func $f))
1051                 (memory (export "m") 1)
1052                 (func (export "f"))
1053                 (global (export "g") i32 (i32.const 0))
1054                 (table (export "t") 1 funcref)
1055                 (start $f)
1056             )
1057 
1058         "#,
1059     )?;
1060     Instance::new(&mut store, &module, &[f.into()])?;
1061     Ok(())
1062 }
1063 
1064 #[test]
1065 #[cfg_attr(miri, ignore)]
1066 fn func_write_nothing() -> anyhow::Result<()> {
1067     let mut store = Store::<()>::default();
1068     let ty = FuncType::new(store.engine(), None, Some(ValType::I32));
1069     let f = Func::new(&mut store, ty, |_, _, _| Ok(()));
1070     let err = f.call(&mut store, &[], &mut [Val::I32(0)]).unwrap_err();
1071     assert!(
1072         err.to_string()
1073             .contains("function attempted to return an incompatible value")
1074     );
1075     Ok(())
1076 }
1077 
1078 #[wasmtime_test(wasm_features(reference_types))]
1079 #[cfg_attr(miri, ignore)]
1080 fn return_cross_store_value(config: &mut Config) -> anyhow::Result<()> {
1081     let _ = env_logger::try_init();
1082 
1083     let wasm = wat::parse_str(
1084         r#"
1085             (import "" "" (func (result funcref)))
1086 
1087             (func (export "run") (result funcref)
1088                 call 0
1089             )
1090         "#,
1091     )?;
1092     let engine = Engine::new(&config)?;
1093     let module = Module::new(&engine, &wasm)?;
1094 
1095     let mut store1 = Store::new(&engine, ());
1096     let mut store2 = Store::new(&engine, ());
1097 
1098     let store2_func = Func::wrap(&mut store2, || {});
1099     let return_cross_store_func = Func::wrap(&mut store1, move || Some(store2_func));
1100 
1101     let instance = Instance::new(&mut store1, &module, &[return_cross_store_func.into()])?;
1102 
1103     let run = instance.get_func(&mut store1, "run").unwrap();
1104     let result = run.call(&mut store1, &[], &mut [Val::I32(0)]);
1105     assert!(result.is_err());
1106     assert!(format!("{:?}", result.unwrap_err()).contains("cross-`Store`"));
1107 
1108     Ok(())
1109 }
1110 
1111 #[wasmtime_test(wasm_features(reference_types))]
1112 fn pass_cross_store_arg(config: &mut Config) -> anyhow::Result<()> {
1113     let engine = Engine::new(&config)?;
1114 
1115     let mut store1 = Store::new(&engine, ());
1116     let mut store2 = Store::new(&engine, ());
1117 
1118     let store1_func = Func::wrap(&mut store1, |_: Option<Func>| {});
1119     let store2_func = Func::wrap(&mut store2, || {});
1120 
1121     // Using regular `.call` fails with cross-Store arguments.
1122     assert!(
1123         store1_func
1124             .call(&mut store1, &[Val::FuncRef(Some(store2_func))], &mut [])
1125             .is_err()
1126     );
1127 
1128     // And using `.get` followed by a function call also fails with cross-Store
1129     // arguments.
1130     let f = store1_func.typed::<Option<Func>, ()>(&store1)?;
1131     let result = f.call(&mut store1, Some(store2_func));
1132     assert!(result.is_err());
1133     assert!(result.unwrap_err().to_string().contains("cross-`Store`"));
1134 
1135     Ok(())
1136 }
1137 
1138 #[test]
1139 #[cfg_attr(miri, ignore)]
1140 fn externref_signature_no_reference_types() -> anyhow::Result<()> {
1141     let mut config = Config::new();
1142     config.wasm_reference_types(false);
1143     let mut store = Store::new(&Engine::new(&config)?, ());
1144     Func::wrap(&mut store, |_: Option<Func>| {});
1145     let func_ty = FuncType::new(
1146         store.engine(),
1147         [ValType::FUNCREF, ValType::EXTERNREF].iter().cloned(),
1148         [ValType::FUNCREF, ValType::EXTERNREF].iter().cloned(),
1149     );
1150     Func::new(&mut store, func_ty, |_, _, _| Ok(()));
1151     Ok(())
1152 }
1153 
1154 #[wasmtime_test]
1155 #[cfg_attr(miri, ignore)]
1156 fn trampolines_always_valid(config: &mut Config) -> anyhow::Result<()> {
1157     // Compile two modules up front
1158     let engine = Engine::new(&config)?;
1159     let mut store = Store::<()>::new(&engine, ());
1160     let module1 = Module::new(store.engine(), "(module (import \"\" \"\" (func)))")?;
1161     let module2 = Module::new(store.engine(), "(module (func (export \"\")))")?;
1162     // Start instantiating the first module, but this will fail.
1163     // Historically this registered the module's trampolines with `Store`
1164     // before the failure, but then after the failure the `Store` didn't
1165     // hold onto the trampoline.
1166     drop(Instance::new(&mut store, &module1, &[]));
1167     drop(module1);
1168 
1169     // Then instantiate another module which has the same function type (no
1170     // parameters or results) which tries to use the trampoline defined in
1171     // the previous module. Then we extract the function and, after we drop the
1172     // module's reference, we call the func.
1173     let i = Instance::new(&mut store, &module2, &[])?;
1174     let func = i.get_func(&mut store, "").unwrap();
1175     drop(module2);
1176 
1177     // ... and no segfaults! right? right? ...
1178     func.call(&mut store, &[], &mut [])?;
1179     Ok(())
1180 }
1181 
1182 #[wasmtime_test]
1183 #[cfg_attr(miri, ignore)]
1184 fn typed_multiple_results(config: &mut Config) -> anyhow::Result<()> {
1185     let engine = Engine::new(&config)?;
1186     let mut store = Store::<()>::new(&engine, ());
1187     let module = Module::new(
1188         store.engine(),
1189         r#"
1190             (module
1191                 (func (export "f0") (result i32 i64)
1192                     i32.const 0
1193                     i64.const 1)
1194                 (func (export "f1") (param i32 i32 i32) (result f32 f64)
1195                     f32.const 2
1196                     f64.const 3)
1197             )
1198 
1199         "#,
1200     )?;
1201     let instance = Instance::new(&mut store, &module, &[])?;
1202     let f0 = instance.get_func(&mut store, "f0").unwrap();
1203     assert!(f0.typed::<(), ()>(&store).is_err());
1204     assert!(f0.typed::<(), (i32, f32)>(&store).is_err());
1205     assert!(f0.typed::<(), i32>(&store).is_err());
1206     assert_eq!(
1207         f0.typed::<(), (i32, i64)>(&store)?.call(&mut store, ())?,
1208         (0, 1)
1209     );
1210 
1211     let f1 = instance.get_func(&mut store, "f1").unwrap();
1212     assert_eq!(
1213         f1.typed::<(i32, i32, i32), (f32, f64)>(&store)?
1214             .call(&mut store, (1, 2, 3))?,
1215         (2., 3.)
1216     );
1217     Ok(())
1218 }
1219 
1220 #[test]
1221 #[cfg_attr(miri, ignore)]
1222 fn trap_doesnt_leak() -> anyhow::Result<()> {
1223     #[derive(Default)]
1224     struct Canary(Arc<AtomicBool>);
1225 
1226     impl Drop for Canary {
1227         fn drop(&mut self) {
1228             self.0.store(true, SeqCst);
1229         }
1230     }
1231 
1232     let mut store = Store::<()>::default();
1233 
1234     // test that `Func::wrap` is correct
1235     let canary1 = Canary::default();
1236     let dtor1_run = canary1.0.clone();
1237     let f1 = Func::wrap(&mut store, move || -> Result<()> {
1238         let _ = &canary1;
1239         bail!("")
1240     });
1241     assert!(f1.typed::<(), ()>(&store)?.call(&mut store, ()).is_err());
1242     assert!(f1.call(&mut store, &[], &mut []).is_err());
1243 
1244     // test that `Func::new` is correct
1245     let canary2 = Canary::default();
1246     let dtor2_run = canary2.0.clone();
1247     let func_ty = FuncType::new(store.engine(), None, None);
1248     let f2 = Func::new(&mut store, func_ty, move |_, _, _| {
1249         let _ = &canary2;
1250         bail!("")
1251     });
1252     assert!(f2.typed::<(), ()>(&store)?.call(&mut store, ()).is_err());
1253     assert!(f2.call(&mut store, &[], &mut []).is_err());
1254 
1255     // drop everything and ensure dtors are run
1256     drop(store);
1257     assert!(dtor1_run.load(SeqCst));
1258     assert!(dtor2_run.load(SeqCst));
1259     Ok(())
1260 }
1261 
1262 #[wasmtime_test]
1263 #[cfg_attr(miri, ignore)]
1264 fn wrap_multiple_results(config: &mut Config) -> anyhow::Result<()> {
1265     fn test<T>(store: &mut Store<()>, t: T) -> anyhow::Result<()>
1266     where
1267         T: WasmRet
1268             + WasmResults
1269             + PartialEq
1270             + Copy
1271             + std::fmt::Debug
1272             + EqualToValues
1273             + 'static
1274             + Send
1275             + Sync,
1276     {
1277         let f = Func::wrap(&mut *store, move || t);
1278         let mut results = vec![Val::I32(0); f.ty(&store).results().len()];
1279         assert_eq!(f.typed::<(), T>(&store)?.call(&mut *store, ())?, t);
1280         f.call(&mut *store, &[], &mut results)?;
1281         assert!(t.eq_values(&results));
1282 
1283         let module = Module::new(store.engine(), &T::gen_wasm())?;
1284         let instance = Instance::new(&mut *store, &module, &[f.into()])?;
1285         let f = instance.get_func(&mut *store, "foo").unwrap();
1286 
1287         assert_eq!(f.typed::<(), T>(&store)?.call(&mut *store, ())?, t);
1288         f.call(&mut *store, &[], &mut results)?;
1289         assert!(t.eq_values(&results));
1290         Ok(())
1291     }
1292 
1293     let engine = Engine::new(&config)?;
1294     let mut store = Store::new(&engine, ());
1295     // 0 element
1296     test(&mut store, ())?;
1297 
1298     // 1 element
1299     test(&mut store, (1i32,))?;
1300     test(&mut store, (2u32,))?;
1301     test(&mut store, (3i64,))?;
1302     test(&mut store, (4u64,))?;
1303     test(&mut store, (5.0f32,))?;
1304     test(&mut store, (6.0f64,))?;
1305 
1306     // 2 element ...
1307     test(&mut store, (7i32, 8i32))?;
1308     test(&mut store, (7i32, 8i64))?;
1309     test(&mut store, (7i32, 8f32))?;
1310     test(&mut store, (7i32, 8f64))?;
1311 
1312     test(&mut store, (7i64, 8i32))?;
1313     test(&mut store, (7i64, 8i64))?;
1314     test(&mut store, (7i64, 8f32))?;
1315     test(&mut store, (7i64, 8f64))?;
1316 
1317     test(&mut store, (7f32, 8i32))?;
1318     test(&mut store, (7f32, 8i64))?;
1319     test(&mut store, (7f32, 8f32))?;
1320     test(&mut store, (7f32, 8f64))?;
1321 
1322     test(&mut store, (7f64, 8i32))?;
1323     test(&mut store, (7f64, 8i64))?;
1324     test(&mut store, (7f64, 8f32))?;
1325     test(&mut store, (7f64, 8f64))?;
1326 
1327     // and beyond...
1328     test(&mut store, (1i32, 2i32, 3i32))?;
1329     test(&mut store, (1i32, 2f32, 3i32))?;
1330     test(&mut store, (1f64, 2f32, 3i32))?;
1331     test(&mut store, (1f64, 2i64, 3i32))?;
1332     test(&mut store, (1f32, 2f32, 3i64, 4f64))?;
1333     test(&mut store, (1f64, 2i64, 3i32, 4i64, 5f32))?;
1334     test(&mut store, (1i32, 2f64, 3i64, 4f64, 5f64, 6f32))?;
1335     test(&mut store, (1i64, 2i32, 3i64, 4f32, 5f32, 6i32, 7u64))?;
1336     test(&mut store, (1u32, 2f32, 3u64, 4f64, 5i32, 6f32, 7u64, 8u32))?;
1337     test(
1338         &mut store,
1339         (1f32, 2f64, 3f32, 4i32, 5u32, 6i64, 7f32, 8i32, 9u64),
1340     )?;
1341     return Ok(());
1342 
1343     trait EqualToValues {
1344         fn eq_values(&self, values: &[Val]) -> bool;
1345         fn gen_wasm() -> String;
1346     }
1347 
1348     macro_rules! equal_tuples {
1349         ($($cnt:tt ($($a:ident),*))*) => ($(
1350             #[allow(non_snake_case, reason = "macro-generated code")]
1351             impl<$($a: EqualToValue,)*> EqualToValues for ($($a,)*) {
1352                 fn eq_values(&self, values: &[Val]) -> bool {
1353                     let ($($a,)*) = self;
1354                     let mut _values = values.iter();
1355                     _values.len() == $cnt &&
1356                         $($a.eq_value(_values.next().unwrap()) &&)*
1357                         true
1358                 }
1359 
1360                 fn gen_wasm() -> String {
1361                     let mut wasm = String::new();
1362                     wasm.push_str("(module ");
1363                     wasm.push_str("(type $t (func (result ");
1364                     $(
1365                         wasm.push_str($a::wasm_ty());
1366                         wasm.push_str(" ");
1367                     )*
1368                     wasm.push_str(")))");
1369 
1370                     wasm.push_str("(import \"\" \"\" (func $host (type $t)))");
1371                     wasm.push_str("(func (export \"foo\") (type $t)");
1372                     wasm.push_str("call $host");
1373                     wasm.push_str(")");
1374                     wasm.push_str(")");
1375 
1376                     wasm
1377                 }
1378             }
1379         )*)
1380     }
1381 
1382     equal_tuples! {
1383         0 ()
1384         1 (A1)
1385         2 (A1, A2)
1386         3 (A1, A2, A3)
1387         4 (A1, A2, A3, A4)
1388         5 (A1, A2, A3, A4, A5)
1389         6 (A1, A2, A3, A4, A5, A6)
1390         7 (A1, A2, A3, A4, A5, A6, A7)
1391         8 (A1, A2, A3, A4, A5, A6, A7, A8)
1392         9 (A1, A2, A3, A4, A5, A6, A7, A8, A9)
1393     }
1394 
1395     trait EqualToValue {
1396         fn eq_value(&self, value: &Val) -> bool;
1397         fn wasm_ty() -> &'static str;
1398     }
1399 
1400     macro_rules! equal_values {
1401         ($a:ident $($ty:ident $wasm:tt $variant:ident $e:expr,)*) => ($(
1402             impl EqualToValue for $ty {
1403                 fn eq_value(&self, val: &Val) -> bool {
1404                     if let Val::$variant($a) = *val {
1405                         return *self == $e;
1406                     }
1407                     false
1408                 }
1409 
1410                 fn wasm_ty() -> &'static str {
1411                     $wasm
1412                 }
1413             }
1414         )*)
1415     }
1416 
1417     equal_values! {
1418         a
1419         i32 "i32" I32 a,
1420         u32 "i32" I32 a as u32,
1421         i64 "i64" I64 a,
1422         u64 "i64" I64 a as u64,
1423         f32 "f32" F32 f32::from_bits(a),
1424         f64 "f64" F64 f64::from_bits(a),
1425     }
1426 }
1427 
1428 #[wasmtime_test(wasm_features(reference_types, gc_types))]
1429 #[cfg_attr(miri, ignore)]
1430 fn trampoline_for_declared_elem(config: &mut Config) -> anyhow::Result<()> {
1431     let engine = Engine::new(&config)?;
1432 
1433     let module = Module::new(
1434         &engine,
1435         r#"
1436             (module
1437                 (elem declare func $f)
1438                 (func $f)
1439                 (func (export "g") (result funcref)
1440                   (ref.func $f)
1441                 )
1442             )
1443         "#,
1444     )?;
1445 
1446     let mut store = Store::new(&engine, ());
1447     let instance = Instance::new(&mut store, &module, &[])?;
1448 
1449     let g = instance.get_typed_func::<(), Option<Func>>(&mut store, "g")?;
1450 
1451     let func = g.call(&mut store, ())?;
1452     func.unwrap().call(&mut store, &[], &mut [])?;
1453     Ok(())
1454 }
1455 
1456 #[wasmtime_test]
1457 #[cfg_attr(miri, ignore)]
1458 fn wasm_ty_roundtrip(config: &mut Config) -> Result<(), anyhow::Error> {
1459     let engine = Engine::new(&config)?;
1460     let mut store = Store::<()>::new(&engine, ());
1461     let debug = Func::wrap(
1462         &mut store,
1463         |a: i32, b: u32, c: f32, d: i64, e: u64, f: f64| {
1464             assert_eq!(a, -1);
1465             assert_eq!(b, 1);
1466             assert_eq!(c, 2.0);
1467             assert_eq!(d, -3);
1468             assert_eq!(e, 3);
1469             assert_eq!(f, 4.0);
1470         },
1471     );
1472     let module = Module::new(
1473         store.engine(),
1474         r#"
1475              (module
1476                  (import "" "" (func $debug (param i32 i32 f32 i64 i64 f64)))
1477                  (func (export "foo") (param i32 i32 f32 i64 i64 f64)
1478                     (if (i32.ne (local.get 0) (i32.const -1))
1479                         (then unreachable)
1480                     )
1481                     (if (i32.ne (local.get 1) (i32.const 1))
1482                         (then unreachable)
1483                     )
1484                     (if (f32.ne (local.get 2) (f32.const 2))
1485                         (then unreachable)
1486                     )
1487                     (if (i64.ne (local.get 3) (i64.const -3))
1488                         (then unreachable)
1489                     )
1490                     (if (i64.ne (local.get 4) (i64.const 3))
1491                         (then unreachable)
1492                     )
1493                     (if (f64.ne (local.get 5) (f64.const 4))
1494                         (then unreachable)
1495                     )
1496                     local.get 0
1497                     local.get 1
1498                     local.get 2
1499                     local.get 3
1500                     local.get 4
1501                     local.get 5
1502                     call $debug
1503                 )
1504             )
1505          "#,
1506     )?;
1507     let instance = Instance::new(&mut store, &module, &[debug.into()])?;
1508     let foo = instance.get_typed_func::<(i32, u32, f32, i64, u64, f64), ()>(&mut store, "foo")?;
1509     foo.call(&mut store, (-1, 1, 2.0, -3, 3, 4.0))?;
1510     Ok(())
1511 }
1512 
1513 #[wasmtime_test]
1514 #[cfg_attr(miri, ignore)]
1515 fn typed_funcs_count_params_correctly_in_error_messages(config: &mut Config) -> anyhow::Result<()> {
1516     let engine = Engine::new(&config)?;
1517     let mut store = Store::<()>::new(&engine, ());
1518     let module = Module::new(
1519         store.engine(),
1520         r#"
1521             (module
1522                 (func (export "f") (param i32 i32))
1523             )
1524 
1525         "#,
1526     )?;
1527     let instance = Instance::new(&mut store, &module, &[])?;
1528 
1529     // Too few parameters.
1530     match instance.get_typed_func::<(), ()>(&mut store, "f") {
1531         Ok(_) => panic!("should be wrong signature"),
1532         Err(e) => {
1533             let msg = format!("{e:?}");
1534             assert!(dbg!(msg).contains("expected 0 types, found 2"))
1535         }
1536     }
1537     match instance.get_typed_func::<(i32,), ()>(&mut store, "f") {
1538         Ok(_) => panic!("should be wrong signature"),
1539         Err(e) => {
1540             let msg = format!("{e:?}");
1541             assert!(dbg!(msg).contains("expected 1 types, found 2"))
1542         }
1543     }
1544 
1545     // Too many parameters.
1546     match instance.get_typed_func::<(i32, i32, i32), ()>(&mut store, "f") {
1547         Ok(_) => panic!("should be wrong signature"),
1548         Err(e) => {
1549             let msg = format!("{e:?}");
1550             assert!(dbg!(msg).contains("expected 3 types, found 2"))
1551         }
1552     }
1553 
1554     Ok(())
1555 }
1556 
1557 #[wasmtime_test(wasm_features(reference_types, gc_types))]
1558 #[cfg_attr(miri, ignore)]
1559 fn calls_with_funcref_and_externref(config: &mut Config) -> anyhow::Result<()> {
1560     let engine = Engine::new(&config)?;
1561     let mut store = Store::<()>::new(&engine, ());
1562     let module = Module::new(
1563         store.engine(),
1564         r#"
1565             (module
1566                 (import "" "witness" (func $witness (param funcref externref)))
1567                 (func (export "f") (param funcref externref) (result externref funcref)
1568                     local.get 0
1569                     local.get 1
1570                     call $witness
1571                     local.get 1
1572                     local.get 0
1573                 )
1574             )
1575 
1576         "#,
1577     )?;
1578     let mut linker = Linker::new(store.engine());
1579     linker.func_wrap(
1580         "",
1581         "witness",
1582         |mut caller: Caller<'_, ()>, func: Option<Func>, externref: Option<Rooted<ExternRef>>| {
1583             if func.is_some() {
1584                 assert_my_funcref(&mut caller, func.as_ref())?;
1585             }
1586             if externref.is_some() {
1587                 assert_my_externref(&caller, externref);
1588             }
1589             Ok(())
1590         },
1591     )?;
1592     let instance = linker.instantiate(&mut store, &module)?;
1593 
1594     let typed = instance
1595         .get_typed_func::<(Option<Func>, Option<Rooted<ExternRef>>), (Option<Rooted<ExternRef>>, Option<Func>)>(
1596             &mut store, "f",
1597         )?;
1598     let untyped = typed.func();
1599 
1600     let my_funcref = Func::wrap(&mut store, || 100u32);
1601     let my_externref = ExternRef::new(&mut store, 99u32)?;
1602     let mut results = [Val::I32(0), Val::I32(0)];
1603 
1604     fn assert_my_funcref(mut store: impl AsContextMut, func: Option<&Func>) -> Result<()> {
1605         let mut store = store.as_context_mut();
1606         let func = func.unwrap();
1607         assert_eq!(func.typed::<(), u32>(&store)?.call(&mut store, ())?, 100);
1608         Ok(())
1609     }
1610     fn assert_my_externref(store: impl AsContext, externref: Option<Rooted<ExternRef>>) {
1611         assert_eq!(
1612             externref
1613                 .unwrap()
1614                 .data(&store)
1615                 .unwrap()
1616                 .unwrap()
1617                 .downcast_ref(),
1618             Some(&99u32)
1619         );
1620     }
1621 
1622     // funcref=null, externref=null
1623     let (a, b) = typed.call(&mut store, (None, None))?;
1624     assert!(a.is_none());
1625     assert!(b.is_none());
1626     untyped.call(
1627         &mut store,
1628         &[Val::FuncRef(None), Val::ExternRef(None)],
1629         &mut results,
1630     )?;
1631     assert!(results[0].unwrap_externref().is_none());
1632     assert!(results[1].unwrap_funcref().is_none());
1633 
1634     // funcref=Some, externref=null
1635     let (a, b) = typed.call(&mut store, (Some(my_funcref), None))?;
1636     assert!(a.is_none());
1637     assert_my_funcref(&mut store, b.as_ref())?;
1638     untyped.call(
1639         &mut store,
1640         &[Val::FuncRef(Some(my_funcref)), Val::ExternRef(None)],
1641         &mut results,
1642     )?;
1643     assert!(results[0].unwrap_externref().is_none());
1644     assert_my_funcref(&mut store, results[1].unwrap_funcref())?;
1645 
1646     // funcref=null, externref=Some
1647     let (a, b) = typed.call(&mut store, (None, Some(my_externref)))?;
1648     assert_my_externref(&store, a);
1649     assert!(b.is_none());
1650     untyped.call(
1651         &mut store,
1652         &[Val::FuncRef(None), Val::ExternRef(Some(my_externref))],
1653         &mut results,
1654     )?;
1655     assert_my_externref(&store, results[0].unwrap_externref().copied());
1656     assert!(results[1].unwrap_funcref().is_none());
1657 
1658     // funcref=Some, externref=Some
1659     let (a, b) = typed.call(&mut store, (Some(my_funcref), Some(my_externref)))?;
1660     assert_my_externref(&store, a);
1661     assert_my_funcref(&mut store, b.as_ref())?;
1662     untyped.call(
1663         &mut store,
1664         &[
1665             Val::FuncRef(Some(my_funcref)),
1666             Val::ExternRef(Some(my_externref)),
1667         ],
1668         &mut results,
1669     )?;
1670     assert_my_externref(&store, results[0].unwrap_externref().copied());
1671     assert_my_funcref(&mut store, results[1].unwrap_funcref())?;
1672 
1673     Ok(())
1674 }
1675 
1676 #[wasmtime_test(wasm_features(function_references))]
1677 #[cfg_attr(miri, ignore)]
1678 fn typed_concrete_param(config: &mut Config) -> anyhow::Result<()> {
1679     let engine = Engine::new(&config)?;
1680     let module = Module::new(
1681         &engine,
1682         r#"
1683             (module
1684                 (type $t (func))
1685                 (func (export "f") (param (ref null $t)))
1686             )
1687         "#,
1688     )?;
1689     let mut store = Store::new(&engine, ());
1690     let instance = Instance::new(&mut store, &module, &[])?;
1691 
1692     let nop = Func::new(
1693         &mut store,
1694         FuncType::new(&engine, None, None),
1695         |_caller, _params, _results| Ok(()),
1696     );
1697 
1698     let f = instance.get_func(&mut store, "f").unwrap();
1699 
1700     // Can type with a subtype, which should avoid all dynamic type checks after
1701     // successful construction.
1702     let a = f.typed::<Option<NoFunc>, ()>(&store)?;
1703     a.call(&mut store, None)?;
1704     // NB: Cannot call with Some(_) as `NoFunc` is uninhabited.
1705 
1706     // Can call `typed` with a supertype, falling back to dynamic type checks on
1707     // each call.
1708     let a = f.typed::<Option<Func>, ()>(&store)?;
1709     a.call(&mut store, None)?;
1710     a.call(&mut store, Some(nop))?;
1711     let e = a.call(&mut store, Some(f)).expect_err(
1712         "should return an error because while we did pass an instance of \
1713          `Option<Func>`, it was not an instance of `(ref null $t)`",
1714     );
1715     let e = format!("{e:?}");
1716     assert!(e.contains("argument type mismatch for reference to concrete type"));
1717     assert!(e.contains(
1718         "type mismatch: expected (type (func)), \
1719          found (type (func (param (ref null (concrete func VMSharedTypeIndex(0))))))"
1720     ));
1721 
1722     // And dynamic checks also work with a non-nullable super type.
1723     let a = f.typed::<Func, ()>(&store)?;
1724     a.call(&mut store, nop)?;
1725     let e = a.call(&mut store, f).expect_err(
1726         "should return an error because while we did pass an instance of \
1727          `Func`, it was not an instance of `(ref null $t)`",
1728     );
1729     let e = format!("{e:?}");
1730     assert!(e.contains("argument type mismatch for reference to concrete type"));
1731     assert!(e.contains(
1732         "type mismatch: expected (type (func)), \
1733          found (type (func (param (ref null (concrete func VMSharedTypeIndex(0))))))"
1734     ));
1735 
1736     // Calling `typed` with a type that is not a supertype nor a subtype fails
1737     // the initial type check.
1738     let e = f
1739         .typed::<Option<Rooted<ExternRef>>, ()>(&store)
1740         .err()
1741         .unwrap();
1742     let e = format!("{e:?}");
1743     assert!(e.contains("type mismatch with parameters"));
1744     assert!(e.contains("type mismatch: expected func, found extern"));
1745 
1746     Ok(())
1747 }
1748 
1749 #[wasmtime_test(wasm_features(function_references))]
1750 #[cfg_attr(miri, ignore)]
1751 fn typed_concrete_result(config: &mut Config) -> anyhow::Result<()> {
1752     let engine = Engine::new(&config)?;
1753     let module = Module::new(
1754         &engine,
1755         r#"
1756             (module
1757                 (type $t (func))
1758                 (func $nop)
1759                 (elem declare func $nop)
1760                 (func (export "f") (result (ref $t))
1761                     ref.func $nop
1762                 )
1763             )
1764         "#,
1765     )?;
1766     let mut store = Store::new(&engine, ());
1767     let instance = Instance::new(&mut store, &module, &[])?;
1768 
1769     let f = instance.get_func(&mut store, "f").unwrap();
1770 
1771     // Can type `f` with a supertype of the declared result type, and we get the
1772     // expected return value.
1773     let a = f.typed::<(), Func>(&store)?;
1774     let g = a.call(&mut store, ())?;
1775     g.typed::<(), ()>(&store)?.call(&mut store, ())?;
1776 
1777     // Also works with a nullable supertype.
1778     let a = f.typed::<(), Option<Func>>(&store)?;
1779     let g = a.call(&mut store, ())?;
1780     g.unwrap().typed::<(), ()>(&store)?.call(&mut store, ())?;
1781 
1782     // But we can't claim that `f` returns a particular subtype of its actual
1783     // return type.
1784     let e = f.typed::<(), NoFunc>(&store).err().unwrap();
1785     let e = format!("{e:?}");
1786     assert!(e.contains("type mismatch with results"));
1787     assert!(e.contains(
1788         "type mismatch: expected (ref nofunc), found (ref (concrete func VMSharedTypeIndex(0)))"
1789     ));
1790 
1791     // Nor some unrelated type that it is neither a subtype or supertype of.
1792     let e = f.typed::<(), Rooted<ExternRef>>(&store).err().unwrap();
1793     let e = format!("{e:?}");
1794     assert!(e.contains("type mismatch with results"));
1795     assert!(e.contains(
1796         "type mismatch: expected (ref extern), found (ref (concrete func VMSharedTypeIndex(0)))"
1797     ));
1798 
1799     Ok(())
1800 }
1801 
1802 #[test]
1803 #[cfg_attr(miri, ignore)]
1804 fn wrap_subtype_param() -> anyhow::Result<()> {
1805     let mut store = Store::<()>::default();
1806     let f = Func::wrap(&mut store, |_caller: Caller<'_, ()>, _: Option<Func>| {
1807         // No-op.
1808     });
1809 
1810     // Precise type.
1811     let a = f.typed::<Option<Func>, ()>(&store)?;
1812     a.call(&mut store, None)?;
1813     a.call(&mut store, Some(f))?;
1814 
1815     // Subtype via heap type.
1816     let a = f.typed::<Option<NoFunc>, ()>(&store)?;
1817     a.call(&mut store, None)?;
1818 
1819     // Subtype via non-null.
1820     let a = f.typed::<Func, ()>(&store)?;
1821     a.call(&mut store, f)?;
1822 
1823     Ok(())
1824 }
1825 
1826 #[test]
1827 #[cfg_attr(miri, ignore)]
1828 fn wrap_supertype_result() -> anyhow::Result<()> {
1829     let mut store = Store::<()>::default();
1830     let f = Func::wrap(&mut store, |_caller: Caller<'_, ()>| -> NoFunc {
1831         unreachable!()
1832     });
1833 
1834     // Precise type.
1835     let _ = f.typed::<(), NoFunc>(&store)?;
1836 
1837     // Supertype via heap type.
1838     let _ = f.typed::<(), Func>(&store)?;
1839 
1840     // Supertype via nullability.
1841     let _ = f.typed::<(), Option<NoFunc>>(&store)?;
1842 
1843     Ok(())
1844 }
1845 
1846 #[wasmtime_test(wasm_features(function_references))]
1847 #[cfg_attr(miri, ignore)]
1848 fn call_wasm_passing_subtype_func_param(config: &mut Config) -> anyhow::Result<()> {
1849     config.wasm_function_references(true);
1850     let engine = Engine::new(&config)?;
1851     let mut store = Store::new(&engine, ());
1852 
1853     let module = Module::new(
1854         &engine,
1855         r#"
1856             (module
1857                 (type $ty (func (result funcref)))
1858                 (func (export "f") (param (ref null $ty)) (result funcref)
1859                     ;; Return null if the funcref is null.
1860                     ref.null func
1861                     local.get 0
1862                     ref.is_null
1863                     br_if 0
1864                     drop
1865 
1866                     ;; Otherwise, call it.
1867                     local.get 0
1868                     call_ref $ty
1869                 )
1870             )
1871         "#,
1872     )?;
1873 
1874     let instance = Instance::new(&mut store, &module, &[])?;
1875     let f = instance.get_func(&mut store, "f").unwrap();
1876 
1877     let g_ty = FuncType::new(&engine, None, Some(ValType::I32));
1878     let g = Func::new(&mut store, g_ty.clone(), |_caller, _params, results| {
1879         results[0] = Val::I32(0x1234_5678);
1880         Ok(())
1881     });
1882 
1883     // h's type is a subtype of the Wasm-defined `$ty`:
1884     //
1885     //     (func (result (ref null g_ty))) <: (func (result funcref))
1886     let h_ty = FuncType::new(
1887         &engine,
1888         None,
1889         Some(ValType::Ref(RefType::new(
1890             true,
1891             HeapType::ConcreteFunc(g_ty),
1892         ))),
1893     );
1894     let h = Func::new(&mut store, h_ty, move |_caller, _params, results| {
1895         results[0] = Val::FuncRef(Some(g));
1896         Ok(())
1897     });
1898 
1899     // Array call, passing in a subtype of the expected parameter.
1900 
1901     let mut results = vec![Val::I32(0)];
1902     f.call(&mut store, &[Val::null_func_ref()], &mut results)?;
1903     assert!(results[0].unwrap_func_ref().is_none());
1904 
1905     f.call(&mut store, &[h.into()], &mut results)?;
1906     let g = results[0];
1907     let g = g.unwrap_func_ref().unwrap();
1908     g.call(&mut store, &[], &mut results)?;
1909     assert_eq!(results[0].unwrap_i32(), 0x1234_5678);
1910 
1911     // Native call, passing in a subtype of the expected parameter.
1912 
1913     let f = f.typed::<Option<Func>, Option<Func>>(&store)?;
1914     let r = f.call(&mut store, None)?;
1915     assert!(r.is_none());
1916 
1917     let g = f.call(&mut store, Some(h))?;
1918     let g = g.unwrap().typed::<(), u32>(&mut store)?;
1919     let x = g.call(&mut store, ())?;
1920     assert_eq!(x, 0x1234_5678);
1921 
1922     Ok(())
1923 }
1924 
1925 #[wasmtime_test(wasm_features(gc, function_references))]
1926 #[cfg_attr(miri, ignore)]
1927 fn call_wasm_getting_subtype_func_return(config: &mut Config) -> anyhow::Result<()> {
1928     let engine = Engine::new(&config)?;
1929     let mut store = Store::new(&engine, ());
1930 
1931     let module = Module::new(
1932         &engine,
1933         r#"
1934             (module
1935                 (type $ty (func (result funcref)))
1936 
1937                 (func $a (result i32)
1938                     i32.const 0x12345678
1939                 )
1940 
1941                 (func $b (result funcref)
1942                     ref.func $a
1943                 )
1944 
1945                 (elem declare func $a $b)
1946 
1947                 ;; Returns a `(ref null nofunc)` if called with `0`, otherwise
1948                 ;; returns `(ref null $ty)`, both of which are subtypes of
1949                 ;; `funcref`.
1950                 (func (export "f") (param i32) (result funcref)
1951                     block
1952                         local.get 0
1953                         br_if 0
1954                         ref.null nofunc
1955                         return
1956                     end
1957                     ref.func $b
1958                 )
1959             )
1960         "#,
1961     )?;
1962 
1963     let instance = Instance::new(&mut store, &module, &[])?;
1964     let f = instance.get_func(&mut store, "f").unwrap();
1965 
1966     // Array call, receiving a subtype of the expected result.
1967 
1968     let mut results = vec![Val::I32(0)];
1969     f.call(&mut store, &[Val::I32(0)], &mut results)?;
1970     assert!(results[0].unwrap_func_ref().is_none());
1971 
1972     f.call(&mut store, &[Val::I32(1)], &mut results)?;
1973     let b = results[0];
1974     let b = b.unwrap_func_ref().unwrap();
1975     b.call(&mut store, &[], &mut results)?;
1976     let a = results[0];
1977     let a = a.unwrap_func_ref().unwrap();
1978     a.call(&mut store, &[], &mut results)?;
1979     assert_eq!(results[0].unwrap_i32(), 0x1234_5678);
1980 
1981     // Native call, receiving a subtype of the expected result.
1982 
1983     let f = f.typed::<u32, Option<Func>>(&store)?;
1984     let r = f.call(&mut store, 0)?;
1985     assert!(r.is_none());
1986 
1987     let b = f.call(&mut store, 1)?;
1988     let b = b.unwrap().typed::<(), Option<Func>>(&store)?;
1989     let a = b.call(&mut store, ())?;
1990     let a = a.unwrap().typed::<(), u32>(&store)?;
1991     let x = a.call(&mut store, ())?;
1992     assert_eq!(x, 0x1234_5678);
1993 
1994     Ok(())
1995 }
1996 
1997 #[wasmtime_test(wasm_features(simd), strategies(not(Winch)))]
1998 #[cfg_attr(miri, ignore)]
1999 fn typed_v128(config: &mut Config) -> anyhow::Result<()> {
2000     let engine = Engine::new(&config)?;
2001     let mut store = Store::<()>::new(&engine, ());
2002     let module = Module::new(
2003         store.engine(),
2004         r#"
2005             (module
2006                 (func (export "a") (param v128) (result v128)
2007                     local.get 0)
2008                 (func (export "b") (param v128 v128) (result v128 v128)
2009                     local.get 0
2010                     local.get 1)
2011                 (func (export "c") (param v128 v128 v128 v128 v128 v128 v128 v128) (result v128)
2012                     local.get 0
2013                     local.get 1
2014                     local.get 2
2015                     local.get 3
2016                     local.get 4
2017                     local.get 5
2018                     local.get 6
2019                     local.get 7
2020                     i64x2.add
2021                     i64x2.add
2022                     i64x2.add
2023                     i64x2.add
2024                     i64x2.add
2025                     i64x2.add
2026                     i64x2.add)
2027             )
2028 
2029         "#,
2030     )?;
2031     let instance = Instance::new(&mut store, &module, &[])?;
2032 
2033     let a = instance.get_typed_func::<V128, V128>(&mut store, "a")?;
2034     assert_eq!(a.call(&mut store, V128::from(1))?, V128::from(1));
2035     assert_eq!(a.call(&mut store, V128::from(2))?, V128::from(2));
2036 
2037     let b = instance.get_typed_func::<(V128, V128), (V128, V128)>(&mut store, "b")?;
2038     assert_eq!(
2039         b.call(&mut store, (V128::from(1), V128::from(2)))?,
2040         (V128::from(1), V128::from(2))
2041     );
2042 
2043     let c = instance.get_typed_func::<(V128, V128, V128, V128, V128, V128, V128, V128), V128>(
2044         &mut store, "c",
2045     )?;
2046     assert_eq!(
2047         c.call(
2048             &mut store,
2049             (
2050                 V128::from(1),
2051                 V128::from(2),
2052                 V128::from(3),
2053                 V128::from(4),
2054                 V128::from(5),
2055                 V128::from(6),
2056                 V128::from(7),
2057                 V128::from(8),
2058             )
2059         )?,
2060         V128::from(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8),
2061     );
2062 
2063     Ok(())
2064 }
2065 
2066 #[wasmtime_test(wasm_features(simd))]
2067 #[cfg_attr(miri, ignore)]
2068 fn typed_v128_imports(config: &mut Config) -> anyhow::Result<()> {
2069     let engine = Engine::new(&config)?;
2070     let mut store = Store::<()>::new(&engine, ());
2071     let module = Module::new(
2072         store.engine(),
2073         r#"
2074             (module
2075                 (import "" "a" (func $a (param v128) (result i32)))
2076                 (import "" "b" (func $b (param i32) (result v128)))
2077                 (import "" "c" (func $c (param v128 f64 v128) (result v128 i32 v128)))
2078                 (import "" "d" (func $d (param v128 v128 v128 v128 v128 v128 v128 v128) (result i32)))
2079 
2080                 (func (export "a") (param v128) (result i32)
2081                     local.get 0
2082                     call $a)
2083 
2084                 (func (export "b") (param i32) (result v128)
2085                     local.get 0
2086                     call $b)
2087 
2088                 (func (export "c") (param v128 f64 v128) (result v128 i32 v128)
2089                     local.get 0
2090                     local.get 1
2091                     local.get 2
2092                     call $c)
2093 
2094                 (func (export "d") (param v128 v128 v128 v128 v128 v128 v128 v128) (result i32)
2095                     local.get 0
2096                     local.get 1
2097                     local.get 2
2098                     local.get 3
2099                     local.get 4
2100                     local.get 5
2101                     local.get 6
2102                     local.get 7
2103                     call $d)
2104             )
2105 
2106         "#,
2107     )?;
2108 
2109     let mut l = Linker::new(store.engine());
2110     l.func_wrap("", "a", |x: V128| {
2111         let x = x.as_u128();
2112         (x >> 0) as u32 + (x >> 32) as u32 + (x >> 64) as u32 + (x >> 96) as u32
2113     })?;
2114     l.func_wrap("", "b", |x: u32| {
2115         let x = u128::from(x);
2116         V128::from(x | ((x + 1) << 32) | ((x + 2) << 64) | ((x + 3) << 96))
2117     })?;
2118     l.func_wrap("", "c", |x: V128, y: f64, z: V128| (x, y as i32, z))?;
2119     l.func_wrap(
2120         "",
2121         "d",
2122         |a0: V128, a1: V128, a2: V128, a3: V128, a4: V128, a5: V128, a6: V128, a7: V128| {
2123             let tmp = a0.as_u128()
2124                 + a1.as_u128()
2125                 + a2.as_u128()
2126                 + a3.as_u128()
2127                 + a4.as_u128()
2128                 + a5.as_u128()
2129                 + a6.as_u128()
2130                 + a7.as_u128();
2131             (tmp >> 0) as u32 + (tmp >> 32) as u32 + (tmp >> 64) as u32 + (tmp >> 96) as u32
2132         },
2133     )?;
2134 
2135     let i = l.instantiate(&mut store, &module)?;
2136     let a = i.get_typed_func::<V128, i32>(&mut store, "a")?;
2137     let b = i.get_typed_func::<i32, V128>(&mut store, "b")?;
2138     let c = i.get_typed_func::<(V128, f64, V128), (V128, i32, V128)>(&mut store, "c")?;
2139     let d =
2140         i.get_typed_func::<(V128, V128, V128, V128, V128, V128, V128, V128), i32>(&mut store, "d")?;
2141 
2142     assert_eq!(
2143         a.call(&mut store, 0x00000004_00000003_00000002_00000001.into())?,
2144         1 + 2 + 3 + 4
2145     );
2146     assert_eq!(
2147         b.call(&mut store, 0x10)?,
2148         V128::from(0x00000013_00000012_00000011_00000010),
2149     );
2150     assert_eq!(
2151         c.call(&mut store, (1.into(), 2., 3.into()))?,
2152         (V128::from(1), 2, V128::from(3)),
2153     );
2154     assert_eq!(
2155         d.call(
2156             &mut store,
2157             (
2158                 1.into(),
2159                 2.into(),
2160                 3.into(),
2161                 4.into(),
2162                 5.into(),
2163                 6.into(),
2164                 7.into(),
2165                 8.into(),
2166             )
2167         )?,
2168         1 + 2 + 3 + 4 + 5 + 6 + 7 + 8
2169     );
2170 
2171     Ok(())
2172 }
2173 
2174 #[wasmtime_test(wasm_features(function_references, gc))]
2175 #[cfg_attr(miri, ignore)]
2176 fn wrap_and_typed_i31ref(config: &mut Config) -> Result<()> {
2177     let engine = Engine::new(&config)?;
2178     let mut store = Store::<AtomicUsize>::new(&engine, AtomicUsize::new(0));
2179 
2180     let mut linker = Linker::new(&engine);
2181     linker.func_wrap(
2182         "env",
2183         "i31ref",
2184         |caller: Caller<'_, AtomicUsize>, x: Option<I31>| -> Option<I31> {
2185             assert_eq!(caller.data().fetch_add(1, Ordering::SeqCst), 0);
2186             x
2187         },
2188     )?;
2189     linker.func_wrap(
2190         "env",
2191         "ref-i31",
2192         |caller: Caller<'_, AtomicUsize>, x: I31| -> I31 {
2193             assert_eq!(caller.data().fetch_add(1, Ordering::SeqCst), 1);
2194             x
2195         },
2196     )?;
2197 
2198     let module = Module::new(
2199         &engine,
2200         r#"
2201             (module
2202                 (import "env" "i31ref" (func (param i31ref) (result i31ref)))
2203                 (import "env" "ref-i31" (func (param (ref i31)) (result (ref i31))))
2204 
2205                 (func (export "i31ref") (param i31ref) (result i31ref)
2206                     local.get 0
2207                     call 0
2208                 )
2209 
2210                 (func (export "ref-i31") (param (ref i31)) (result (ref i31))
2211                     local.get 0
2212                     call 1
2213                 )
2214             )
2215         "#,
2216     )?;
2217 
2218     let instance = linker.instantiate(&mut store, &module)?;
2219 
2220     let i31ref = instance.get_typed_func::<Option<I31>, Option<I31>>(&mut store, "i31ref")?;
2221     let x = i31ref.call(&mut store, Some(I31::wrapping_u32(42)))?;
2222     assert_eq!(x, Some(I31::wrapping_u32(42)));
2223 
2224     let ref_i31 = instance.get_typed_func::<I31, I31>(&mut store, "ref-i31")?;
2225     let x = ref_i31.call(&mut store, I31::wrapping_u32(0x1234))?;
2226     assert_eq!(x, I31::wrapping_u32(0x1234));
2227 
2228     assert_eq!(store.data().load(Ordering::SeqCst), 2);
2229     Ok(())
2230 }
2231 
2232 #[wasmtime_test(wasm_features(function_references, gc))]
2233 fn call_func_with_funcref_both_typed_and_untyped(config: &mut Config) -> Result<()> {
2234     let engine = Engine::new(&config)?;
2235     let mut store = Store::new(&engine, ());
2236 
2237     let f1 = Func::wrap(&mut store, |_: Option<Func>| {});
2238     let f2 = Func::wrap(&mut store, || {});
2239 
2240     f1.typed::<Func, ()>(&mut store)?.call(&mut store, f2)?;
2241     f1.call(&mut store, &[Val::FuncRef(Some(f2))], &mut [])?;
2242     Ok(())
2243 }
2244 
2245 #[wasmtime_test(wasm_features(function_references, gc))]
2246 #[cfg_attr(miri, ignore)]
2247 fn wasm_to_host_trampolines_and_subtyping(config: &mut Config) -> Result<()> {
2248     let _ = env_logger::try_init();
2249 
2250     let engine = Engine::new(&config)?;
2251 
2252     let ft0 = FuncType::with_finality_and_supertype(
2253         &engine,
2254         Finality::NonFinal,
2255         None,
2256         [],
2257         [ValType::Ref(RefType::new(true, HeapType::Extern))],
2258     )?;
2259     let ft1 = FuncType::with_finality_and_supertype(
2260         &engine,
2261         Finality::NonFinal,
2262         Some(&ft0),
2263         [],
2264         [ValType::Ref(RefType::new(false, HeapType::Extern))],
2265     )?;
2266 
2267     let module = Module::new(
2268         &engine,
2269         r#"
2270             (module
2271                 (type $ft0 (sub (func (result (ref null extern)))))
2272 
2273                 (import "" "a" (func $imported_func (type $ft0)))
2274                 (import "" "return_func" (func $return_func (result (ref $ft0))))
2275                 (global $g (export "g") (mut (ref null $ft0)) (ref.null $ft0))
2276                 (table $t (export "t") 10 10 (ref null $ft0))
2277 
2278                 (func (export "f")
2279                     (drop (call $imported_func))
2280                     (drop (call_ref $ft0 (call $return_func)))
2281                     (drop (call_ref $ft0 (global.get $g)))
2282                     (drop (call_ref $ft0 (table.get $t (i32.const 0))))
2283                 )
2284             )
2285         "#,
2286     )?;
2287 
2288     // This defines a function of type `(func (result (ref extern)))` and not of
2289     // type `(func (result (ref null extern)))` that the Wasm imports. But it is
2290     // still a subtype of the Wasm import's type, so we should be able to use
2291     // the Wasm's precompiled trampolines with this host function.
2292     //
2293     // But this means we also need to look up the trampoline by the caller's
2294     // type, rather than the callee's type.
2295     //
2296     // So give it to Wasm in every way that Wasm can receive a function, and
2297     // make sure we find the correct trampolines in all cases and everything
2298     // works.
2299     let make_func = |store: &mut Store<_>| {
2300         Func::new(
2301             store,
2302             ft1.clone(),
2303             |mut caller: Caller<'_, ()>, _args, results| {
2304                 results[0] = ExternRef::new(&mut caller, 200)?.into();
2305                 Ok(())
2306             },
2307         )
2308     };
2309 
2310     let return_func_ty = module.imports().nth(1).unwrap().ty().unwrap_func().clone();
2311 
2312     let mut store = Store::new(&engine, ());
2313 
2314     let imported_func = make_func(&mut store);
2315     assert!(FuncType::eq(&imported_func.ty(&store), &ft1));
2316 
2317     let returned_func = make_func(&mut store);
2318     assert!(FuncType::eq(&returned_func.ty(&store), &ft1));
2319 
2320     let return_func = Func::new(
2321         &mut store,
2322         return_func_ty.clone(),
2323         move |_caller, _args, results| {
2324             results[0] = returned_func.into();
2325             Ok(())
2326         },
2327     );
2328 
2329     let instance = Instance::new(
2330         &mut store,
2331         &module,
2332         &[imported_func.into(), return_func.into()],
2333     )?;
2334 
2335     let g = make_func(&mut store);
2336     assert!(FuncType::eq(&g.ty(&store), &ft1));
2337     instance
2338         .get_global(&mut store, "g")
2339         .unwrap()
2340         .set(&mut store, g.into())?;
2341 
2342     let t = make_func(&mut store);
2343     assert!(FuncType::eq(&t.ty(&store), &ft1));
2344     instance
2345         .get_table(&mut store, "t")
2346         .unwrap()
2347         .set(&mut store, 0, t.into())?;
2348 
2349     let f = instance.get_typed_func::<(), ()>(&mut store, "f")?;
2350     f.call(&mut store, ())?;
2351 
2352     Ok(())
2353 }
2354