xref: /wasmtime-44.0.1/tests/all/func.rs (revision 071c4061)
1 use std::sync::Arc;
2 use std::sync::atomic::Ordering;
3 use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst};
4 use wasmtime::bail;
5 use wasmtime::*;
6 use wasmtime_test_macros::wasmtime_test;
7 
8 #[wasmtime_test]
9 #[cfg_attr(miri, ignore)]
call_wasm_to_wasm(config: &mut Config) -> Result<()>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)]
call_wasm_to_native(config: &mut Config) -> Result<()>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)]
call_wasm_to_array(config: &mut Config) -> Result<()>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)]
call_native_to_wasm(config: &mut Config) -> Result<()>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]
call_native_to_native() -> Result<()>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)]
call_native_to_array() -> Result<()>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)]
call_array_to_wasm(config: &mut Config) -> Result<()>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]
call_array_to_native() -> Result<()>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)]
call_array_to_array() -> Result<()>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)]
call_indirect_native_from_wasm_import_global(config: &mut Config) -> Result<()>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)]
call_indirect_native_from_wasm_import_table(config: &mut Config) -> Result<()>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)]
call_indirect_native_from_wasm_import_func_returns_funcref(config: &mut Config) -> Result<()>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)]
call_indirect_native_from_exported_table(config: &mut Config) -> Result<()>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)]
call_indirect_native_from_exported_global(config: &mut Config) -> Result<()>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]
func_constructors()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]
dtor_runs()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)]
dtor_delayed() -> Result<()>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]
signatures_match()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)]
import_works() -> Result<()>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)]
trap_smoke() -> Result<()>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)]
trap_import(config: &mut Config) -> Result<()>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]
get_from_wrapper()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)]
get_from_signature()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)]
get_from_module(config: &mut Config) -> wasmtime::Result<()>926 fn get_from_module(config: &mut Config) -> wasmtime::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]
call_wrapped_func() -> Result<()>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)]
caller_memory(config: &mut Config) -> wasmtime::Result<()>999 fn caller_memory(config: &mut Config) -> wasmtime::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)]
func_write_nothing() -> wasmtime::Result<()>1066 fn func_write_nothing() -> wasmtime::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)]
return_cross_store_value(config: &mut Config) -> wasmtime::Result<()>1080 fn return_cross_store_value(config: &mut Config) -> wasmtime::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))]
pass_cross_store_arg(config: &mut Config) -> wasmtime::Result<()>1112 fn pass_cross_store_arg(config: &mut Config) -> wasmtime::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)]
externref_signature_no_reference_types() -> wasmtime::Result<()>1140 fn externref_signature_no_reference_types() -> wasmtime::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)]
trampolines_always_valid(config: &mut Config) -> wasmtime::Result<()>1156 fn trampolines_always_valid(config: &mut Config) -> wasmtime::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)]
typed_multiple_results(config: &mut Config) -> wasmtime::Result<()>1184 fn typed_multiple_results(config: &mut Config) -> wasmtime::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)]
trap_doesnt_leak() -> wasmtime::Result<()>1222 fn trap_doesnt_leak() -> wasmtime::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)]
wrap_multiple_results(config: &mut Config) -> wasmtime::Result<()>1264 fn wrap_multiple_results(config: &mut Config) -> wasmtime::Result<()> {
1265     fn test<T>(store: &mut Store<()>, t: T) -> wasmtime::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, bulk_memory))]
1429 #[cfg_attr(miri, ignore)]
trampoline_for_declared_elem(config: &mut Config) -> wasmtime::Result<()>1430 fn trampoline_for_declared_elem(config: &mut Config) -> wasmtime::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)]
wasm_ty_roundtrip(config: &mut Config) -> Result<(), wasmtime::Error>1458 fn wasm_ty_roundtrip(config: &mut Config) -> Result<(), wasmtime::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)]
typed_funcs_count_params_correctly_in_error_messages( config: &mut Config, ) -> wasmtime::Result<()>1515 fn typed_funcs_count_params_correctly_in_error_messages(
1516     config: &mut Config,
1517 ) -> wasmtime::Result<()> {
1518     let engine = Engine::new(&config)?;
1519     let mut store = Store::<()>::new(&engine, ());
1520     let module = Module::new(
1521         store.engine(),
1522         r#"
1523             (module
1524                 (func (export "f") (param i32 i32))
1525             )
1526 
1527         "#,
1528     )?;
1529     let instance = Instance::new(&mut store, &module, &[])?;
1530 
1531     // Too few parameters.
1532     match instance.get_typed_func::<(), ()>(&mut store, "f") {
1533         Ok(_) => panic!("should be wrong signature"),
1534         Err(e) => {
1535             let msg = format!("{e:?}");
1536             assert!(dbg!(msg).contains("expected 0 types, found 2"))
1537         }
1538     }
1539     match instance.get_typed_func::<(i32,), ()>(&mut store, "f") {
1540         Ok(_) => panic!("should be wrong signature"),
1541         Err(e) => {
1542             let msg = format!("{e:?}");
1543             assert!(dbg!(msg).contains("expected 1 types, found 2"))
1544         }
1545     }
1546 
1547     // Too many parameters.
1548     match instance.get_typed_func::<(i32, i32, i32), ()>(&mut store, "f") {
1549         Ok(_) => panic!("should be wrong signature"),
1550         Err(e) => {
1551             let msg = format!("{e:?}");
1552             assert!(dbg!(msg).contains("expected 3 types, found 2"))
1553         }
1554     }
1555 
1556     Ok(())
1557 }
1558 
1559 #[wasmtime_test(wasm_features(reference_types, gc_types))]
1560 #[cfg_attr(miri, ignore)]
calls_with_funcref_and_externref(config: &mut Config) -> wasmtime::Result<()>1561 fn calls_with_funcref_and_externref(config: &mut Config) -> wasmtime::Result<()> {
1562     let engine = Engine::new(&config)?;
1563     let mut store = Store::<()>::new(&engine, ());
1564     let module = Module::new(
1565         store.engine(),
1566         r#"
1567             (module
1568                 (import "" "witness" (func $witness (param funcref externref)))
1569                 (func (export "f") (param funcref externref) (result externref funcref)
1570                     local.get 0
1571                     local.get 1
1572                     call $witness
1573                     local.get 1
1574                     local.get 0
1575                 )
1576             )
1577 
1578         "#,
1579     )?;
1580     let mut linker = Linker::new(store.engine());
1581     linker.func_wrap(
1582         "",
1583         "witness",
1584         |mut caller: Caller<'_, ()>, func: Option<Func>, externref: Option<Rooted<ExternRef>>| {
1585             if func.is_some() {
1586                 assert_my_funcref(&mut caller, func.as_ref())?;
1587             }
1588             if externref.is_some() {
1589                 assert_my_externref(&caller, externref);
1590             }
1591             Ok(())
1592         },
1593     )?;
1594     let instance = linker.instantiate(&mut store, &module)?;
1595 
1596     let typed = instance
1597         .get_typed_func::<(Option<Func>, Option<Rooted<ExternRef>>), (Option<Rooted<ExternRef>>, Option<Func>)>(
1598             &mut store, "f",
1599         )?;
1600     let untyped = typed.func();
1601 
1602     let my_funcref = Func::wrap(&mut store, || 100u32);
1603     let my_externref = ExternRef::new(&mut store, 99u32)?;
1604     let mut results = [Val::I32(0), Val::I32(0)];
1605 
1606     fn assert_my_funcref(mut store: impl AsContextMut, func: Option<&Func>) -> Result<()> {
1607         let mut store = store.as_context_mut();
1608         let func = func.unwrap();
1609         assert_eq!(func.typed::<(), u32>(&store)?.call(&mut store, ())?, 100);
1610         Ok(())
1611     }
1612     fn assert_my_externref(store: impl AsContext, externref: Option<Rooted<ExternRef>>) {
1613         assert_eq!(
1614             externref
1615                 .unwrap()
1616                 .data(&store)
1617                 .unwrap()
1618                 .unwrap()
1619                 .downcast_ref(),
1620             Some(&99u32)
1621         );
1622     }
1623 
1624     // funcref=null, externref=null
1625     let (a, b) = typed.call(&mut store, (None, None))?;
1626     assert!(a.is_none());
1627     assert!(b.is_none());
1628     untyped.call(
1629         &mut store,
1630         &[Val::FuncRef(None), Val::ExternRef(None)],
1631         &mut results,
1632     )?;
1633     assert!(results[0].unwrap_externref().is_none());
1634     assert!(results[1].unwrap_funcref().is_none());
1635 
1636     // funcref=Some, externref=null
1637     let (a, b) = typed.call(&mut store, (Some(my_funcref), None))?;
1638     assert!(a.is_none());
1639     assert_my_funcref(&mut store, b.as_ref())?;
1640     untyped.call(
1641         &mut store,
1642         &[Val::FuncRef(Some(my_funcref)), Val::ExternRef(None)],
1643         &mut results,
1644     )?;
1645     assert!(results[0].unwrap_externref().is_none());
1646     assert_my_funcref(&mut store, results[1].unwrap_funcref())?;
1647 
1648     // funcref=null, externref=Some
1649     let (a, b) = typed.call(&mut store, (None, Some(my_externref)))?;
1650     assert_my_externref(&store, a);
1651     assert!(b.is_none());
1652     untyped.call(
1653         &mut store,
1654         &[Val::FuncRef(None), Val::ExternRef(Some(my_externref))],
1655         &mut results,
1656     )?;
1657     assert_my_externref(&store, results[0].unwrap_externref().copied());
1658     assert!(results[1].unwrap_funcref().is_none());
1659 
1660     // funcref=Some, externref=Some
1661     let (a, b) = typed.call(&mut store, (Some(my_funcref), Some(my_externref)))?;
1662     assert_my_externref(&store, a);
1663     assert_my_funcref(&mut store, b.as_ref())?;
1664     untyped.call(
1665         &mut store,
1666         &[
1667             Val::FuncRef(Some(my_funcref)),
1668             Val::ExternRef(Some(my_externref)),
1669         ],
1670         &mut results,
1671     )?;
1672     assert_my_externref(&store, results[0].unwrap_externref().copied());
1673     assert_my_funcref(&mut store, results[1].unwrap_funcref())?;
1674 
1675     Ok(())
1676 }
1677 
1678 #[wasmtime_test(wasm_features(function_references, bulk_memory))]
1679 #[cfg_attr(miri, ignore)]
typed_concrete_param(config: &mut Config) -> wasmtime::Result<()>1680 fn typed_concrete_param(config: &mut Config) -> wasmtime::Result<()> {
1681     let engine = Engine::new(&config)?;
1682     let module = Module::new(
1683         &engine,
1684         r#"
1685             (module
1686                 (type $t (func))
1687                 (func (export "f") (param (ref null $t)))
1688             )
1689         "#,
1690     )?;
1691     let mut store = Store::new(&engine, ());
1692     let instance = Instance::new(&mut store, &module, &[])?;
1693 
1694     let nop = Func::new(
1695         &mut store,
1696         FuncType::new(&engine, None, None),
1697         |_caller, _params, _results| Ok(()),
1698     );
1699 
1700     let f = instance.get_func(&mut store, "f").unwrap();
1701 
1702     // Can type with a subtype, which should avoid all dynamic type checks after
1703     // successful construction.
1704     let a = f.typed::<Option<NoFunc>, ()>(&store)?;
1705     a.call(&mut store, None)?;
1706     // NB: Cannot call with Some(_) as `NoFunc` is uninhabited.
1707 
1708     // Can call `typed` with a supertype, falling back to dynamic type checks on
1709     // each call.
1710     let a = f.typed::<Option<Func>, ()>(&store)?;
1711     a.call(&mut store, None)?;
1712     a.call(&mut store, Some(nop))?;
1713     let e = a.call(&mut store, Some(f)).expect_err(
1714         "should return an error because while we did pass an instance of \
1715          `Option<Func>`, it was not an instance of `(ref null $t)`",
1716     );
1717     let e = format!("{e:?}");
1718     assert!(e.contains("argument type mismatch for reference to concrete type"));
1719     assert!(e.contains(
1720         "type mismatch: expected (type (func)), \
1721          found (type (func (param (ref null (concrete func VMSharedTypeIndex(0))))))"
1722     ));
1723 
1724     // And dynamic checks also work with a non-nullable super type.
1725     let a = f.typed::<Func, ()>(&store)?;
1726     a.call(&mut store, nop)?;
1727     let e = a.call(&mut store, f).expect_err(
1728         "should return an error because while we did pass an instance of \
1729          `Func`, it was not an instance of `(ref null $t)`",
1730     );
1731     let e = format!("{e:?}");
1732     assert!(e.contains("argument type mismatch for reference to concrete type"));
1733     assert!(e.contains(
1734         "type mismatch: expected (type (func)), \
1735          found (type (func (param (ref null (concrete func VMSharedTypeIndex(0))))))"
1736     ));
1737 
1738     // Calling `typed` with a type that is not a supertype nor a subtype fails
1739     // the initial type check.
1740     let e = f
1741         .typed::<Option<Rooted<ExternRef>>, ()>(&store)
1742         .err()
1743         .unwrap();
1744     let e = format!("{e:?}");
1745     assert!(e.contains("type mismatch with parameters"));
1746     assert!(e.contains("type mismatch: expected func, found extern"));
1747 
1748     Ok(())
1749 }
1750 
1751 #[wasmtime_test(wasm_features(function_references, bulk_memory))]
1752 #[cfg_attr(miri, ignore)]
typed_concrete_result(config: &mut Config) -> wasmtime::Result<()>1753 fn typed_concrete_result(config: &mut Config) -> wasmtime::Result<()> {
1754     let engine = Engine::new(&config)?;
1755     let module = Module::new(
1756         &engine,
1757         r#"
1758             (module
1759                 (type $t (func))
1760                 (func $nop)
1761                 (elem declare func $nop)
1762                 (func (export "f") (result (ref $t))
1763                     ref.func $nop
1764                 )
1765             )
1766         "#,
1767     )?;
1768     let mut store = Store::new(&engine, ());
1769     let instance = Instance::new(&mut store, &module, &[])?;
1770 
1771     let f = instance.get_func(&mut store, "f").unwrap();
1772 
1773     // Can type `f` with a supertype of the declared result type, and we get the
1774     // expected return value.
1775     let a = f.typed::<(), Func>(&store)?;
1776     let g = a.call(&mut store, ())?;
1777     g.typed::<(), ()>(&store)?.call(&mut store, ())?;
1778 
1779     // Also works with a nullable supertype.
1780     let a = f.typed::<(), Option<Func>>(&store)?;
1781     let g = a.call(&mut store, ())?;
1782     g.unwrap().typed::<(), ()>(&store)?.call(&mut store, ())?;
1783 
1784     // But we can't claim that `f` returns a particular subtype of its actual
1785     // return type.
1786     let e = f.typed::<(), NoFunc>(&store).err().unwrap();
1787     let e = format!("{e:?}");
1788     assert!(e.contains("type mismatch with results"));
1789     assert!(e.contains(
1790         "type mismatch: expected (ref nofunc), found (ref (concrete func VMSharedTypeIndex(0)))"
1791     ));
1792 
1793     // Nor some unrelated type that it is neither a subtype or supertype of.
1794     let e = f.typed::<(), Rooted<ExternRef>>(&store).err().unwrap();
1795     let e = format!("{e:?}");
1796     assert!(e.contains("type mismatch with results"));
1797     assert!(e.contains(
1798         "type mismatch: expected (ref extern), found (ref (concrete func VMSharedTypeIndex(0)))"
1799     ));
1800 
1801     Ok(())
1802 }
1803 
1804 #[test]
1805 #[cfg_attr(miri, ignore)]
wrap_subtype_param() -> wasmtime::Result<()>1806 fn wrap_subtype_param() -> wasmtime::Result<()> {
1807     let mut store = Store::<()>::default();
1808     let f = Func::wrap(&mut store, |_caller: Caller<'_, ()>, _: Option<Func>| {
1809         // No-op.
1810     });
1811 
1812     // Precise type.
1813     let a = f.typed::<Option<Func>, ()>(&store)?;
1814     a.call(&mut store, None)?;
1815     a.call(&mut store, Some(f))?;
1816 
1817     // Subtype via heap type.
1818     let a = f.typed::<Option<NoFunc>, ()>(&store)?;
1819     a.call(&mut store, None)?;
1820 
1821     // Subtype via non-null.
1822     let a = f.typed::<Func, ()>(&store)?;
1823     a.call(&mut store, f)?;
1824 
1825     Ok(())
1826 }
1827 
1828 #[test]
1829 #[cfg_attr(miri, ignore)]
wrap_supertype_result() -> wasmtime::Result<()>1830 fn wrap_supertype_result() -> wasmtime::Result<()> {
1831     let mut store = Store::<()>::default();
1832     let f = Func::wrap(&mut store, |_caller: Caller<'_, ()>| -> NoFunc {
1833         unreachable!()
1834     });
1835 
1836     // Precise type.
1837     let _ = f.typed::<(), NoFunc>(&store)?;
1838 
1839     // Supertype via heap type.
1840     let _ = f.typed::<(), Func>(&store)?;
1841 
1842     // Supertype via nullability.
1843     let _ = f.typed::<(), Option<NoFunc>>(&store)?;
1844 
1845     Ok(())
1846 }
1847 
1848 #[wasmtime_test(wasm_features(function_references))]
1849 #[cfg_attr(miri, ignore)]
call_wasm_passing_subtype_func_param(config: &mut Config) -> wasmtime::Result<()>1850 fn call_wasm_passing_subtype_func_param(config: &mut Config) -> wasmtime::Result<()> {
1851     config.wasm_function_references(true);
1852     let engine = Engine::new(&config)?;
1853     let mut store = Store::new(&engine, ());
1854 
1855     let module = Module::new(
1856         &engine,
1857         r#"
1858             (module
1859                 (type $ty (func (result funcref)))
1860                 (func (export "f") (param (ref null $ty)) (result funcref)
1861                     ;; Return null if the funcref is null.
1862                     ref.null func
1863                     local.get 0
1864                     ref.is_null
1865                     br_if 0
1866                     drop
1867 
1868                     ;; Otherwise, call it.
1869                     local.get 0
1870                     call_ref $ty
1871                 )
1872             )
1873         "#,
1874     )?;
1875 
1876     let instance = Instance::new(&mut store, &module, &[])?;
1877     let f = instance.get_func(&mut store, "f").unwrap();
1878 
1879     let g_ty = FuncType::new(&engine, None, Some(ValType::I32));
1880     let g = Func::new(&mut store, g_ty.clone(), |_caller, _params, results| {
1881         results[0] = Val::I32(0x1234_5678);
1882         Ok(())
1883     });
1884 
1885     // h's type is a subtype of the Wasm-defined `$ty`:
1886     //
1887     //     (func (result (ref null g_ty))) <: (func (result funcref))
1888     let h_ty = FuncType::new(
1889         &engine,
1890         None,
1891         Some(ValType::Ref(RefType::new(
1892             true,
1893             HeapType::ConcreteFunc(g_ty),
1894         ))),
1895     );
1896     let h = Func::new(&mut store, h_ty, move |_caller, _params, results| {
1897         results[0] = Val::FuncRef(Some(g));
1898         Ok(())
1899     });
1900 
1901     // Array call, passing in a subtype of the expected parameter.
1902 
1903     let mut results = vec![Val::I32(0)];
1904     f.call(&mut store, &[Val::null_func_ref()], &mut results)?;
1905     assert!(results[0].unwrap_func_ref().is_none());
1906 
1907     f.call(&mut store, &[h.into()], &mut results)?;
1908     let g = results[0];
1909     let g = g.unwrap_func_ref().unwrap();
1910     g.call(&mut store, &[], &mut results)?;
1911     assert_eq!(results[0].unwrap_i32(), 0x1234_5678);
1912 
1913     // Native call, passing in a subtype of the expected parameter.
1914 
1915     let f = f.typed::<Option<Func>, Option<Func>>(&store)?;
1916     let r = f.call(&mut store, None)?;
1917     assert!(r.is_none());
1918 
1919     let g = f.call(&mut store, Some(h))?;
1920     let g = g.unwrap().typed::<(), u32>(&mut store)?;
1921     let x = g.call(&mut store, ())?;
1922     assert_eq!(x, 0x1234_5678);
1923 
1924     Ok(())
1925 }
1926 
1927 #[wasmtime_test(wasm_features(gc, function_references, bulk_memory))]
1928 #[cfg_attr(miri, ignore)]
call_wasm_getting_subtype_func_return(config: &mut Config) -> wasmtime::Result<()>1929 fn call_wasm_getting_subtype_func_return(config: &mut Config) -> wasmtime::Result<()> {
1930     let engine = Engine::new(&config)?;
1931     let mut store = Store::new(&engine, ());
1932 
1933     let module = Module::new(
1934         &engine,
1935         r#"
1936             (module
1937                 (type $ty (func (result funcref)))
1938 
1939                 (func $a (result i32)
1940                     i32.const 0x12345678
1941                 )
1942 
1943                 (func $b (result funcref)
1944                     ref.func $a
1945                 )
1946 
1947                 (elem declare func $a $b)
1948 
1949                 ;; Returns a `(ref null nofunc)` if called with `0`, otherwise
1950                 ;; returns `(ref null $ty)`, both of which are subtypes of
1951                 ;; `funcref`.
1952                 (func (export "f") (param i32) (result funcref)
1953                     block
1954                         local.get 0
1955                         br_if 0
1956                         ref.null nofunc
1957                         return
1958                     end
1959                     ref.func $b
1960                 )
1961             )
1962         "#,
1963     )?;
1964 
1965     let instance = Instance::new(&mut store, &module, &[])?;
1966     let f = instance.get_func(&mut store, "f").unwrap();
1967 
1968     // Array call, receiving a subtype of the expected result.
1969 
1970     let mut results = vec![Val::I32(0)];
1971     f.call(&mut store, &[Val::I32(0)], &mut results)?;
1972     assert!(results[0].unwrap_func_ref().is_none());
1973 
1974     f.call(&mut store, &[Val::I32(1)], &mut results)?;
1975     let b = results[0];
1976     let b = b.unwrap_func_ref().unwrap();
1977     b.call(&mut store, &[], &mut results)?;
1978     let a = results[0];
1979     let a = a.unwrap_func_ref().unwrap();
1980     a.call(&mut store, &[], &mut results)?;
1981     assert_eq!(results[0].unwrap_i32(), 0x1234_5678);
1982 
1983     // Native call, receiving a subtype of the expected result.
1984 
1985     let f = f.typed::<u32, Option<Func>>(&store)?;
1986     let r = f.call(&mut store, 0)?;
1987     assert!(r.is_none());
1988 
1989     let b = f.call(&mut store, 1)?;
1990     let b = b.unwrap().typed::<(), Option<Func>>(&store)?;
1991     let a = b.call(&mut store, ())?;
1992     let a = a.unwrap().typed::<(), u32>(&store)?;
1993     let x = a.call(&mut store, ())?;
1994     assert_eq!(x, 0x1234_5678);
1995 
1996     Ok(())
1997 }
1998 
1999 #[wasmtime_test(wasm_features(simd), strategies(not(Winch)))]
2000 #[cfg_attr(miri, ignore)]
typed_v128(config: &mut Config) -> wasmtime::Result<()>2001 fn typed_v128(config: &mut Config) -> wasmtime::Result<()> {
2002     let engine = Engine::new(&config)?;
2003     let mut store = Store::<()>::new(&engine, ());
2004     let module = Module::new(
2005         store.engine(),
2006         r#"
2007             (module
2008                 (func (export "a") (param v128) (result v128)
2009                     local.get 0)
2010                 (func (export "b") (param v128 v128) (result v128 v128)
2011                     local.get 0
2012                     local.get 1)
2013                 (func (export "c") (param v128 v128 v128 v128 v128 v128 v128 v128) (result v128)
2014                     local.get 0
2015                     local.get 1
2016                     local.get 2
2017                     local.get 3
2018                     local.get 4
2019                     local.get 5
2020                     local.get 6
2021                     local.get 7
2022                     i64x2.add
2023                     i64x2.add
2024                     i64x2.add
2025                     i64x2.add
2026                     i64x2.add
2027                     i64x2.add
2028                     i64x2.add)
2029             )
2030 
2031         "#,
2032     )?;
2033     let instance = Instance::new(&mut store, &module, &[])?;
2034 
2035     let a = instance.get_typed_func::<V128, V128>(&mut store, "a")?;
2036     assert_eq!(a.call(&mut store, V128::from(1))?, V128::from(1));
2037     assert_eq!(a.call(&mut store, V128::from(2))?, V128::from(2));
2038 
2039     let b = instance.get_typed_func::<(V128, V128), (V128, V128)>(&mut store, "b")?;
2040     assert_eq!(
2041         b.call(&mut store, (V128::from(1), V128::from(2)))?,
2042         (V128::from(1), V128::from(2))
2043     );
2044 
2045     let c = instance.get_typed_func::<(V128, V128, V128, V128, V128, V128, V128, V128), V128>(
2046         &mut store, "c",
2047     )?;
2048     assert_eq!(
2049         c.call(
2050             &mut store,
2051             (
2052                 V128::from(1),
2053                 V128::from(2),
2054                 V128::from(3),
2055                 V128::from(4),
2056                 V128::from(5),
2057                 V128::from(6),
2058                 V128::from(7),
2059                 V128::from(8),
2060             )
2061         )?,
2062         V128::from(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8),
2063     );
2064 
2065     Ok(())
2066 }
2067 
2068 #[wasmtime_test(wasm_features(simd))]
2069 #[cfg_attr(miri, ignore)]
typed_v128_imports(config: &mut Config) -> wasmtime::Result<()>2070 fn typed_v128_imports(config: &mut Config) -> wasmtime::Result<()> {
2071     let engine = Engine::new(&config)?;
2072     let mut store = Store::<()>::new(&engine, ());
2073     let module = Module::new(
2074         store.engine(),
2075         r#"
2076             (module
2077                 (import "" "a" (func $a (param v128) (result i32)))
2078                 (import "" "b" (func $b (param i32) (result v128)))
2079                 (import "" "c" (func $c (param v128 f64 v128) (result v128 i32 v128)))
2080                 (import "" "d" (func $d (param v128 v128 v128 v128 v128 v128 v128 v128) (result i32)))
2081 
2082                 (func (export "a") (param v128) (result i32)
2083                     local.get 0
2084                     call $a)
2085 
2086                 (func (export "b") (param i32) (result v128)
2087                     local.get 0
2088                     call $b)
2089 
2090                 (func (export "c") (param v128 f64 v128) (result v128 i32 v128)
2091                     local.get 0
2092                     local.get 1
2093                     local.get 2
2094                     call $c)
2095 
2096                 (func (export "d") (param v128 v128 v128 v128 v128 v128 v128 v128) (result i32)
2097                     local.get 0
2098                     local.get 1
2099                     local.get 2
2100                     local.get 3
2101                     local.get 4
2102                     local.get 5
2103                     local.get 6
2104                     local.get 7
2105                     call $d)
2106             )
2107 
2108         "#,
2109     )?;
2110 
2111     let mut l = Linker::new(store.engine());
2112     l.func_wrap("", "a", |x: V128| {
2113         let x = x.as_u128();
2114         (x >> 0) as u32 + (x >> 32) as u32 + (x >> 64) as u32 + (x >> 96) as u32
2115     })?;
2116     l.func_wrap("", "b", |x: u32| {
2117         let x = u128::from(x);
2118         V128::from(x | ((x + 1) << 32) | ((x + 2) << 64) | ((x + 3) << 96))
2119     })?;
2120     l.func_wrap("", "c", |x: V128, y: f64, z: V128| (x, y as i32, z))?;
2121     l.func_wrap(
2122         "",
2123         "d",
2124         |a0: V128, a1: V128, a2: V128, a3: V128, a4: V128, a5: V128, a6: V128, a7: V128| {
2125             let tmp = a0.as_u128()
2126                 + a1.as_u128()
2127                 + a2.as_u128()
2128                 + a3.as_u128()
2129                 + a4.as_u128()
2130                 + a5.as_u128()
2131                 + a6.as_u128()
2132                 + a7.as_u128();
2133             (tmp >> 0) as u32 + (tmp >> 32) as u32 + (tmp >> 64) as u32 + (tmp >> 96) as u32
2134         },
2135     )?;
2136 
2137     let i = l.instantiate(&mut store, &module)?;
2138     let a = i.get_typed_func::<V128, i32>(&mut store, "a")?;
2139     let b = i.get_typed_func::<i32, V128>(&mut store, "b")?;
2140     let c = i.get_typed_func::<(V128, f64, V128), (V128, i32, V128)>(&mut store, "c")?;
2141     let d =
2142         i.get_typed_func::<(V128, V128, V128, V128, V128, V128, V128, V128), i32>(&mut store, "d")?;
2143 
2144     assert_eq!(
2145         a.call(&mut store, 0x00000004_00000003_00000002_00000001.into())?,
2146         1 + 2 + 3 + 4
2147     );
2148     assert_eq!(
2149         b.call(&mut store, 0x10)?,
2150         V128::from(0x00000013_00000012_00000011_00000010),
2151     );
2152     assert_eq!(
2153         c.call(&mut store, (1.into(), 2., 3.into()))?,
2154         (V128::from(1), 2, V128::from(3)),
2155     );
2156     assert_eq!(
2157         d.call(
2158             &mut store,
2159             (
2160                 1.into(),
2161                 2.into(),
2162                 3.into(),
2163                 4.into(),
2164                 5.into(),
2165                 6.into(),
2166                 7.into(),
2167                 8.into(),
2168             )
2169         )?,
2170         1 + 2 + 3 + 4 + 5 + 6 + 7 + 8
2171     );
2172 
2173     Ok(())
2174 }
2175 
2176 #[wasmtime_test(wasm_features(function_references, gc))]
2177 #[cfg_attr(miri, ignore)]
wrap_and_typed_i31ref(config: &mut Config) -> Result<()>2178 fn wrap_and_typed_i31ref(config: &mut Config) -> Result<()> {
2179     let engine = Engine::new(&config)?;
2180     let mut store = Store::<AtomicUsize>::new(&engine, AtomicUsize::new(0));
2181 
2182     let mut linker = Linker::new(&engine);
2183     linker.func_wrap(
2184         "env",
2185         "i31ref",
2186         |caller: Caller<'_, AtomicUsize>, x: Option<I31>| -> Option<I31> {
2187             assert_eq!(caller.data().fetch_add(1, Ordering::SeqCst), 0);
2188             x
2189         },
2190     )?;
2191     linker.func_wrap(
2192         "env",
2193         "ref-i31",
2194         |caller: Caller<'_, AtomicUsize>, x: I31| -> I31 {
2195             assert_eq!(caller.data().fetch_add(1, Ordering::SeqCst), 1);
2196             x
2197         },
2198     )?;
2199 
2200     let module = Module::new(
2201         &engine,
2202         r#"
2203             (module
2204                 (import "env" "i31ref" (func (param i31ref) (result i31ref)))
2205                 (import "env" "ref-i31" (func (param (ref i31)) (result (ref i31))))
2206 
2207                 (func (export "i31ref") (param i31ref) (result i31ref)
2208                     local.get 0
2209                     call 0
2210                 )
2211 
2212                 (func (export "ref-i31") (param (ref i31)) (result (ref i31))
2213                     local.get 0
2214                     call 1
2215                 )
2216             )
2217         "#,
2218     )?;
2219 
2220     let instance = linker.instantiate(&mut store, &module)?;
2221 
2222     let i31ref = instance.get_typed_func::<Option<I31>, Option<I31>>(&mut store, "i31ref")?;
2223     let x = i31ref.call(&mut store, Some(I31::wrapping_u32(42)))?;
2224     assert_eq!(x, Some(I31::wrapping_u32(42)));
2225 
2226     let ref_i31 = instance.get_typed_func::<I31, I31>(&mut store, "ref-i31")?;
2227     let x = ref_i31.call(&mut store, I31::wrapping_u32(0x1234))?;
2228     assert_eq!(x, I31::wrapping_u32(0x1234));
2229 
2230     assert_eq!(store.data().load(Ordering::SeqCst), 2);
2231     Ok(())
2232 }
2233 
2234 #[wasmtime_test(wasm_features(function_references, gc))]
call_func_with_funcref_both_typed_and_untyped(config: &mut Config) -> Result<()>2235 fn call_func_with_funcref_both_typed_and_untyped(config: &mut Config) -> Result<()> {
2236     let engine = Engine::new(&config)?;
2237     let mut store = Store::new(&engine, ());
2238 
2239     let f1 = Func::wrap(&mut store, |_: Option<Func>| {});
2240     let f2 = Func::wrap(&mut store, || {});
2241 
2242     f1.typed::<Func, ()>(&mut store)?.call(&mut store, f2)?;
2243     f1.call(&mut store, &[Val::FuncRef(Some(f2))], &mut [])?;
2244     Ok(())
2245 }
2246 
2247 #[wasmtime_test(wasm_features(function_references, gc))]
2248 #[cfg_attr(miri, ignore)]
wasm_to_host_trampolines_and_subtyping(config: &mut Config) -> Result<()>2249 fn wasm_to_host_trampolines_and_subtyping(config: &mut Config) -> Result<()> {
2250     let _ = env_logger::try_init();
2251 
2252     let engine = Engine::new(&config)?;
2253 
2254     let ft0 = FuncType::with_finality_and_supertype(
2255         &engine,
2256         Finality::NonFinal,
2257         None,
2258         [],
2259         [ValType::Ref(RefType::new(true, HeapType::Extern))],
2260     )?;
2261     let ft1 = FuncType::with_finality_and_supertype(
2262         &engine,
2263         Finality::NonFinal,
2264         Some(&ft0),
2265         [],
2266         [ValType::Ref(RefType::new(false, HeapType::Extern))],
2267     )?;
2268 
2269     let module = Module::new(
2270         &engine,
2271         r#"
2272             (module
2273                 (type $ft0 (sub (func (result (ref null extern)))))
2274 
2275                 (import "" "a" (func $imported_func (type $ft0)))
2276                 (import "" "return_func" (func $return_func (result (ref $ft0))))
2277                 (global $g (export "g") (mut (ref null $ft0)) (ref.null $ft0))
2278                 (table $t (export "t") 10 10 (ref null $ft0))
2279 
2280                 (func (export "f")
2281                     (drop (call $imported_func))
2282                     (drop (call_ref $ft0 (call $return_func)))
2283                     (drop (call_ref $ft0 (global.get $g)))
2284                     (drop (call_ref $ft0 (table.get $t (i32.const 0))))
2285                 )
2286             )
2287         "#,
2288     )?;
2289 
2290     // This defines a function of type `(func (result (ref extern)))` and not of
2291     // type `(func (result (ref null extern)))` that the Wasm imports. But it is
2292     // still a subtype of the Wasm import's type, so we should be able to use
2293     // the Wasm's precompiled trampolines with this host function.
2294     //
2295     // But this means we also need to look up the trampoline by the caller's
2296     // type, rather than the callee's type.
2297     //
2298     // So give it to Wasm in every way that Wasm can receive a function, and
2299     // make sure we find the correct trampolines in all cases and everything
2300     // works.
2301     let make_func = |store: &mut Store<_>| {
2302         Func::new(
2303             store,
2304             ft1.clone(),
2305             |mut caller: Caller<'_, ()>, _args, results| {
2306                 results[0] = ExternRef::new(&mut caller, 200)?.into();
2307                 Ok(())
2308             },
2309         )
2310     };
2311 
2312     let return_func_ty = module.imports().nth(1).unwrap().ty().unwrap_func().clone();
2313 
2314     let mut store = Store::new(&engine, ());
2315 
2316     let imported_func = make_func(&mut store);
2317     assert!(FuncType::eq(&imported_func.ty(&store), &ft1));
2318 
2319     let returned_func = make_func(&mut store);
2320     assert!(FuncType::eq(&returned_func.ty(&store), &ft1));
2321 
2322     let return_func = Func::new(
2323         &mut store,
2324         return_func_ty.clone(),
2325         move |_caller, _args, results| {
2326             results[0] = returned_func.into();
2327             Ok(())
2328         },
2329     );
2330 
2331     let instance = Instance::new(
2332         &mut store,
2333         &module,
2334         &[imported_func.into(), return_func.into()],
2335     )?;
2336 
2337     let g = make_func(&mut store);
2338     assert!(FuncType::eq(&g.ty(&store), &ft1));
2339     instance
2340         .get_global(&mut store, "g")
2341         .unwrap()
2342         .set(&mut store, g.into())?;
2343 
2344     let t = make_func(&mut store);
2345     assert!(FuncType::eq(&t.ty(&store), &ft1));
2346     instance
2347         .get_table(&mut store, "t")
2348         .unwrap()
2349         .set(&mut store, 0, t.into())?;
2350 
2351     let f = instance.get_typed_func::<(), ()>(&mut store, "f")?;
2352     f.call(&mut store, ())?;
2353 
2354     Ok(())
2355 }
2356