1 #![cfg(not(miri))]
2 
3 use super::{Param, Type, make_echo_component, make_echo_component_with_params};
4 use wasmtime::Result;
5 use wasmtime::component::types::{self, Case, ComponentItem, Field};
6 use wasmtime::component::{Component, Linker, ResourceType, Val};
7 use wasmtime::{Module, Store};
8 use wasmtime_component_util::REALLOC_AND_FREE;
9 
10 #[test]
primitives() -> Result<()>11 fn primitives() -> Result<()> {
12     let engine = super::engine();
13     let mut store = Store::new(&engine, ());
14     let mut output = [Val::Bool(false)];
15 
16     for (input, ty, param) in [
17         (Val::Bool(true), "bool", Param(Type::U8, Some(0))),
18         (Val::S8(-42), "s8", Param(Type::S8, Some(0))),
19         (Val::U8(42), "u8", Param(Type::U8, Some(0))),
20         (Val::S16(-4242), "s16", Param(Type::S16, Some(0))),
21         (Val::U16(4242), "u16", Param(Type::U16, Some(0))),
22         (Val::S32(-314159265), "s32", Param(Type::I32, Some(0))),
23         (Val::U32(314159265), "u32", Param(Type::I32, Some(0))),
24         (Val::S64(-31415926535897), "s64", Param(Type::I64, Some(0))),
25         (Val::U64(31415926535897), "u64", Param(Type::I64, Some(0))),
26         (
27             Val::Float32(3.14159265),
28             "float32",
29             Param(Type::F32, Some(0)),
30         ),
31         (
32             Val::Float64(3.14159265),
33             "float64",
34             Param(Type::F64, Some(0)),
35         ),
36         (Val::Char('��'), "char", Param(Type::I32, Some(0))),
37     ] {
38         let component = Component::new(&engine, make_echo_component_with_params(ty, &[param]))?;
39         let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
40         let func = instance.get_func(&mut store, "echo").unwrap();
41         func.call(&mut store, &[input.clone()], &mut output)?;
42 
43         assert_eq!(input, output[0]);
44     }
45 
46     // Sad path: type mismatch
47 
48     let component = Component::new(
49         &engine,
50         make_echo_component_with_params("float64", &[Param(Type::F64, Some(0))]),
51     )?;
52     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
53     let func = instance.get_func(&mut store, "echo").unwrap();
54     let err = func
55         .call(&mut store, &[Val::U64(42)], &mut output)
56         .unwrap_err();
57 
58     assert!(err.to_string().contains("type mismatch"), "{err}");
59 
60     // Sad path: arity mismatch (too many)
61 
62     let err = func
63         .call(
64             &mut store,
65             &[Val::Float64(3.14159265), Val::Float64(3.14159265)],
66             &mut output,
67         )
68         .unwrap_err();
69 
70     assert!(
71         err.to_string().contains("expected 1 argument(s), got 2"),
72         "{err}"
73     );
74 
75     // Sad path: arity mismatch (too few)
76 
77     let err = func.call(&mut store, &[], &mut output).unwrap_err();
78     assert!(
79         err.to_string().contains("expected 1 argument(s), got 0"),
80         "{err}"
81     );
82 
83     let err = func.call(&mut store, &output, &mut []).unwrap_err();
84     assert!(
85         err.to_string().contains("expected 1 result(s), got 0"),
86         "{err}"
87     );
88 
89     Ok(())
90 }
91 
92 #[test]
strings() -> Result<()>93 fn strings() -> Result<()> {
94     let engine = super::engine();
95     let mut store = Store::new(&engine, ());
96 
97     let component = Component::new(&engine, make_echo_component("string", 8))?;
98     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
99     let func = instance.get_func(&mut store, "echo").unwrap();
100     let input = Val::String("hello, component!".into());
101     let mut output = [Val::Bool(false)];
102     func.call(&mut store, &[input.clone()], &mut output)?;
103     assert_eq!(input, output[0]);
104 
105     Ok(())
106 }
107 
108 #[test]
lists() -> Result<()>109 fn lists() -> Result<()> {
110     let engine = super::engine();
111     let mut store = Store::new(&engine, ());
112 
113     let component = Component::new(&engine, make_echo_component("(list u32)", 8))?;
114     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
115     let func = instance.get_func(&mut store, "echo").unwrap();
116     let input = Val::List(vec![
117         Val::U32(32343),
118         Val::U32(79023439),
119         Val::U32(2084037802),
120     ]);
121     let mut output = [Val::Bool(false)];
122     func.call(&mut store, &[input.clone()], &mut output)?;
123 
124     assert_eq!(input, output[0]);
125 
126     // Sad path: type mismatch
127 
128     let err = Val::List(vec![
129         Val::U32(32343),
130         Val::U32(79023439),
131         Val::Float32(3.14159265),
132     ]);
133     let err = func.call(&mut store, &[err], &mut output).unwrap_err();
134     assert!(err.to_string().contains("type mismatch"), "{err}");
135 
136     Ok(())
137 }
138 
139 #[test]
maps() -> Result<()>140 fn maps() -> Result<()> {
141     let engine = super::map_engine();
142     let mut store = Store::new(&engine, ());
143 
144     let component = Component::new(&engine, make_echo_component("(map u32 string)", 8))?;
145     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
146     let func = instance.get_func(&mut store, "echo").unwrap();
147 
148     let input_map = vec![
149         (Val::U32(1), Val::String("one".into())),
150         (Val::U32(2), Val::String("two".into())),
151         (Val::U32(3), Val::String("three".into())),
152     ];
153     let input = Val::Map(input_map);
154 
155     let mut output = [Val::Bool(false)];
156     func.call(&mut store, &[input.clone()], &mut output)?;
157 
158     // Maps should round-trip correctly
159     match &output[0] {
160         Val::Map(output_map) => {
161             assert_eq!(output_map.len(), 3);
162             assert!(
163                 output_map
164                     .iter()
165                     .any(|(k, v)| *k == Val::U32(1) && *v == Val::String("one".into()))
166             );
167             assert!(
168                 output_map
169                     .iter()
170                     .any(|(k, v)| *k == Val::U32(2) && *v == Val::String("two".into()))
171             );
172             assert!(
173                 output_map
174                     .iter()
175                     .any(|(k, v)| *k == Val::U32(3) && *v == Val::String("three".into()))
176             );
177         }
178         _ => panic!("expected map"),
179     }
180 
181     // Sad path: type mismatch (wrong key type)
182     // Need to create a fresh instance because errors can leave the instance in a bad state
183     let mut store2 = Store::new(&engine, ());
184     let instance2 = Linker::new(&engine).instantiate(&mut store2, &component)?;
185     let func2 = instance2.get_func(&mut store2, "echo").unwrap();
186 
187     let err_map = vec![(Val::String("key".into()), Val::String("value".into()))];
188     let err = Val::Map(err_map);
189     let err = func2.call(&mut store2, &[err], &mut output).unwrap_err();
190     assert!(err.to_string().contains("type mismatch"), "{err}");
191 
192     // Sad path: type mismatch (wrong value type)
193     let mut store3 = Store::new(&engine, ());
194     let instance3 = Linker::new(&engine).instantiate(&mut store3, &component)?;
195     let func3 = instance3.get_func(&mut store3, "echo").unwrap();
196 
197     let err_map2 = vec![(Val::U32(1), Val::U32(42))];
198     let err = Val::Map(err_map2);
199     let err = func3.call(&mut store3, &[err], &mut output).unwrap_err();
200     assert!(err.to_string().contains("type mismatch"), "{err}");
201 
202     // Test empty map
203     let empty_map = vec![];
204     let input = Val::Map(empty_map);
205     func.call(&mut store, &[input.clone()], &mut output)?;
206     match &output[0] {
207         Val::Map(output_map) => assert_eq!(output_map.len(), 0),
208         _ => panic!("expected map"),
209     }
210 
211     Ok(())
212 }
213 
214 #[test]
maps_complex_types() -> Result<()>215 fn maps_complex_types() -> Result<()> {
216     let engine = super::map_engine();
217     let mut store = Store::new(&engine, ());
218 
219     // Test map<string, list<u32>>
220     let component = Component::new(&engine, make_echo_component("(map string (list u32))", 8))?;
221     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
222     let func = instance.get_func(&mut store, "echo").unwrap();
223 
224     let input_map = vec![
225         (
226             Val::String("first".into()),
227             Val::List(vec![Val::U32(1), Val::U32(2), Val::U32(3)]),
228         ),
229         (
230             Val::String("second".into()),
231             Val::List(vec![Val::U32(4), Val::U32(5)]),
232         ),
233     ];
234     let input = Val::Map(input_map);
235 
236     let mut output = [Val::Bool(false)];
237     func.call(&mut store, &[input.clone()], &mut output)?;
238 
239     // Verify round-trip
240     match &output[0] {
241         Val::Map(output_map) => {
242             assert_eq!(output_map.len(), 2);
243             // Check first entry
244             let first_entry = output_map
245                 .iter()
246                 .find(|(k, _)| *k == Val::String("first".into()));
247             match first_entry {
248                 Some((_, Val::List(list))) => {
249                     assert_eq!(list.len(), 3);
250                     assert_eq!(list[0], Val::U32(1));
251                     assert_eq!(list[1], Val::U32(2));
252                     assert_eq!(list[2], Val::U32(3));
253                 }
254                 _ => panic!("expected list"),
255             }
256             // Check second entry
257             let second_entry = output_map
258                 .iter()
259                 .find(|(k, _)| *k == Val::String("second".into()));
260             match second_entry {
261                 Some((_, Val::List(list))) => {
262                     assert_eq!(list.len(), 2);
263                     assert_eq!(list[0], Val::U32(4));
264                     assert_eq!(list[1], Val::U32(5));
265                 }
266                 _ => panic!("expected list"),
267             }
268         }
269         _ => panic!("expected map"),
270     }
271 
272     Ok(())
273 }
274 
275 #[test]
maps_equality() -> Result<()>276 fn maps_equality() -> Result<()> {
277     let map1 = vec![
278         (Val::U32(1), Val::String("one".into())),
279         (Val::U32(2), Val::String("two".into())),
280     ];
281 
282     let map2 = vec![
283         (Val::U32(1), Val::String("one".into())),
284         (Val::U32(2), Val::String("two".into())),
285     ];
286 
287     // Maps with same content in same order should be equal
288     assert_eq!(Val::Map(map1.clone()), Val::Map(map2));
289 
290     // Different values should not be equal
291     let map3 = vec![
292         (Val::U32(1), Val::String("different".into())),
293         (Val::U32(2), Val::String("two".into())),
294     ];
295     assert_ne!(Val::Map(map1.clone()), Val::Map(map3));
296 
297     // Different keys should not be equal
298     let map4 = vec![
299         (Val::U32(3), Val::String("one".into())),
300         (Val::U32(2), Val::String("two".into())),
301     ];
302     assert_ne!(Val::Map(map1), Val::Map(map4));
303 
304     // Empty maps should be equal
305     let empty1: Vec<(Val, Val)> = vec![];
306     let empty2: Vec<(Val, Val)> = vec![];
307     assert_eq!(Val::Map(empty1), Val::Map(empty2));
308 
309     Ok(())
310 }
311 
312 #[test]
maps_duplicate_keys() -> Result<()>313 fn maps_duplicate_keys() -> Result<()> {
314     let engine = super::map_engine();
315     let mut store = Store::new(&engine, ());
316 
317     let component = Component::new(&engine, make_echo_component("(map u32 string)", 8))?;
318     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
319     let func = instance.get_func(&mut store, "echo").unwrap();
320 
321     // Create a map with duplicate keys - Vec preserves all entries
322     let input_map = vec![
323         (Val::U32(1), Val::String("first".into())),
324         (Val::U32(1), Val::String("last".into())), // Duplicate key
325         (Val::U32(2), Val::String("two".into())),
326     ];
327     let input = Val::Map(input_map);
328 
329     let mut output = [Val::Bool(false)];
330     func.call(&mut store, &[input.clone()], &mut output)?;
331 
332     // Verify all entries are preserved (Vec doesn't deduplicate)
333     match &output[0] {
334         Val::Map(output_map) => {
335             // Should have 3 entries (Vec preserves duplicates)
336             assert_eq!(output_map.len(), 3);
337         }
338         _ => panic!("expected map"),
339     }
340 
341     Ok(())
342 }
343 
344 #[test]
maps_all_primitive_types() -> Result<()>345 fn maps_all_primitive_types() -> Result<()> {
346     let engine = super::map_engine();
347     let mut store = Store::new(&engine, ());
348 
349     // Test map<u32, u32>
350     let component = Component::new(&engine, make_echo_component("(map u32 u32)", 8))?;
351     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
352     let func = instance.get_func(&mut store, "echo").unwrap();
353 
354     let input_map = vec![(Val::U32(1), Val::U32(100)), (Val::U32(2), Val::U32(200))];
355     let input = Val::Map(input_map);
356 
357     let mut output = [Val::Bool(false)];
358     func.call(&mut store, &[input.clone()], &mut output)?;
359     assert_eq!(input, output[0]);
360 
361     // Test map<string, u32>
362     let component = Component::new(&engine, make_echo_component("(map string u32)", 8))?;
363     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
364     let func = instance.get_func(&mut store, "echo").unwrap();
365 
366     let input_map = vec![
367         (Val::String("one".into()), Val::U32(1)),
368         (Val::String("two".into()), Val::U32(2)),
369     ];
370     let input = Val::Map(input_map);
371 
372     func.call(&mut store, &[input.clone()], &mut output)?;
373     assert_eq!(input, output[0]);
374 
375     Ok(())
376 }
377 
378 #[test]
maps_alignment() -> Result<()>379 fn maps_alignment() -> Result<()> {
380     let engine = super::map_engine();
381     let mut store = Store::new(&engine, ());
382 
383     // Test map<u8, u64> - key_size=1, value_align=8
384     // This would fail with the alignment bug because value would be at offset 1 instead of 8
385     let component = Component::new(&engine, make_echo_component("(map u8 u64)", 8))?;
386     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
387     let func = instance.get_func(&mut store, "echo").unwrap();
388 
389     let input_map = vec![
390         (Val::U8(1), Val::U64(100)),
391         (Val::U8(2), Val::U64(200)),
392         (Val::U8(3), Val::U64(300)),
393     ];
394     let input = Val::Map(input_map);
395 
396     let mut output = [Val::Bool(false)];
397     func.call(&mut store, &[input.clone()], &mut output)?;
398     assert_eq!(input, output[0]);
399 
400     // Test map<u32, u64> - key_size=4, value_align=8
401     // This would fail with the alignment bug because value would be at offset 4 instead of 8
402     let component = Component::new(&engine, make_echo_component("(map u32 u64)", 8))?;
403     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
404     let func = instance.get_func(&mut store, "echo").unwrap();
405 
406     let input_map = vec![(Val::U32(1), Val::U64(1000)), (Val::U32(2), Val::U64(2000))];
407     let input = Val::Map(input_map);
408 
409     func.call(&mut store, &[input.clone()], &mut output)?;
410     assert_eq!(input, output[0]);
411 
412     // Test map<u8, u32> - key_size=1, value_align=4
413     // This would fail with the alignment bug because value would be at offset 1 instead of 4
414     let component = Component::new(&engine, make_echo_component("(map u8 u32)", 8))?;
415     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
416     let func = instance.get_func(&mut store, "echo").unwrap();
417 
418     let input_map = vec![(Val::U8(10), Val::U32(100)), (Val::U8(20), Val::U32(200))];
419     let input = Val::Map(input_map);
420 
421     func.call(&mut store, &[input.clone()], &mut output)?;
422     assert_eq!(input, output[0]);
423 
424     // Test map<u16, u64> - key_size=2, value_align=8
425     // This would fail with the alignment bug because value would be at offset 2 instead of 8
426     let component = Component::new(&engine, make_echo_component("(map u16 u64)", 8))?;
427     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
428     let func = instance.get_func(&mut store, "echo").unwrap();
429 
430     let input_map = vec![
431         (Val::U16(1), Val::U64(10000)),
432         (Val::U16(2), Val::U64(20000)),
433     ];
434     let input = Val::Map(input_map);
435 
436     func.call(&mut store, &[input.clone()], &mut output)?;
437     assert_eq!(input, output[0]);
438 
439     Ok(())
440 }
441 
442 #[test]
maps_large() -> Result<()>443 fn maps_large() -> Result<()> {
444     let engine = super::map_engine();
445     let mut store = Store::new(&engine, ());
446 
447     let component = Component::new(&engine, make_echo_component("(map u32 string)", 8))?;
448     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
449     let func = instance.get_func(&mut store, "echo").unwrap();
450 
451     // Create a map with many entries
452     let input_map: Vec<(Val, Val)> = (0..100)
453         .map(|i| (Val::U32(i), Val::String(format!("value_{i}"))))
454         .collect();
455     let input = Val::Map(input_map);
456 
457     let mut output = [Val::Bool(false)];
458     func.call(&mut store, &[input.clone()], &mut output)?;
459 
460     // Verify all entries are present
461     match &output[0] {
462         Val::Map(output_map) => {
463             assert_eq!(output_map.len(), 100);
464             for i in 0..100 {
465                 assert!(output_map.iter().any(|(k, v)| {
466                     *k == Val::U32(i) && *v == Val::String(format!("value_{i}"))
467                 }));
468             }
469         }
470         _ => panic!("expected map"),
471     }
472 
473     Ok(())
474 }
475 
476 #[test]
records() -> Result<()>477 fn records() -> Result<()> {
478     let engine = super::engine();
479     let mut store = Store::new(&engine, ());
480 
481     let component = Component::new(
482         &engine,
483         make_echo_component_with_params(
484             r#"
485                 (type $c' (record
486                     (field "D" bool)
487                     (field "E" u32)
488                 ))
489                 (export $c "c" (type $c'))
490                 (type $Foo' (record
491                     (field "A" u32)
492                     (field "B" float64)
493                     (field "C" $c)
494                 ))
495             "#,
496             &[
497                 Param(Type::I32, Some(0)),
498                 Param(Type::F64, Some(8)),
499                 Param(Type::U8, Some(16)),
500                 Param(Type::I32, Some(20)),
501             ],
502         ),
503     )?;
504     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
505     let func = instance.get_func(&mut store, "echo").unwrap();
506     let input = Val::Record(vec![
507         ("A".into(), Val::U32(32343)),
508         ("B".into(), Val::Float64(3.14159265)),
509         (
510             "C".into(),
511             Val::Record(vec![
512                 ("D".into(), Val::Bool(false)),
513                 ("E".into(), Val::U32(2084037802)),
514             ]),
515         ),
516     ]);
517     let mut output = [Val::Bool(false)];
518     func.call(&mut store, &[input.clone()], &mut output)?;
519 
520     assert_eq!(input, output[0]);
521 
522     // Sad path: type mismatch
523 
524     let err = Val::Record(vec![
525         ("A".into(), Val::S32(32343)),
526         ("B".into(), Val::Float64(3.14159265)),
527         (
528             "C".into(),
529             Val::Record(vec![
530                 ("D".into(), Val::Bool(false)),
531                 ("E".into(), Val::U32(2084037802)),
532             ]),
533         ),
534     ]);
535     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
536     let func = instance.get_func(&mut store, "echo").unwrap();
537     let err = func.call(&mut store, &[err], &mut output).unwrap_err();
538     assert!(err.to_string().contains("type mismatch"), "{err}");
539 
540     // Sad path: too many fields
541 
542     let err = Val::Record(vec![
543         ("A".into(), Val::U32(32343)),
544         ("B".into(), Val::Float64(3.14159265)),
545         (
546             "C".into(),
547             Val::Record(vec![
548                 ("D".into(), Val::Bool(false)),
549                 ("E".into(), Val::U32(2084037802)),
550             ]),
551         ),
552         ("F".into(), Val::Bool(true)),
553     ]);
554     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
555     let func = instance.get_func(&mut store, "echo").unwrap();
556     let err = func.call(&mut store, &[err], &mut output).unwrap_err();
557     assert!(
558         err.to_string().contains("expected 3 fields, got 4"),
559         "{err}"
560     );
561 
562     // Sad path: too few fields
563 
564     let err = Val::Record(vec![
565         ("A".into(), Val::U32(32343)),
566         ("B".into(), Val::Float64(3.14159265)),
567     ]);
568     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
569     let func = instance.get_func(&mut store, "echo").unwrap();
570     let err = func.call(&mut store, &[err], &mut output).unwrap_err();
571     assert!(
572         err.to_string().contains("expected 3 fields, got 2"),
573         "{err}"
574     );
575 
576     Ok(())
577 }
578 
579 #[test]
variants() -> Result<()>580 fn variants() -> Result<()> {
581     let engine = super::engine();
582     let mut store = Store::new(&engine, ());
583 
584     let fragment = r#"
585                 (type $c' (record (field "D" bool) (field "E" u32)))
586                 (export $c "c" (type $c'))
587                 (type $Foo' (variant
588                     (case "A" u32)
589                     (case "B" float64)
590                     (case "C" $c)
591                 ))
592             "#;
593 
594     let component = Component::new(
595         &engine,
596         make_echo_component_with_params(
597             fragment,
598             &[
599                 Param(Type::U8, Some(0)),
600                 Param(Type::I64, Some(8)),
601                 Param(Type::I32, None),
602             ],
603         ),
604     )?;
605     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
606     let func = instance.get_func(&mut store, "echo").unwrap();
607     let input = Val::Variant("B".into(), Some(Box::new(Val::Float64(3.14159265))));
608     let mut output = [Val::Bool(false)];
609     func.call(&mut store, &[input.clone()], &mut output)?;
610 
611     assert_eq!(input, output[0]);
612 
613     // Do it again, this time using case "C"
614 
615     let component = Component::new(
616         &engine,
617         make_echo_component_with_params(
618             fragment,
619             &[
620                 Param(Type::U8, Some(0)),
621                 Param(Type::I64, Some(8)),
622                 Param(Type::I32, Some(12)),
623             ],
624         ),
625     )?;
626     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
627     let func = instance.get_func(&mut store, "echo").unwrap();
628     let input = Val::Variant(
629         "C".into(),
630         Some(Box::new(Val::Record(vec![
631             ("D".into(), Val::Bool(true)),
632             ("E".into(), Val::U32(314159265)),
633         ]))),
634     );
635     func.call(&mut store, &[input.clone()], &mut output)?;
636 
637     assert_eq!(input, output[0]);
638 
639     // Sad path: type mismatch
640 
641     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
642     let func = instance.get_func(&mut store, "echo").unwrap();
643     let err = Val::Variant("B".into(), Some(Box::new(Val::U64(314159265))));
644     let err = func.call(&mut store, &[err], &mut output).unwrap_err();
645     assert!(err.to_string().contains("type mismatch"), "{err}");
646 
647     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
648     let func = instance.get_func(&mut store, "echo").unwrap();
649     let err = Val::Variant("B".into(), None);
650     let err = func.call(&mut store, &[err], &mut output).unwrap_err();
651     assert!(
652         err.to_string().contains("expected a payload for case `B`"),
653         "{err}"
654     );
655 
656     // Sad path: unknown case
657 
658     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
659     let func = instance.get_func(&mut store, "echo").unwrap();
660     let err = Val::Variant("D".into(), Some(Box::new(Val::U64(314159265))));
661     let err = func.call(&mut store, &[err], &mut output).unwrap_err();
662     assert!(err.to_string().contains("unknown variant case"), "{err}");
663 
664     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
665     let func = instance.get_func(&mut store, "echo").unwrap();
666     let err = Val::Variant("D".into(), None);
667     let err = func.call(&mut store, &[err], &mut output).unwrap_err();
668     assert!(err.to_string().contains("unknown variant case"), "{err}");
669 
670     // Make sure we lift variants which have cases of different sizes with the correct alignment
671 
672     let component = Component::new(
673         &engine,
674         make_echo_component_with_params(
675             r#"
676                 (type $c' (record (field "D" bool) (field "E" u32)))
677                 (export $c "c" (type $c'))
678                 (type $a' (variant
679                     (case "A" u32)
680                     (case "B" float64)
681                     (case "C" $c)
682                 ))
683                 (export $a "a" (type $a'))
684                 (type $Foo' (record
685                     (field "A" $a)
686                     (field "B" u32)
687                 ))
688             "#,
689             &[
690                 Param(Type::U8, Some(0)),
691                 Param(Type::I64, Some(8)),
692                 Param(Type::I32, None),
693                 Param(Type::I32, Some(16)),
694             ],
695         ),
696     )?;
697     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
698     let func = instance.get_func(&mut store, "echo").unwrap();
699     let input = Val::Record(vec![
700         (
701             "A".into(),
702             Val::Variant("A".into(), Some(Box::new(Val::U32(314159265)))),
703         ),
704         ("B".into(), Val::U32(628318530)),
705     ]);
706     func.call(&mut store, &[input.clone()], &mut output)?;
707 
708     assert_eq!(input, output[0]);
709 
710     Ok(())
711 }
712 
713 #[test]
flags() -> Result<()>714 fn flags() -> Result<()> {
715     let engine = super::engine();
716     let mut store = Store::new(&engine, ());
717 
718     let component = Component::new(
719         &engine,
720         make_echo_component_with_params(
721             r#"(flags "A" "B" "C" "D" "E")"#,
722             &[Param(Type::U8, Some(0))],
723         ),
724     )?;
725     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
726     let func = instance.get_func(&mut store, "echo").unwrap();
727     let input = Val::Flags(vec!["B".into(), "D".into()]);
728     let mut output = [Val::Bool(false)];
729     func.call(&mut store, &[input.clone()], &mut output)?;
730 
731     assert_eq!(input, output[0]);
732 
733     // Sad path: unknown flags
734 
735     let err = Val::Flags(vec!["B".into(), "D".into(), "F".into()]);
736     let err = func.call(&mut store, &[err], &mut output).unwrap_err();
737     assert!(err.to_string().contains("unknown flag"), "{err}");
738 
739     Ok(())
740 }
741 
742 #[test]
everything() -> Result<()>743 fn everything() -> Result<()> {
744     // This serves to test both nested types and storing parameters on the heap (i.e. exceeding `MAX_STACK_PARAMS`)
745 
746     let engine = super::engine();
747     let mut store = Store::new(&engine, ());
748 
749     let component = Component::new(
750         &engine,
751         make_echo_component_with_params(
752             r#"
753                 (type $b' (enum "a" "b"))
754                 (export $b "b" (type $b'))
755                 (type $c' (record (field "D" bool) (field "E" u32)))
756                 (export $c "c" (type $c'))
757                 (type $f' (flags "G" "H" "I"))
758                 (export $f "f" (type $f'))
759                 (type $m' (record (field "N" bool) (field "O" u32)))
760                 (export $m "m" (type $m'))
761                 (type $j' (variant
762                     (case "K" u32)
763                     (case "L" float64)
764                     (case "M" $m)
765                 ))
766                 (export $j "j" (type $j'))
767 
768                 (type $Foo' (record
769                     (field "A" u32)
770                     (field "B" $b)
771                     (field "C" $c)
772                     (field "F" (list $f))
773                     (field "J" $j)
774                     (field "P" s8)
775                     (field "Q" s16)
776                     (field "R" s32)
777                     (field "S" s64)
778                     (field "T" float32)
779                     (field "U" float64)
780                     (field "V" string)
781                     (field "W" char)
782                     (field "Y" (tuple u32 u32))
783                     (field "AA" (option u32))
784                     (field "BB" (result string (error string)))
785                 ))
786             "#,
787             &[
788                 Param(Type::I32, Some(0)),
789                 Param(Type::U8, Some(4)),
790                 Param(Type::U8, Some(5)),
791                 Param(Type::I32, Some(8)),
792                 Param(Type::I32, Some(12)),
793                 Param(Type::I32, Some(16)),
794                 Param(Type::U8, Some(20)),
795                 Param(Type::I64, Some(28)),
796                 Param(Type::I32, Some(32)),
797                 Param(Type::S8, Some(36)),
798                 Param(Type::S16, Some(38)),
799                 Param(Type::I32, Some(40)),
800                 Param(Type::I64, Some(48)),
801                 Param(Type::F32, Some(56)),
802                 Param(Type::F64, Some(64)),
803                 Param(Type::I32, Some(72)),
804                 Param(Type::I32, Some(76)),
805                 Param(Type::I32, Some(80)),
806                 Param(Type::I32, Some(84)),
807                 Param(Type::I32, Some(88)),
808                 Param(Type::I64, Some(96)),
809                 Param(Type::U8, Some(104)),
810                 Param(Type::I32, Some(108)),
811                 Param(Type::U8, Some(112)),
812                 Param(Type::I32, Some(116)),
813                 Param(Type::I32, Some(120)),
814             ],
815         ),
816     )?;
817     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
818     let func = instance.get_func(&mut store, "echo").unwrap();
819     let input = Val::Record(vec![
820         ("A".into(), Val::U32(32343)),
821         ("B".into(), Val::Enum("b".to_string())),
822         (
823             "C".into(),
824             Val::Record(vec![
825                 ("D".to_string(), Val::Bool(false)),
826                 ("E".to_string(), Val::U32(2084037802)),
827             ]),
828         ),
829         (
830             "F".into(),
831             Val::List(vec![Val::Flags(vec!["G".to_string(), "I".to_string()])]),
832         ),
833         (
834             "J".into(),
835             Val::Variant("L".to_string(), Some(Box::new(Val::Float64(3.14159265)))),
836         ),
837         ("P".into(), Val::S8(42)),
838         ("Q".into(), Val::S16(4242)),
839         ("R".into(), Val::S32(42424242)),
840         ("S".into(), Val::S64(424242424242424242)),
841         ("T".into(), Val::Float32(3.14159265)),
842         ("U".into(), Val::Float64(3.14159265)),
843         ("V".into(), Val::String("wow, nice types".to_string())),
844         ("W".into(), Val::Char('��')),
845         ("Y".into(), Val::Tuple(vec![Val::U32(42), Val::U32(24)])),
846         (
847             "AA".into(),
848             Val::Option(Some(Box::new(Val::U32(314159265)))),
849         ),
850         (
851             "BB".into(),
852             Val::Result(Ok(Some(Box::new(Val::String("no problem".to_string()))))),
853         ),
854     ]);
855     let mut output = [Val::Bool(false)];
856     func.call(&mut store, &[input.clone()], &mut output)?;
857 
858     assert_eq!(input, output[0]);
859 
860     Ok(())
861 }
862 
863 #[test]
introspection() -> Result<()>864 fn introspection() -> Result<()> {
865     let engine = super::engine();
866 
867     let component = Component::new(
868         &engine,
869         format!(
870             r#"
871             (component
872                 (import "res" (type $res (sub resource)))
873 
874                 (import "ai" (instance $i))
875                 (import "bi" (instance $i2 (export "m" (core module))))
876 
877                 (alias export $i2 "m" (core module $m))
878 
879                 (type $t (func (param "a" u32) (result u32)))
880                 (component $a
881                   (core module $m
882                     (func (export "add-five") (param i32) (result i32)
883                       local.get 0
884                       i32.const 5
885                       i32.add)
886                   )
887                   (core instance $m (instantiate $m))
888                   (func (export "add-five") (type $t) (canon lift (core func $m "add-five")))
889                 )
890                 (component $b
891                   (import "interface-v1" (instance $i
892                     (export "add-five" (func (type $t)))))
893                   (core module $m
894                     (func $add-five (import "interface-0.1.0" "add-five") (param i32) (result i32))
895                     (func) ;; causes index out of bounds
896                     (func (export "run") (result i32) i32.const 0 call $add-five)
897                   )
898                   (core func $add-five (canon lower (func $i "add-five")))
899                   (core instance $i (instantiate 0
900                     (with "interface-0.1.0" (instance
901                       (export "add-five" (func $add-five))
902                     ))
903                   ))
904                   (func (result u32) (canon lift (core func $i "run")))
905                   (export "run" (func 1))
906                 )
907                 (instance $a (instantiate $a))
908                 (instance $b (instantiate $b (with "interface-v1" (instance $a))))
909                 (export "run" (func $b "run"))
910 
911                 (component $c
912                     (component $c
913                         (export "m" (core module $m))
914                     )
915                     (instance $c (instantiate $c))
916                     (export "i" (instance $c))
917                 )
918                 (instance $c (instantiate $c))
919                 (export "i" (instance $c))
920                 (export "r" (instance $i))
921                 (export "r2" (instance $i2))
922 
923                 (type $b' (enum "a" "b"))
924                 (export $b "b" (type $b'))
925                 (type $c' (record (field "D" bool) (field "E" u32)))
926                 (export $c "c" (type $c'))
927                 (type $f' (flags "G" "H" "I"))
928                 (export $f "f" (type $f'))
929                 (type $m' (record (field "N" bool) (field "O" u32)))
930                 (export $m "m" (type $m'))
931                 (type $j' (variant
932                     (case "K" u32)
933                     (case "L" float64)
934                     (case "M" $m)
935                 ))
936                 (export $j "j" (type $j'))
937 
938                 (type $Foo' (record
939                     (field "A" u32)
940                     (field "B" $b)
941                     (field "C" $c)
942                     (field "F" (list $f))
943                     (field "J" $j)
944                     (field "P" s8)
945                     (field "Q" s16)
946                     (field "R" s32)
947                     (field "S" s64)
948                     (field "T" float32)
949                     (field "U" float64)
950                     (field "V" string)
951                     (field "W" char)
952                     (field "Y" (tuple u32 u32))
953                     (field "AA" (option u32))
954                     (field "BB" (result string (error string)))
955                     (field "CC" (own $res))
956                 ))
957                 (export $Foo "foo" (type $Foo'))
958 
959                 (core module $m2
960                     (func (export "f") (param i32) (result i32)
961                         local.get 0
962                     )
963                     (memory (export "memory") 1)
964                     {REALLOC_AND_FREE}
965                 )
966                 (core instance $i3 (instantiate $m2))
967 
968                 (func (export "fn") (param "x" (option $Foo)) (result (option (tuple u32 u32)))
969                     (canon lift
970                         (core func $i3 "f")
971                         (memory $i3 "memory")
972                         (realloc (func $i3 "realloc"))
973                     )
974                 )
975             )
976         "#
977         ),
978     )?;
979 
980     struct MyType;
981 
982     let mut linker = Linker::<()>::new(&engine);
983     linker
984         .root()
985         .resource("res", ResourceType::host::<MyType>(), |_, _| Ok(()))?;
986     linker.instance("ai")?;
987     linker
988         .instance("bi")?
989         .module("m", &Module::new(&engine, "(module)")?)?;
990 
991     let component_ty = linker.substituted_component_type(&component)?;
992 
993     let mut imports = component_ty.imports(linker.engine());
994     assert_eq!(imports.len(), 3);
995     let (name, res_ty) = imports.next().unwrap();
996     assert_eq!(name, "res");
997     let ComponentItem::Resource(res_ty) = res_ty else {
998         panic!("`res` import item of wrong type")
999     };
1000     assert_eq!(res_ty, ResourceType::host::<MyType>());
1001 
1002     let (name, ai_ty) = imports.next().unwrap();
1003     assert_eq!(name, "ai");
1004     let ComponentItem::ComponentInstance(ai_ty) = ai_ty else {
1005         panic!("`ai` import item of wrong type")
1006     };
1007     assert_eq!(ai_ty.exports(linker.engine()).len(), 0);
1008 
1009     let (name, bi_ty) = imports.next().unwrap();
1010     assert_eq!(name, "bi");
1011     let ComponentItem::ComponentInstance(bi_ty) = bi_ty else {
1012         panic!("`bi` import item of wrong type")
1013     };
1014     let mut bi_exports = bi_ty.exports(linker.engine());
1015     assert_eq!(bi_exports.len(), 1);
1016     let (name, bi_m_ty) = bi_exports.next().unwrap();
1017     assert_eq!(name, "m");
1018     let ComponentItem::Module(bi_m_ty) = bi_m_ty else {
1019         panic!("`bi.m` import item of wrong type")
1020     };
1021     assert_eq!(bi_m_ty.imports(linker.engine()).len(), 0);
1022     assert_eq!(bi_m_ty.exports(linker.engine()).len(), 0);
1023 
1024     let mut exports = component_ty.exports(linker.engine());
1025     assert_eq!(exports.len(), 11);
1026 
1027     let (name, run_ty) = exports.next().unwrap();
1028     assert_eq!(name, "run");
1029     let ComponentItem::ComponentFunc(run_ty) = run_ty else {
1030         panic!("`run` export item of wrong type")
1031     };
1032     assert_eq!(run_ty.params().len(), 0);
1033 
1034     let mut run_results = run_ty.results();
1035     assert_eq!(run_results.len(), 1);
1036     assert_eq!(run_results.next().unwrap(), types::Type::U32);
1037 
1038     let (name, i_ty) = exports.next().unwrap();
1039     assert_eq!(name, "i");
1040     let ComponentItem::ComponentInstance(i_ty) = i_ty else {
1041         panic!("`i` export item of wrong type")
1042     };
1043     let mut i_ty_exports = i_ty.exports(linker.engine());
1044     assert_eq!(i_ty_exports.len(), 1);
1045     let (name, i_i_ty) = i_ty_exports.next().unwrap();
1046     assert_eq!(name, "i");
1047     let ComponentItem::ComponentInstance(i_i_ty) = i_i_ty else {
1048         panic!("`i.i` import item of wrong type")
1049     };
1050     let mut i_i_ty_exports = i_i_ty.exports(linker.engine());
1051     assert_eq!(i_i_ty_exports.len(), 1);
1052     let (name, i_i_m_ty) = i_i_ty_exports.next().unwrap();
1053     assert_eq!(name, "m");
1054     let ComponentItem::Module(i_i_m_ty) = i_i_m_ty else {
1055         panic!("`i.i.m` import item of wrong type")
1056     };
1057     assert_eq!(i_i_m_ty.imports(linker.engine()).len(), 0);
1058     assert_eq!(i_i_m_ty.exports(linker.engine()).len(), 0);
1059 
1060     let (name, r_ty) = exports.next().unwrap();
1061     assert_eq!(name, "r");
1062     let ComponentItem::ComponentInstance(r_ty) = r_ty else {
1063         panic!("`r` export item of wrong type")
1064     };
1065     assert_eq!(r_ty.exports(linker.engine()).len(), 0);
1066 
1067     let (name, r2_ty) = exports.next().unwrap();
1068     assert_eq!(name, "r2");
1069     let ComponentItem::ComponentInstance(r2_ty) = r2_ty else {
1070         panic!("`r2` export item of wrong type")
1071     };
1072     let mut r2_exports = r2_ty.exports(linker.engine());
1073     assert_eq!(r2_exports.len(), 1);
1074     let (name, r2_m_ty) = r2_exports.next().unwrap();
1075     assert_eq!(name, "m");
1076     let ComponentItem::Module(r2_m_ty) = r2_m_ty else {
1077         panic!("`r2.m` export item of wrong type")
1078     };
1079     assert_eq!(r2_m_ty.imports(linker.engine()).len(), 0);
1080     assert_eq!(r2_m_ty.exports(linker.engine()).len(), 0);
1081 
1082     let (name, b_ty) = exports.next().unwrap();
1083     assert_eq!(name, "b");
1084     let ComponentItem::Type(b_ty) = b_ty else {
1085         panic!("`b` export item of wrong type")
1086     };
1087     assert_eq!(b_ty.unwrap_enum().names().collect::<Vec<_>>(), ["a", "b"]);
1088 
1089     let (name, c_ty) = exports.next().unwrap();
1090     assert_eq!(name, "c");
1091     let ComponentItem::Type(c_ty) = c_ty else {
1092         panic!("`c` export item of wrong type")
1093     };
1094     let mut fields = c_ty.unwrap_record().fields();
1095     {
1096         let Field { name, ty } = fields.next().unwrap();
1097         assert_eq!(name, "D");
1098         assert_eq!(ty, types::Type::Bool);
1099         let Field { name, ty } = fields.next().unwrap();
1100         assert_eq!(name, "E");
1101         assert_eq!(ty, types::Type::U32);
1102     }
1103 
1104     let (name, f_ty) = exports.next().unwrap();
1105     assert_eq!(name, "f");
1106     let ComponentItem::Type(f_ty) = f_ty else {
1107         panic!("`f` export item of wrong type")
1108     };
1109     assert_eq!(
1110         f_ty.unwrap_flags().names().collect::<Vec<_>>(),
1111         ["G", "H", "I"]
1112     );
1113 
1114     let (name, m_ty) = exports.next().unwrap();
1115     assert_eq!(name, "m");
1116     let ComponentItem::Type(m_ty) = m_ty else {
1117         panic!("`m` export item of wrong type")
1118     };
1119     {
1120         let mut fields = m_ty.unwrap_record().fields();
1121         let Field { name, ty } = fields.next().unwrap();
1122         assert_eq!(name, "N");
1123         assert_eq!(ty, types::Type::Bool);
1124         let Field { name, ty } = fields.next().unwrap();
1125         assert_eq!(name, "O");
1126         assert_eq!(ty, types::Type::U32);
1127     }
1128 
1129     let (name, j_ty) = exports.next().unwrap();
1130     assert_eq!(name, "j");
1131     let ComponentItem::Type(j_ty) = j_ty else {
1132         panic!("`j` export item of wrong type")
1133     };
1134     let mut cases = j_ty.unwrap_variant().cases();
1135     {
1136         let Case { name, ty } = cases.next().unwrap();
1137         assert_eq!(name, "K");
1138         assert_eq!(ty, Some(types::Type::U32));
1139         let Case { name, ty } = cases.next().unwrap();
1140         assert_eq!(name, "L");
1141         assert_eq!(ty, Some(types::Type::Float64));
1142         let Case { name, ty } = cases.next().unwrap();
1143         assert_eq!(name, "M");
1144         assert_eq!(ty, Some(m_ty));
1145     }
1146 
1147     let (name, foo_ty) = exports.next().unwrap();
1148     assert_eq!(name, "foo");
1149     let ComponentItem::Type(foo_ty) = foo_ty else {
1150         panic!("`foo` export item of wrong type")
1151     };
1152     {
1153         let mut fields = foo_ty.unwrap_record().fields();
1154         assert_eq!(fields.len(), 17);
1155         let Field { name, ty } = fields.next().unwrap();
1156         assert_eq!(name, "A");
1157         assert_eq!(ty, types::Type::U32);
1158         let Field { name, ty } = fields.next().unwrap();
1159         assert_eq!(name, "B");
1160         assert_eq!(ty, b_ty);
1161         let Field { name, ty } = fields.next().unwrap();
1162         assert_eq!(name, "C");
1163         assert_eq!(ty, c_ty);
1164         let Field { name, ty } = fields.next().unwrap();
1165         assert_eq!(name, "F");
1166         let ty = ty.unwrap_list();
1167         assert_eq!(ty.ty(), f_ty);
1168         let Field { name, ty } = fields.next().unwrap();
1169         assert_eq!(name, "J");
1170         assert_eq!(ty, j_ty);
1171         let Field { name, ty } = fields.next().unwrap();
1172         assert_eq!(name, "P");
1173         assert_eq!(ty, types::Type::S8);
1174         let Field { name, ty } = fields.next().unwrap();
1175         assert_eq!(name, "Q");
1176         assert_eq!(ty, types::Type::S16);
1177         let Field { name, ty } = fields.next().unwrap();
1178         assert_eq!(name, "R");
1179         assert_eq!(ty, types::Type::S32);
1180         let Field { name, ty } = fields.next().unwrap();
1181         assert_eq!(name, "S");
1182         assert_eq!(ty, types::Type::S64);
1183         let Field { name, ty } = fields.next().unwrap();
1184         assert_eq!(name, "T");
1185         assert_eq!(ty, types::Type::Float32);
1186         let Field { name, ty } = fields.next().unwrap();
1187         assert_eq!(name, "U");
1188         assert_eq!(ty, types::Type::Float64);
1189         let Field { name, ty } = fields.next().unwrap();
1190         assert_eq!(name, "V");
1191         assert_eq!(ty, types::Type::String);
1192         let Field { name, ty } = fields.next().unwrap();
1193         assert_eq!(name, "W");
1194         assert_eq!(ty, types::Type::Char);
1195         let Field { name, ty } = fields.next().unwrap();
1196         assert_eq!(name, "Y");
1197         assert_eq!(
1198             ty.unwrap_tuple().types().collect::<Vec<_>>(),
1199             [types::Type::U32, types::Type::U32]
1200         );
1201         let Field { name, ty } = fields.next().unwrap();
1202         assert_eq!(name, "AA");
1203         assert_eq!(ty.unwrap_option().ty(), types::Type::U32);
1204         let Field { name, ty } = fields.next().unwrap();
1205         assert_eq!(name, "BB");
1206         let ty = ty.unwrap_result();
1207         assert_eq!(ty.ok(), Some(types::Type::String));
1208         assert_eq!(ty.err(), Some(types::Type::String));
1209         let Field { name, ty } = fields.next().unwrap();
1210         assert_eq!(name, "CC");
1211         assert_eq!(*ty.unwrap_own(), res_ty);
1212     }
1213 
1214     let (name, fn_ty) = exports.next().unwrap();
1215     assert_eq!(name, "fn");
1216     let ComponentItem::ComponentFunc(fn_ty) = fn_ty else {
1217         panic!("`fn` export item of wrong type")
1218     };
1219     let mut params = fn_ty.params();
1220     assert_eq!(params.len(), 1);
1221     let (name, param) = params.next().unwrap();
1222     assert_eq!(name, "x");
1223     assert_eq!(param.unwrap_option().ty(), foo_ty);
1224 
1225     let mut results = fn_ty.results();
1226     assert_eq!(results.len(), 1);
1227     assert_eq!(
1228         results
1229             .next()
1230             .unwrap()
1231             .unwrap_option()
1232             .ty()
1233             .unwrap_tuple()
1234             .types()
1235             .collect::<Vec<_>>(),
1236         [types::Type::U32, types::Type::U32]
1237     );
1238     Ok(())
1239 }
1240 
1241 #[test]
flags_beyond_end() -> Result<()>1242 fn flags_beyond_end() -> Result<()> {
1243     let engine = super::engine();
1244 
1245     let component = Component::new(
1246         &engine,
1247         r#"
1248             (component
1249                 (type $f' (flags "a" "b"))
1250                 (export $f "f" (type $f'))
1251 
1252                 (core module $m
1253                     (func (export "r") (param i32) (result i32) local.get 0)
1254                 )
1255                 (core instance $i (instantiate $m))
1256                 (func (export "run") (param "x" u32) (result $f)
1257                     (canon lift (core func $i "r")))
1258             )
1259         "#,
1260     )?;
1261     let mut store = Store::new(&engine, ());
1262     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
1263     let run = instance.get_func(&mut store, "run").unwrap();
1264 
1265     let mut output = [Val::Bool(false)];
1266     run.call(&mut store, &[Val::U32(0)], &mut output)?;
1267     assert_eq!(output[0], Val::Flags(vec![]));
1268 
1269     let mut output = [Val::Bool(false)];
1270     run.call(&mut store, &[Val::U32(1)], &mut output)?;
1271     assert_eq!(output[0], Val::Flags(vec!["a".to_string()]));
1272 
1273     let mut output = [Val::Bool(false)];
1274     run.call(&mut store, &[Val::U32(2)], &mut output)?;
1275     assert_eq!(output[0], Val::Flags(vec!["b".to_string()]));
1276 
1277     let mut output = [Val::Bool(false)];
1278     run.call(&mut store, &[Val::U32(3)], &mut output)?;
1279     assert_eq!(
1280         output[0],
1281         Val::Flags(vec!["a".to_string(), "b".to_string()])
1282     );
1283     let mut output = [Val::Bool(false)];
1284 
1285     run.call(&mut store, &[Val::U32(4)], &mut output)?;
1286     assert_eq!(output[0], Val::Flags(vec![]));
1287 
1288     run.call(&mut store, &[Val::U32(5)], &mut output)?;
1289     assert_eq!(output[0], Val::Flags(vec!["a".to_string()]));
1290 
1291     wasmtime::component::flags! {
1292         F {
1293             #[component(name = "a")]
1294             const A;
1295             #[component(name = "b")]
1296             const B;
1297         }
1298     }
1299 
1300     let run = instance.get_typed_func::<(u32,), (F,)>(&mut store, "run")?;
1301     assert_eq!(run.call(&mut store, (0,))?, (F::empty(),));
1302     assert_eq!(run.call(&mut store, (1,))?, (F::A,));
1303     assert_eq!(run.call(&mut store, (2,))?, (F::B,));
1304     assert_eq!(run.call(&mut store, (3,))?, (F::A | F::B,));
1305     assert_eq!(run.call(&mut store, (4,))?, (F::empty(),));
1306     assert_eq!(run.call(&mut store, (5,))?, (F::A,));
1307     Ok(())
1308 }
1309