wasm_smith/
component.rs

1//! Generation of Wasm
2//! [components](https://github.com/WebAssembly/component-model).
3
4// FIXME(#1000): component support in `wasm-smith` is a work in progress.
5#![allow(unused_variables, dead_code)]
6
7use crate::{arbitrary_loop, Config};
8use arbitrary::{Arbitrary, Result, Unstructured};
9use std::collections::BTreeMap;
10use std::{
11    collections::{HashMap, HashSet},
12    rc::Rc,
13};
14use wasm_encoder::{
15    ComponentTypeRef, ComponentValType, HeapType, PrimitiveValType, RefType, TypeBounds, ValType,
16};
17
18mod encode;
19
20/// A pseudo-random WebAssembly [component].
21///
22/// Construct instances of this type with [the `Arbitrary`
23/// trait](https://docs.rs/arbitrary/*/arbitrary/trait.Arbitrary.html).
24///
25/// [component]: https://github.com/WebAssembly/component-model/blob/ast-and-binary/design/MVP/Explainer.md
26///
27/// ## Configured Generated Components
28///
29/// The `Arbitrary` implementation uses the [`Config::default()`][crate::Config]
30/// configuration. If you want to customize the shape of generated components,
31/// create your own [`Config`][crate::Config] instance and pass it to
32/// [`Component::new`][crate::Component::new].
33#[derive(Debug)]
34pub struct Component {
35    sections: Vec<Section>,
36}
37
38/// A builder to create a component (and possibly a whole tree of nested
39/// components).
40///
41/// Maintains a stack of components we are currently building, as well as
42/// metadata about them. The split between `Component` and `ComponentBuilder` is
43/// that the builder contains metadata that is purely used when generating
44/// components and is unnecessary after we are done generating the structure of
45/// the components and only need to encode an already-generated component to
46/// bytes.
47#[derive(Debug)]
48struct ComponentBuilder {
49    config: Config,
50
51    // The set of core `valtype`s that we are configured to generate.
52    core_valtypes: Vec<ValType>,
53
54    // Stack of types scopes that are currently available.
55    //
56    // There is an entry in this stack for each component, but there can also be
57    // additional entries for module/component/instance types, each of which
58    // have their own scope.
59    //
60    // This stack is always non-empty and the last entry is always the current
61    // scope.
62    //
63    // When a particular scope can alias outer types, it can alias from any
64    // scope that is older than it (i.e. `types_scope[i]` can alias from
65    // `types_scope[j]` when `j <= i`).
66    types: Vec<TypesScope>,
67
68    // The set of components we are currently building and their associated
69    // metadata.
70    components: Vec<ComponentContext>,
71
72    // Whether we are in the final bits of generating this component and we just
73    // need to ensure that the minimum number of entities configured have all
74    // been generated. This changes the behavior of various
75    // `arbitrary_<section>` methods to always fill in their minimums.
76    fill_minimums: bool,
77
78    // Our maximums for these entities are applied across the whole component
79    // tree, not per-component.
80    total_components: usize,
81    total_modules: usize,
82    total_instances: usize,
83    total_values: usize,
84}
85
86#[derive(Debug, Clone)]
87enum ComponentOrCoreFuncType {
88    Component(Rc<FuncType>),
89    Core(Rc<crate::core::FuncType>),
90}
91
92impl ComponentOrCoreFuncType {
93    fn as_core(&self) -> &Rc<crate::core::FuncType> {
94        match self {
95            ComponentOrCoreFuncType::Core(t) => t,
96            ComponentOrCoreFuncType::Component(_) => panic!("not a core func type"),
97        }
98    }
99
100    fn as_component(&self) -> &Rc<FuncType> {
101        match self {
102            ComponentOrCoreFuncType::Core(_) => panic!("not a component func type"),
103            ComponentOrCoreFuncType::Component(t) => t,
104        }
105    }
106}
107
108#[derive(Debug, Clone)]
109enum ComponentOrCoreInstanceType {
110    Component(Rc<InstanceType>),
111    Core(BTreeMap<String, crate::core::EntityType>),
112}
113
114/// Metadata (e.g. contents of various index spaces) we keep track of on a
115/// per-component basis.
116#[derive(Debug)]
117struct ComponentContext {
118    // The actual component itself.
119    component: Component,
120
121    // The number of imports we have generated thus far.
122    num_imports: usize,
123
124    // The set of names of imports we've generated thus far.
125    import_names: HashSet<String>,
126
127    // The set of URLs of imports we've generated thus far.
128    import_urls: HashSet<String>,
129
130    // This component's function index space.
131    funcs: Vec<ComponentOrCoreFuncType>,
132
133    // Which entries in `funcs` are component functions?
134    component_funcs: Vec<u32>,
135
136    // Which entries in `component_funcs` are component functions that only use scalar
137    // types?
138    scalar_component_funcs: Vec<u32>,
139
140    // Which entries in `funcs` are core Wasm functions?
141    //
142    // Note that a component can't import core functions, so these entries will
143    // never point to a `Section::Import`.
144    core_funcs: Vec<u32>,
145
146    // This component's component index space.
147    //
148    // An indirect list of all directly-nested (not transitive) components
149    // inside this component.
150    //
151    // Each entry is of the form `(i, j)` where `component.sections[i]` is
152    // guaranteed to be either
153    //
154    // * a `Section::Component` and we are referencing the component defined in
155    //   that section (in this case `j` must also be `0`, since a component
156    //   section can only contain a single nested component), or
157    //
158    // * a `Section::Import` and we are referencing the `j`th import in that
159    //   section, which is guaranteed to be a component import.
160    components: Vec<(usize, usize)>,
161
162    // This component's module index space.
163    //
164    // An indirect list of all directly-nested (not transitive) modules
165    // inside this component.
166    //
167    // Each entry is of the form `(i, j)` where `component.sections[i]` is
168    // guaranteed to be either
169    //
170    // * a `Section::Core` and we are referencing the module defined in that
171    //   section (in this case `j` must also be `0`, since a core section can
172    //   only contain a single nested module), or
173    //
174    // * a `Section::Import` and we are referencing the `j`th import in that
175    //   section, which is guaranteed to be a module import.
176    modules: Vec<(usize, usize)>,
177
178    // This component's instance index space.
179    instances: Vec<ComponentOrCoreInstanceType>,
180
181    // This component's value index space.
182    values: Vec<ComponentValType>,
183}
184
185impl ComponentContext {
186    fn empty() -> Self {
187        ComponentContext {
188            component: Component::empty(),
189            num_imports: 0,
190            import_names: HashSet::default(),
191            import_urls: HashSet::default(),
192            funcs: vec![],
193            component_funcs: vec![],
194            scalar_component_funcs: vec![],
195            core_funcs: vec![],
196            components: vec![],
197            modules: vec![],
198            instances: vec![],
199            values: vec![],
200        }
201    }
202
203    fn num_modules(&self) -> usize {
204        self.modules.len()
205    }
206
207    fn num_components(&self) -> usize {
208        self.components.len()
209    }
210
211    fn num_instances(&self) -> usize {
212        self.instances.len()
213    }
214
215    fn num_funcs(&self) -> usize {
216        self.funcs.len()
217    }
218
219    fn num_values(&self) -> usize {
220        self.values.len()
221    }
222}
223
224#[derive(Debug, Default)]
225struct TypesScope {
226    // All core types in this scope, regardless of kind.
227    core_types: Vec<Rc<CoreType>>,
228
229    // The indices of all the entries in `core_types` that are core function types.
230    core_func_types: Vec<u32>,
231
232    // The indices of all the entries in `core_types` that are module types.
233    module_types: Vec<u32>,
234
235    // All component types in this index space, regardless of kind.
236    types: Vec<Rc<Type>>,
237
238    // The indices of all the entries in `types` that are defined value types.
239    defined_types: Vec<u32>,
240
241    // The indices of all the entries in `types` that are func types.
242    func_types: Vec<u32>,
243
244    // A map from function types to their indices in the types space.
245    func_type_to_indices: HashMap<Rc<FuncType>, Vec<u32>>,
246
247    // The indices of all the entries in `types` that are component types.
248    component_types: Vec<u32>,
249
250    // The indices of all the entries in `types` that are instance types.
251    instance_types: Vec<u32>,
252}
253
254impl TypesScope {
255    fn push(&mut self, ty: Rc<Type>) -> u32 {
256        let ty_idx = u32::try_from(self.types.len()).unwrap();
257
258        let kind_list = match &*ty {
259            Type::Defined(_) => &mut self.defined_types,
260            Type::Func(func_ty) => {
261                self.func_type_to_indices
262                    .entry(func_ty.clone())
263                    .or_default()
264                    .push(ty_idx);
265                &mut self.func_types
266            }
267            Type::Component(_) => &mut self.component_types,
268            Type::Instance(_) => &mut self.instance_types,
269        };
270        kind_list.push(ty_idx);
271
272        self.types.push(ty);
273        ty_idx
274    }
275
276    fn push_core(&mut self, ty: Rc<CoreType>) -> u32 {
277        let ty_idx = u32::try_from(self.core_types.len()).unwrap();
278
279        let kind_list = match &*ty {
280            CoreType::Func(_) => &mut self.core_func_types,
281            CoreType::Module(_) => &mut self.module_types,
282        };
283        kind_list.push(ty_idx);
284
285        self.core_types.push(ty);
286        ty_idx
287    }
288
289    fn get(&self, index: u32) -> &Rc<Type> {
290        &self.types[index as usize]
291    }
292
293    fn get_core(&self, index: u32) -> &Rc<CoreType> {
294        &self.core_types[index as usize]
295    }
296
297    fn get_func(&self, index: u32) -> &Rc<FuncType> {
298        match &**self.get(index) {
299            Type::Func(f) => f,
300            _ => panic!("get_func on non-function type"),
301        }
302    }
303
304    fn can_ref_type(&self) -> bool {
305        // All component types and core module types may be referenced
306        !self.types.is_empty() || !self.module_types.is_empty()
307    }
308}
309
310impl<'a> Arbitrary<'a> for Component {
311    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
312        Component::new(Config::default(), u)
313    }
314}
315
316#[derive(Default)]
317struct EntityCounts {
318    globals: usize,
319    tables: usize,
320    memories: usize,
321    tags: usize,
322    funcs: usize,
323}
324
325impl Component {
326    /// Construct a new `Component` using the given configuration.
327    pub fn new(config: Config, u: &mut Unstructured) -> Result<Self> {
328        let mut builder = ComponentBuilder::new(config);
329        builder.build(u)
330    }
331
332    fn empty() -> Self {
333        Component { sections: vec![] }
334    }
335}
336
337#[must_use]
338enum Step {
339    Finished(Component),
340    StillBuilding,
341}
342
343impl Step {
344    fn unwrap_still_building(self) {
345        match self {
346            Step::Finished(_) => panic!(
347                "`Step::unwrap_still_building` called on a `Step` that is not `StillBuilding`"
348            ),
349            Step::StillBuilding => {}
350        }
351    }
352}
353
354impl ComponentBuilder {
355    fn new(config: Config) -> Self {
356        ComponentBuilder {
357            config,
358            core_valtypes: vec![],
359            types: vec![Default::default()],
360            components: vec![ComponentContext::empty()],
361            fill_minimums: false,
362            total_components: 0,
363            total_modules: 0,
364            total_instances: 0,
365            total_values: 0,
366        }
367    }
368
369    fn build(&mut self, u: &mut Unstructured) -> Result<Component> {
370        self.core_valtypes = crate::core::configured_valtypes(&self.config);
371
372        let mut choices: Vec<fn(&mut ComponentBuilder, &mut Unstructured) -> Result<Step>> = vec![];
373
374        loop {
375            choices.clear();
376            choices.push(Self::finish_component);
377
378            // Only add any choice other than "finish what we've generated thus
379            // far" when there is more arbitrary fuzzer data for us to consume.
380            if !u.is_empty() {
381                choices.push(Self::arbitrary_custom_section);
382
383                // NB: we add each section as a choice even if we've already
384                // generated our maximum number of entities in that section so that
385                // we can exercise adding empty sections to the end of the module.
386                choices.push(Self::arbitrary_core_type_section);
387                choices.push(Self::arbitrary_type_section);
388                choices.push(Self::arbitrary_import_section);
389                choices.push(Self::arbitrary_canonical_section);
390
391                if self.total_modules < self.config.max_modules {
392                    choices.push(Self::arbitrary_core_module_section);
393                }
394
395                if self.components.len() < self.config.max_nesting_depth
396                    && self.total_components < self.config.max_components
397                {
398                    choices.push(Self::arbitrary_component_section);
399                }
400
401                // FIXME(#1000)
402                //
403                // choices.push(Self::arbitrary_instance_section);
404                // choices.push(Self::arbitrary_export_section);
405                // choices.push(Self::arbitrary_start_section);
406                // choices.push(Self::arbitrary_alias_section);
407            }
408
409            let f = u.choose(&choices)?;
410            match f(self, u)? {
411                Step::StillBuilding => {}
412                Step::Finished(component) => {
413                    if self.components.is_empty() {
414                        // If we just finished the root component, then return it.
415                        return Ok(component);
416                    } else {
417                        // Otherwise, add it as a nested component in the parent.
418                        self.push_section(Section::Component(component));
419                    }
420                }
421            }
422        }
423    }
424
425    fn finish_component(&mut self, u: &mut Unstructured) -> Result<Step> {
426        // Ensure we've generated all of our minimums.
427        self.fill_minimums = true;
428        {
429            if self.current_type_scope().types.len() < self.config.min_types {
430                self.arbitrary_type_section(u)?.unwrap_still_building();
431            }
432            if self.component().num_imports < self.config.min_imports {
433                self.arbitrary_import_section(u)?.unwrap_still_building();
434            }
435            if self.component().funcs.len() < self.config.min_funcs {
436                self.arbitrary_canonical_section(u)?.unwrap_still_building();
437            }
438        }
439        self.fill_minimums = false;
440
441        self.types
442            .pop()
443            .expect("should have a types scope for the component we are finishing");
444        Ok(Step::Finished(self.components.pop().unwrap().component))
445    }
446
447    fn component(&self) -> &ComponentContext {
448        self.components.last().unwrap()
449    }
450
451    fn component_mut(&mut self) -> &mut ComponentContext {
452        self.components.last_mut().unwrap()
453    }
454
455    fn last_section(&self) -> Option<&Section> {
456        self.component().component.sections.last()
457    }
458
459    fn last_section_mut(&mut self) -> Option<&mut Section> {
460        self.component_mut().component.sections.last_mut()
461    }
462
463    fn push_section(&mut self, section: Section) {
464        self.component_mut().component.sections.push(section);
465    }
466
467    fn ensure_section(
468        &mut self,
469        mut predicate: impl FnMut(&Section) -> bool,
470        mut make_section: impl FnMut() -> Section,
471    ) -> &mut Section {
472        match self.last_section() {
473            Some(sec) if predicate(sec) => {}
474            _ => self.push_section(make_section()),
475        }
476        self.last_section_mut().unwrap()
477    }
478
479    fn arbitrary_custom_section(&mut self, u: &mut Unstructured) -> Result<Step> {
480        self.push_section(Section::Custom(u.arbitrary()?));
481        Ok(Step::StillBuilding)
482    }
483
484    fn push_type(&mut self, ty: Rc<Type>) -> u32 {
485        match self.ensure_section(
486            |s| matches!(s, Section::Type(_)),
487            || Section::Type(TypeSection { types: vec![] }),
488        ) {
489            Section::Type(TypeSection { types }) => {
490                types.push(ty.clone());
491                self.current_type_scope_mut().push(ty)
492            }
493            _ => unreachable!(),
494        }
495    }
496
497    fn push_core_type(&mut self, ty: Rc<CoreType>) -> u32 {
498        match self.ensure_section(
499            |s| matches!(s, Section::CoreType(_)),
500            || Section::CoreType(CoreTypeSection { types: vec![] }),
501        ) {
502            Section::CoreType(CoreTypeSection { types }) => {
503                types.push(ty.clone());
504                self.current_type_scope_mut().push_core(ty)
505            }
506            _ => unreachable!(),
507        }
508    }
509
510    fn arbitrary_core_type_section(&mut self, u: &mut Unstructured) -> Result<Step> {
511        self.push_section(Section::CoreType(CoreTypeSection { types: vec![] }));
512
513        let min = if self.fill_minimums {
514            self.config
515                .min_types
516                .saturating_sub(self.current_type_scope().types.len())
517        } else {
518            0
519        };
520
521        let max = self.config.max_types - self.current_type_scope().types.len();
522
523        arbitrary_loop(u, min, max, |u| {
524            let mut type_fuel = self.config.max_type_size;
525            let ty = self.arbitrary_core_type(u, &mut type_fuel)?;
526            self.push_core_type(ty);
527            Ok(true)
528        })?;
529
530        Ok(Step::StillBuilding)
531    }
532
533    fn arbitrary_core_type(
534        &self,
535        u: &mut Unstructured,
536        type_fuel: &mut u32,
537    ) -> Result<Rc<CoreType>> {
538        *type_fuel = type_fuel.saturating_sub(1);
539        if *type_fuel == 0 {
540            return Ok(Rc::new(CoreType::Module(Rc::new(ModuleType::default()))));
541        }
542
543        let ty = match u.int_in_range::<u8>(0..=1)? {
544            0 => CoreType::Func(arbitrary_func_type(
545                u,
546                &self.config,
547                &self.core_valtypes,
548                if self.config.multi_value_enabled {
549                    None
550                } else {
551                    Some(1)
552                },
553                0,
554            )?),
555            1 => CoreType::Module(self.arbitrary_module_type(u, type_fuel)?),
556            _ => unreachable!(),
557        };
558        Ok(Rc::new(ty))
559    }
560
561    fn arbitrary_type_section(&mut self, u: &mut Unstructured) -> Result<Step> {
562        self.push_section(Section::Type(TypeSection { types: vec![] }));
563
564        let min = if self.fill_minimums {
565            self.config
566                .min_types
567                .saturating_sub(self.current_type_scope().types.len())
568        } else {
569            0
570        };
571
572        let max = self.config.max_types - self.current_type_scope().types.len();
573
574        arbitrary_loop(u, min, max, |u| {
575            let mut type_fuel = self.config.max_type_size;
576            let ty = self.arbitrary_type(u, &mut type_fuel)?;
577            self.push_type(ty);
578            Ok(true)
579        })?;
580
581        Ok(Step::StillBuilding)
582    }
583
584    fn arbitrary_type_ref<'a>(
585        &self,
586        u: &mut Unstructured<'a>,
587        for_import: bool,
588        for_type_def: bool,
589    ) -> Result<Option<ComponentTypeRef>> {
590        let mut choices: Vec<fn(&Self, &mut Unstructured) -> Result<ComponentTypeRef>> = Vec::new();
591        let scope = self.current_type_scope();
592
593        if !scope.module_types.is_empty()
594            && (for_type_def || !for_import || self.total_modules < self.config.max_modules)
595        {
596            choices.push(|me, u| {
597                Ok(ComponentTypeRef::Module(
598                    *u.choose(&me.current_type_scope().module_types)?,
599                ))
600            });
601        }
602
603        // Types cannot be imported currently
604        if !for_import
605            && !scope.types.is_empty()
606            && (for_type_def || scope.types.len() < self.config.max_types)
607        {
608            choices.push(|me, u| {
609                Ok(ComponentTypeRef::Type(TypeBounds::Eq(u.int_in_range(
610                    0..=u32::try_from(me.current_type_scope().types.len() - 1).unwrap(),
611                )?)))
612            });
613        }
614
615        // TODO: wasm-smith needs to ensure that every arbitrary value gets used exactly once.
616        //       until that time, don't import values
617        // if for_type_def || !for_import || self.total_values < self.config.max_values() {
618        //     choices.push(|me, u| Ok(ComponentTypeRef::Value(me.arbitrary_component_val_type(u)?)));
619        // }
620
621        if !scope.func_types.is_empty()
622            && (for_type_def || !for_import || self.component().num_funcs() < self.config.max_funcs)
623        {
624            choices.push(|me, u| {
625                Ok(ComponentTypeRef::Func(
626                    *u.choose(&me.current_type_scope().func_types)?,
627                ))
628            });
629        }
630
631        if !scope.component_types.is_empty()
632            && (for_type_def || !for_import || self.total_components < self.config.max_components)
633        {
634            choices.push(|me, u| {
635                Ok(ComponentTypeRef::Component(
636                    *u.choose(&me.current_type_scope().component_types)?,
637                ))
638            });
639        }
640
641        if !scope.instance_types.is_empty()
642            && (for_type_def || !for_import || self.total_instances < self.config.max_instances)
643        {
644            choices.push(|me, u| {
645                Ok(ComponentTypeRef::Instance(
646                    *u.choose(&me.current_type_scope().instance_types)?,
647                ))
648            });
649        }
650
651        if choices.is_empty() {
652            return Ok(None);
653        }
654
655        let f = u.choose(&choices)?;
656        f(self, u).map(Option::Some)
657    }
658
659    fn arbitrary_type(&mut self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<Rc<Type>> {
660        *type_fuel = type_fuel.saturating_sub(1);
661        if *type_fuel == 0 {
662            return Ok(Rc::new(Type::Defined(
663                self.arbitrary_defined_type(u, type_fuel)?,
664            )));
665        }
666
667        let ty = match u.int_in_range::<u8>(0..=3)? {
668            0 => Type::Defined(self.arbitrary_defined_type(u, type_fuel)?),
669            1 => Type::Func(self.arbitrary_func_type(u, type_fuel)?),
670            2 => Type::Component(self.arbitrary_component_type(u, type_fuel)?),
671            3 => Type::Instance(self.arbitrary_instance_type(u, type_fuel)?),
672            _ => unreachable!(),
673        };
674        Ok(Rc::new(ty))
675    }
676
677    fn arbitrary_module_type(
678        &self,
679        u: &mut Unstructured,
680        type_fuel: &mut u32,
681    ) -> Result<Rc<ModuleType>> {
682        let mut defs = vec![];
683        let mut has_memory = false;
684        let mut has_canonical_abi_realloc = false;
685        let mut has_canonical_abi_free = false;
686        let mut types: Vec<Rc<crate::core::FuncType>> = vec![];
687        let mut imports = HashMap::new();
688        let mut exports = HashSet::new();
689        let mut counts = EntityCounts::default();
690
691        // Special case the canonical ABI functions since certain types can only
692        // be passed across the component boundary if they exist and
693        // randomly generating them is extremely unlikely.
694
695        // `memory`
696        if counts.memories < self.config.max_memories && u.ratio::<u8>(99, 100)? {
697            defs.push(ModuleTypeDef::Export(
698                "memory".into(),
699                crate::core::EntityType::Memory(self.arbitrary_core_memory_type(u)?),
700            ));
701            exports.insert("memory".into());
702            counts.memories += 1;
703            has_memory = true;
704        }
705
706        // `canonical_abi_realloc`
707        if counts.funcs < self.config.max_funcs
708            && types.len() < self.config.max_types
709            && u.ratio::<u8>(99, 100)?
710        {
711            let realloc_ty = Rc::new(crate::core::FuncType {
712                params: vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32],
713                results: vec![ValType::I32],
714            });
715            let ty_idx = u32::try_from(types.len()).unwrap();
716            types.push(realloc_ty.clone());
717            defs.push(ModuleTypeDef::TypeDef(
718                crate::core::CompositeType::new_func(
719                    realloc_ty.clone(),
720                    false, // TODO: handle shared
721                ),
722            ));
723            defs.push(ModuleTypeDef::Export(
724                "canonical_abi_realloc".into(),
725                crate::core::EntityType::Func(ty_idx, realloc_ty),
726            ));
727            exports.insert("canonical_abi_realloc".into());
728            counts.funcs += 1;
729            has_canonical_abi_realloc = true;
730        }
731
732        // `canonical_abi_free`
733        if counts.funcs < self.config.max_funcs
734            && types.len() < self.config.max_types
735            && u.ratio::<u8>(99, 100)?
736        {
737            let free_ty = Rc::new(crate::core::FuncType {
738                params: vec![ValType::I32, ValType::I32, ValType::I32],
739                results: vec![],
740            });
741            let ty_idx = u32::try_from(types.len()).unwrap();
742            types.push(free_ty.clone());
743            defs.push(ModuleTypeDef::TypeDef(
744                crate::core::CompositeType::new_func(
745                    free_ty.clone(),
746                    false, // TODO: handle shared
747                ),
748            ));
749            defs.push(ModuleTypeDef::Export(
750                "canonical_abi_free".into(),
751                crate::core::EntityType::Func(ty_idx, free_ty),
752            ));
753            exports.insert("canonical_abi_free".into());
754            counts.funcs += 1;
755            has_canonical_abi_free = true;
756        }
757
758        let mut entity_choices: Vec<
759            fn(
760                &ComponentBuilder,
761                &mut Unstructured,
762                &mut EntityCounts,
763                &[Rc<crate::core::FuncType>],
764            ) -> Result<crate::core::EntityType>,
765        > = Vec::with_capacity(5);
766
767        arbitrary_loop(u, 0, 100, |u| {
768            *type_fuel = type_fuel.saturating_sub(1);
769            if *type_fuel == 0 {
770                return Ok(false);
771            }
772
773            let max_choice = if types.len() < self.config.max_types {
774                // Check if the parent scope has core function types to alias
775                if !types.is_empty()
776                    || (!self.types.is_empty()
777                        && !self.types.last().unwrap().core_func_types.is_empty())
778                {
779                    // Imports, exports, types, and aliases
780                    3
781                } else {
782                    // Imports, exports, and types
783                    2
784                }
785            } else {
786                // Imports and exports
787                1
788            };
789
790            match u.int_in_range::<u8>(0..=max_choice)? {
791                // Import.
792                0 => {
793                    let module = crate::limited_string(100, u)?;
794                    let existing_module_imports = imports.entry(module.clone()).or_default();
795                    let field = crate::unique_string(100, existing_module_imports, u)?;
796                    let entity_type = match self.arbitrary_core_entity_type(
797                        u,
798                        &types,
799                        &mut entity_choices,
800                        &mut counts,
801                    )? {
802                        None => return Ok(false),
803                        Some(x) => x,
804                    };
805                    defs.push(ModuleTypeDef::Import(crate::core::Import {
806                        module,
807                        field,
808                        entity_type,
809                    }));
810                }
811
812                // Export.
813                1 => {
814                    let name = crate::unique_string(100, &mut exports, u)?;
815                    let entity_ty = match self.arbitrary_core_entity_type(
816                        u,
817                        &types,
818                        &mut entity_choices,
819                        &mut counts,
820                    )? {
821                        None => return Ok(false),
822                        Some(x) => x,
823                    };
824                    defs.push(ModuleTypeDef::Export(name, entity_ty));
825                }
826
827                // Type definition.
828                2 => {
829                    let ty = arbitrary_func_type(
830                        u,
831                        &self.config,
832                        &self.core_valtypes,
833                        if self.config.multi_value_enabled {
834                            None
835                        } else {
836                            Some(1)
837                        },
838                        0,
839                    )?;
840                    types.push(ty.clone());
841                    defs.push(ModuleTypeDef::TypeDef(
842                        crate::core::CompositeType::new_func(ty, false),
843                    )); // TODO: handle shared
844                }
845
846                // Alias
847                3 => {
848                    let (count, index, kind) = self.arbitrary_outer_core_type_alias(u, &types)?;
849                    let ty = match &kind {
850                        CoreOuterAliasKind::Type(ty) => ty.clone(),
851                    };
852                    types.push(ty);
853                    defs.push(ModuleTypeDef::OuterAlias {
854                        count,
855                        i: index,
856                        kind,
857                    });
858                }
859
860                _ => unreachable!(),
861            }
862
863            Ok(true)
864        })?;
865
866        Ok(Rc::new(ModuleType {
867            defs,
868            has_memory,
869            has_canonical_abi_realloc,
870            has_canonical_abi_free,
871        }))
872    }
873
874    fn arbitrary_core_entity_type(
875        &self,
876        u: &mut Unstructured,
877        types: &[Rc<crate::core::FuncType>],
878        choices: &mut Vec<
879            fn(
880                &ComponentBuilder,
881                &mut Unstructured,
882                &mut EntityCounts,
883                &[Rc<crate::core::FuncType>],
884            ) -> Result<crate::core::EntityType>,
885        >,
886        counts: &mut EntityCounts,
887    ) -> Result<Option<crate::core::EntityType>> {
888        choices.clear();
889
890        if counts.globals < self.config.max_globals {
891            choices.push(|c, u, counts, _types| {
892                counts.globals += 1;
893                Ok(crate::core::EntityType::Global(
894                    c.arbitrary_core_global_type(u)?,
895                ))
896            });
897        }
898
899        if counts.tables < self.config.max_tables {
900            choices.push(|c, u, counts, _types| {
901                counts.tables += 1;
902                Ok(crate::core::EntityType::Table(
903                    c.arbitrary_core_table_type(u)?,
904                ))
905            });
906        }
907
908        if counts.memories < self.config.max_memories {
909            choices.push(|c, u, counts, _types| {
910                counts.memories += 1;
911                Ok(crate::core::EntityType::Memory(
912                    c.arbitrary_core_memory_type(u)?,
913                ))
914            });
915        }
916
917        if types.iter().any(|ty| ty.results.is_empty())
918            && self.config.exceptions_enabled
919            && counts.tags < self.config.max_tags
920        {
921            choices.push(|c, u, counts, types| {
922                counts.tags += 1;
923                let tag_func_types = types
924                    .iter()
925                    .enumerate()
926                    .filter(|(_, ty)| ty.results.is_empty())
927                    .map(|(i, _)| u32::try_from(i).unwrap())
928                    .collect::<Vec<_>>();
929                Ok(crate::core::EntityType::Tag(
930                    crate::core::arbitrary_tag_type(u, &tag_func_types, |idx| {
931                        types[usize::try_from(idx).unwrap()].clone()
932                    })?,
933                ))
934            });
935        }
936
937        if !types.is_empty() && counts.funcs < self.config.max_funcs {
938            choices.push(|c, u, counts, types| {
939                counts.funcs += 1;
940                let ty_idx = u.int_in_range(0..=u32::try_from(types.len() - 1).unwrap())?;
941                let ty = types[ty_idx as usize].clone();
942                Ok(crate::core::EntityType::Func(ty_idx, ty))
943            });
944        }
945
946        if choices.is_empty() {
947            return Ok(None);
948        }
949
950        let f = u.choose(choices)?;
951        let ty = f(self, u, counts, types)?;
952        Ok(Some(ty))
953    }
954
955    fn arbitrary_core_valtype(&self, u: &mut Unstructured) -> Result<ValType> {
956        Ok(*u.choose(&self.core_valtypes)?)
957    }
958
959    fn arbitrary_core_global_type(&self, u: &mut Unstructured) -> Result<crate::core::GlobalType> {
960        Ok(crate::core::GlobalType {
961            val_type: self.arbitrary_core_valtype(u)?,
962            mutable: u.arbitrary()?,
963            shared: false,
964        })
965    }
966
967    fn arbitrary_core_table_type(&self, u: &mut Unstructured) -> Result<crate::core::TableType> {
968        crate::core::arbitrary_table_type(u, &self.config, None)
969    }
970
971    fn arbitrary_core_memory_type(&self, u: &mut Unstructured) -> Result<crate::core::MemoryType> {
972        crate::core::arbitrary_memtype(u, &self.config)
973    }
974
975    fn with_types_scope<T>(&mut self, f: impl FnOnce(&mut Self) -> Result<T>) -> Result<T> {
976        self.types.push(Default::default());
977        let result = f(self);
978        self.types.pop();
979        result
980    }
981
982    fn current_type_scope(&self) -> &TypesScope {
983        self.types.last().unwrap()
984    }
985
986    fn current_type_scope_mut(&mut self) -> &mut TypesScope {
987        self.types.last_mut().unwrap()
988    }
989
990    fn outer_types_scope(&self, count: u32) -> &TypesScope {
991        &self.types[self.types.len() - 1 - usize::try_from(count).unwrap()]
992    }
993
994    fn outer_type(&self, count: u32, i: u32) -> &Rc<Type> {
995        &self.outer_types_scope(count).types[usize::try_from(i).unwrap()]
996    }
997
998    fn arbitrary_component_type(
999        &mut self,
1000        u: &mut Unstructured,
1001        type_fuel: &mut u32,
1002    ) -> Result<Rc<ComponentType>> {
1003        let mut defs = vec![];
1004        let mut imports = HashSet::new();
1005        let mut import_urls = HashSet::new();
1006        let mut exports = HashSet::new();
1007        let mut export_urls = HashSet::new();
1008
1009        self.with_types_scope(|me| {
1010            arbitrary_loop(u, 0, 100, |u| {
1011                *type_fuel = type_fuel.saturating_sub(1);
1012                if *type_fuel == 0 {
1013                    return Ok(false);
1014                }
1015
1016                if me.current_type_scope().can_ref_type() && u.int_in_range::<u8>(0..=3)? == 0 {
1017                    if let Some(ty) = me.arbitrary_type_ref(u, true, true)? {
1018                        // Imports.
1019                        let name = crate::unique_kebab_string(100, &mut imports, u)?;
1020                        let url = if u.arbitrary()? {
1021                            Some(crate::unique_url(100, &mut import_urls, u)?)
1022                        } else {
1023                            None
1024                        };
1025                        defs.push(ComponentTypeDef::Import(Import { name, url, ty }));
1026                        return Ok(true);
1027                    }
1028
1029                    // Can't reference an arbitrary type, fallback to another definition.
1030                }
1031
1032                // Type definitions, exports, and aliases.
1033                let def =
1034                    me.arbitrary_instance_type_def(u, &mut exports, &mut export_urls, type_fuel)?;
1035                defs.push(def.into());
1036                Ok(true)
1037            })
1038        })?;
1039
1040        Ok(Rc::new(ComponentType { defs }))
1041    }
1042
1043    fn arbitrary_instance_type(
1044        &mut self,
1045        u: &mut Unstructured,
1046        type_fuel: &mut u32,
1047    ) -> Result<Rc<InstanceType>> {
1048        let mut defs = vec![];
1049        let mut exports = HashSet::new();
1050        let mut export_urls = HashSet::new();
1051
1052        self.with_types_scope(|me| {
1053            arbitrary_loop(u, 0, 100, |u| {
1054                *type_fuel = type_fuel.saturating_sub(1);
1055                if *type_fuel == 0 {
1056                    return Ok(false);
1057                }
1058
1059                defs.push(me.arbitrary_instance_type_def(
1060                    u,
1061                    &mut exports,
1062                    &mut export_urls,
1063                    type_fuel,
1064                )?);
1065                Ok(true)
1066            })
1067        })?;
1068
1069        Ok(Rc::new(InstanceType { defs }))
1070    }
1071
1072    fn arbitrary_instance_type_def(
1073        &mut self,
1074        u: &mut Unstructured,
1075        exports: &mut HashSet<String>,
1076        export_urls: &mut HashSet<String>,
1077        type_fuel: &mut u32,
1078    ) -> Result<InstanceTypeDecl> {
1079        let mut choices: Vec<
1080            fn(
1081                &mut ComponentBuilder,
1082                &mut HashSet<String>,
1083                &mut HashSet<String>,
1084                &mut Unstructured,
1085                &mut u32,
1086            ) -> Result<InstanceTypeDecl>,
1087        > = Vec::with_capacity(3);
1088
1089        // Export.
1090        if self.current_type_scope().can_ref_type() {
1091            choices.push(|me, exports, export_urls, u, _type_fuel| {
1092                let ty = me.arbitrary_type_ref(u, false, true)?.unwrap();
1093                if let ComponentTypeRef::Type(TypeBounds::Eq(idx)) = ty {
1094                    let ty = me.current_type_scope().get(idx).clone();
1095                    me.current_type_scope_mut().push(ty);
1096                }
1097                Ok(InstanceTypeDecl::Export {
1098                    name: crate::unique_kebab_string(100, exports, u)?,
1099                    url: if u.arbitrary()? {
1100                        Some(crate::unique_url(100, export_urls, u)?)
1101                    } else {
1102                        None
1103                    },
1104                    ty,
1105                })
1106            });
1107        }
1108
1109        // Outer type alias.
1110        if self
1111            .types
1112            .iter()
1113            .any(|scope| !scope.types.is_empty() || !scope.core_types.is_empty())
1114        {
1115            choices.push(|me, _exports, _export_urls, u, _type_fuel| {
1116                let alias = me.arbitrary_outer_type_alias(u)?;
1117                match &alias {
1118                    Alias::Outer {
1119                        kind: OuterAliasKind::Type(ty),
1120                        ..
1121                    } => me.current_type_scope_mut().push(ty.clone()),
1122                    Alias::Outer {
1123                        kind: OuterAliasKind::CoreType(ty),
1124                        ..
1125                    } => me.current_type_scope_mut().push_core(ty.clone()),
1126                    _ => unreachable!(),
1127                };
1128                Ok(InstanceTypeDecl::Alias(alias))
1129            });
1130        }
1131
1132        // Core type definition.
1133        choices.push(|me, _exports, _export_urls, u, type_fuel| {
1134            let ty = me.arbitrary_core_type(u, type_fuel)?;
1135            me.current_type_scope_mut().push_core(ty.clone());
1136            Ok(InstanceTypeDecl::CoreType(ty))
1137        });
1138
1139        // Type definition.
1140        if self.types.len() < self.config.max_nesting_depth {
1141            choices.push(|me, _exports, _export_urls, u, type_fuel| {
1142                let ty = me.arbitrary_type(u, type_fuel)?;
1143                me.current_type_scope_mut().push(ty.clone());
1144                Ok(InstanceTypeDecl::Type(ty))
1145            });
1146        }
1147
1148        let f = u.choose(&choices)?;
1149        f(self, exports, export_urls, u, type_fuel)
1150    }
1151
1152    fn arbitrary_outer_core_type_alias(
1153        &self,
1154        u: &mut Unstructured,
1155        local_types: &[Rc<crate::core::FuncType>],
1156    ) -> Result<(u32, u32, CoreOuterAliasKind)> {
1157        let enclosing_type_len = if !self.types.is_empty() {
1158            self.types.last().unwrap().core_func_types.len()
1159        } else {
1160            0
1161        };
1162
1163        assert!(!local_types.is_empty() || enclosing_type_len > 0);
1164
1165        let max = enclosing_type_len + local_types.len() - 1;
1166        let i = u.int_in_range(0..=max)?;
1167        let (count, index, ty) = if i < enclosing_type_len {
1168            let enclosing = self.types.last().unwrap();
1169            let index = enclosing.core_func_types[i];
1170            (
1171                1,
1172                index,
1173                match enclosing.get_core(index).as_ref() {
1174                    CoreType::Func(ty) => ty.clone(),
1175                    CoreType::Module(_) => unreachable!(),
1176                },
1177            )
1178        } else if i - enclosing_type_len < local_types.len() {
1179            let i = i - enclosing_type_len;
1180            (0, u32::try_from(i).unwrap(), local_types[i].clone())
1181        } else {
1182            unreachable!()
1183        };
1184
1185        Ok((count, index, CoreOuterAliasKind::Type(ty)))
1186    }
1187
1188    fn arbitrary_outer_type_alias(&self, u: &mut Unstructured) -> Result<Alias> {
1189        let non_empty_types_scopes: Vec<_> = self
1190            .types
1191            .iter()
1192            .rev()
1193            .enumerate()
1194            .filter(|(_, scope)| !scope.types.is_empty() || !scope.core_types.is_empty())
1195            .collect();
1196        assert!(
1197            !non_empty_types_scopes.is_empty(),
1198            "precondition: there are non-empty types scopes"
1199        );
1200
1201        let (count, scope) = u.choose(&non_empty_types_scopes)?;
1202        let count = u32::try_from(*count).unwrap();
1203        assert!(!scope.types.is_empty() || !scope.core_types.is_empty());
1204
1205        let max_type_in_scope = scope.types.len() + scope.core_types.len() - 1;
1206        let i = u.int_in_range(0..=max_type_in_scope)?;
1207
1208        let (i, kind) = if i < scope.types.len() {
1209            let i = u32::try_from(i).unwrap();
1210            (i, OuterAliasKind::Type(Rc::clone(scope.get(i))))
1211        } else if i - scope.types.len() < scope.core_types.len() {
1212            let i = u32::try_from(i - scope.types.len()).unwrap();
1213            (i, OuterAliasKind::CoreType(Rc::clone(scope.get_core(i))))
1214        } else {
1215            unreachable!()
1216        };
1217
1218        Ok(Alias::Outer { count, i, kind })
1219    }
1220
1221    fn arbitrary_func_type(
1222        &self,
1223        u: &mut Unstructured,
1224        type_fuel: &mut u32,
1225    ) -> Result<Rc<FuncType>> {
1226        let mut params = Vec::new();
1227        let mut results = Vec::new();
1228        let mut names = HashSet::new();
1229
1230        // Note: parameters are currently limited to a maximum of 16
1231        // because any additional parameters will require indirect access
1232        // via a pointer argument; when this occurs, validation of any
1233        // lowered function will fail because it will be missing a
1234        // memory option (not yet implemented).
1235        //
1236        // When options are correctly specified on canonical functions,
1237        // we should increase this maximum to test indirect parameter
1238        // passing.
1239        arbitrary_loop(u, 0, 16, |u| {
1240            *type_fuel = type_fuel.saturating_sub(1);
1241            if *type_fuel == 0 {
1242                return Ok(false);
1243            }
1244
1245            let name = crate::unique_kebab_string(100, &mut names, u)?;
1246            let ty = self.arbitrary_component_val_type(u)?;
1247
1248            params.push((name, ty));
1249
1250            Ok(true)
1251        })?;
1252
1253        names.clear();
1254
1255        // Likewise, the limit for results is 1 before the memory option is
1256        // required. When the memory option is implemented, this restriction
1257        // should be relaxed.
1258        arbitrary_loop(u, 0, 1, |u| {
1259            *type_fuel = type_fuel.saturating_sub(1);
1260            if *type_fuel == 0 {
1261                return Ok(false);
1262            }
1263
1264            // If the result list is empty (i.e. first push), then arbitrarily give
1265            // the result a name. Otherwise, all of the subsequent items must be named.
1266            let name = if results.is_empty() {
1267                // Most of the time we should have a single, unnamed result.
1268                u.ratio::<u8>(10, 100)?
1269                    .then(|| crate::unique_kebab_string(100, &mut names, u))
1270                    .transpose()?
1271            } else {
1272                Some(crate::unique_kebab_string(100, &mut names, u)?)
1273            };
1274
1275            let ty = self.arbitrary_component_val_type(u)?;
1276
1277            results.push((name, ty));
1278
1279            // There can be only one unnamed result.
1280            if results.len() == 1 && results[0].0.is_none() {
1281                return Ok(false);
1282            }
1283
1284            Ok(true)
1285        })?;
1286
1287        Ok(Rc::new(FuncType { params, results }))
1288    }
1289
1290    fn arbitrary_component_val_type(&self, u: &mut Unstructured) -> Result<ComponentValType> {
1291        let max_choices = if self.current_type_scope().defined_types.is_empty() {
1292            0
1293        } else {
1294            1
1295        };
1296        match u.int_in_range(0..=max_choices)? {
1297            0 => Ok(ComponentValType::Primitive(
1298                self.arbitrary_primitive_val_type(u)?,
1299            )),
1300            1 => {
1301                let index = *u.choose(&self.current_type_scope().defined_types)?;
1302                let ty = Rc::clone(self.current_type_scope().get(index));
1303                Ok(ComponentValType::Type(index))
1304            }
1305            _ => unreachable!(),
1306        }
1307    }
1308
1309    fn arbitrary_primitive_val_type(&self, u: &mut Unstructured) -> Result<PrimitiveValType> {
1310        match u.int_in_range(0..=12)? {
1311            0 => Ok(PrimitiveValType::Bool),
1312            1 => Ok(PrimitiveValType::S8),
1313            2 => Ok(PrimitiveValType::U8),
1314            3 => Ok(PrimitiveValType::S16),
1315            4 => Ok(PrimitiveValType::U16),
1316            5 => Ok(PrimitiveValType::S32),
1317            6 => Ok(PrimitiveValType::U32),
1318            7 => Ok(PrimitiveValType::S64),
1319            8 => Ok(PrimitiveValType::U64),
1320            9 => Ok(PrimitiveValType::F32),
1321            10 => Ok(PrimitiveValType::F64),
1322            11 => Ok(PrimitiveValType::Char),
1323            12 => Ok(PrimitiveValType::String),
1324            _ => unreachable!(),
1325        }
1326    }
1327
1328    fn arbitrary_record_type(
1329        &self,
1330        u: &mut Unstructured,
1331        type_fuel: &mut u32,
1332    ) -> Result<RecordType> {
1333        let mut fields = vec![];
1334        let mut field_names = HashSet::new();
1335        arbitrary_loop(u, 0, 100, |u| {
1336            *type_fuel = type_fuel.saturating_sub(1);
1337            if *type_fuel == 0 {
1338                return Ok(false);
1339            }
1340
1341            let name = crate::unique_kebab_string(100, &mut field_names, u)?;
1342            let ty = self.arbitrary_component_val_type(u)?;
1343
1344            fields.push((name, ty));
1345            Ok(true)
1346        })?;
1347        Ok(RecordType { fields })
1348    }
1349
1350    fn arbitrary_variant_type(
1351        &self,
1352        u: &mut Unstructured,
1353        type_fuel: &mut u32,
1354    ) -> Result<VariantType> {
1355        let mut cases = vec![];
1356        let mut case_names = HashSet::new();
1357        arbitrary_loop(u, 1, 100, |u| {
1358            *type_fuel = type_fuel.saturating_sub(1);
1359            if *type_fuel == 0 {
1360                return Ok(false);
1361            }
1362
1363            let name = crate::unique_kebab_string(100, &mut case_names, u)?;
1364
1365            let ty = u
1366                .arbitrary::<bool>()?
1367                .then(|| self.arbitrary_component_val_type(u))
1368                .transpose()?;
1369
1370            let refines = if !cases.is_empty() && u.arbitrary()? {
1371                let max_cases = u32::try_from(cases.len() - 1).unwrap();
1372                Some(u.int_in_range(0..=max_cases)?)
1373            } else {
1374                None
1375            };
1376
1377            cases.push((name, ty, refines));
1378            Ok(true)
1379        })?;
1380
1381        Ok(VariantType { cases })
1382    }
1383
1384    fn arbitrary_list_type(&self, u: &mut Unstructured) -> Result<ListType> {
1385        Ok(ListType {
1386            elem_ty: self.arbitrary_component_val_type(u)?,
1387        })
1388    }
1389
1390    fn arbitrary_tuple_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<TupleType> {
1391        let mut fields = vec![];
1392        arbitrary_loop(u, 0, 100, |u| {
1393            *type_fuel = type_fuel.saturating_sub(1);
1394            if *type_fuel == 0 {
1395                return Ok(false);
1396            }
1397
1398            fields.push(self.arbitrary_component_val_type(u)?);
1399            Ok(true)
1400        })?;
1401        Ok(TupleType { fields })
1402    }
1403
1404    fn arbitrary_flags_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<FlagsType> {
1405        let mut fields = vec![];
1406        let mut field_names = HashSet::new();
1407        arbitrary_loop(u, 0, 100, |u| {
1408            *type_fuel = type_fuel.saturating_sub(1);
1409            if *type_fuel == 0 {
1410                return Ok(false);
1411            }
1412
1413            fields.push(crate::unique_kebab_string(100, &mut field_names, u)?);
1414            Ok(true)
1415        })?;
1416        Ok(FlagsType { fields })
1417    }
1418
1419    fn arbitrary_enum_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<EnumType> {
1420        let mut variants = vec![];
1421        let mut variant_names = HashSet::new();
1422        arbitrary_loop(u, 1, 100, |u| {
1423            *type_fuel = type_fuel.saturating_sub(1);
1424            if *type_fuel == 0 {
1425                return Ok(false);
1426            }
1427
1428            variants.push(crate::unique_kebab_string(100, &mut variant_names, u)?);
1429            Ok(true)
1430        })?;
1431        Ok(EnumType { variants })
1432    }
1433
1434    fn arbitrary_option_type(&self, u: &mut Unstructured) -> Result<OptionType> {
1435        Ok(OptionType {
1436            inner_ty: self.arbitrary_component_val_type(u)?,
1437        })
1438    }
1439
1440    fn arbitrary_result_type(&self, u: &mut Unstructured) -> Result<ResultType> {
1441        Ok(ResultType {
1442            ok_ty: u
1443                .arbitrary::<bool>()?
1444                .then(|| self.arbitrary_component_val_type(u))
1445                .transpose()?,
1446            err_ty: u
1447                .arbitrary::<bool>()?
1448                .then(|| self.arbitrary_component_val_type(u))
1449                .transpose()?,
1450        })
1451    }
1452
1453    fn arbitrary_defined_type(
1454        &self,
1455        u: &mut Unstructured,
1456        type_fuel: &mut u32,
1457    ) -> Result<DefinedType> {
1458        match u.int_in_range(0..=8)? {
1459            0 => Ok(DefinedType::Primitive(
1460                self.arbitrary_primitive_val_type(u)?,
1461            )),
1462            1 => Ok(DefinedType::Record(
1463                self.arbitrary_record_type(u, type_fuel)?,
1464            )),
1465            2 => Ok(DefinedType::Variant(
1466                self.arbitrary_variant_type(u, type_fuel)?,
1467            )),
1468            3 => Ok(DefinedType::List(self.arbitrary_list_type(u)?)),
1469            4 => Ok(DefinedType::Tuple(self.arbitrary_tuple_type(u, type_fuel)?)),
1470            5 => Ok(DefinedType::Flags(self.arbitrary_flags_type(u, type_fuel)?)),
1471            6 => Ok(DefinedType::Enum(self.arbitrary_enum_type(u, type_fuel)?)),
1472            7 => Ok(DefinedType::Option(self.arbitrary_option_type(u)?)),
1473            8 => Ok(DefinedType::Result(self.arbitrary_result_type(u)?)),
1474            _ => unreachable!(),
1475        }
1476    }
1477
1478    fn push_import(&mut self, name: String, url: Option<String>, ty: ComponentTypeRef) {
1479        let nth = match self.ensure_section(
1480            |sec| matches!(sec, Section::Import(_)),
1481            || Section::Import(ImportSection { imports: vec![] }),
1482        ) {
1483            Section::Import(sec) => {
1484                sec.imports.push(Import { name, url, ty });
1485                sec.imports.len() - 1
1486            }
1487            _ => unreachable!(),
1488        };
1489        let section_index = self.component().component.sections.len() - 1;
1490
1491        match ty {
1492            ComponentTypeRef::Module(_) => {
1493                self.total_modules += 1;
1494                self.component_mut().modules.push((section_index, nth));
1495            }
1496            ComponentTypeRef::Func(ty_index) => {
1497                let func_ty = match self.current_type_scope().get(ty_index).as_ref() {
1498                    Type::Func(ty) => ty.clone(),
1499                    _ => unreachable!(),
1500                };
1501
1502                if func_ty.is_scalar() {
1503                    let func_index = u32::try_from(self.component().component_funcs.len()).unwrap();
1504                    self.component_mut().scalar_component_funcs.push(func_index);
1505                }
1506
1507                let func_index = u32::try_from(self.component().funcs.len()).unwrap();
1508                self.component_mut()
1509                    .funcs
1510                    .push(ComponentOrCoreFuncType::Component(func_ty));
1511
1512                self.component_mut().component_funcs.push(func_index);
1513            }
1514            ComponentTypeRef::Value(ty) => {
1515                self.total_values += 1;
1516                self.component_mut().values.push(ty);
1517            }
1518            ComponentTypeRef::Type(TypeBounds::Eq(ty_index)) => {
1519                let ty = self.current_type_scope().get(ty_index).clone();
1520                self.current_type_scope_mut().push(ty);
1521            }
1522            ComponentTypeRef::Type(TypeBounds::SubResource) => {
1523                unimplemented!()
1524            }
1525            ComponentTypeRef::Instance(ty_index) => {
1526                let instance_ty = match self.current_type_scope().get(ty_index).as_ref() {
1527                    Type::Instance(ty) => ty.clone(),
1528                    _ => unreachable!(),
1529                };
1530
1531                self.total_instances += 1;
1532                self.component_mut()
1533                    .instances
1534                    .push(ComponentOrCoreInstanceType::Component(instance_ty));
1535            }
1536            ComponentTypeRef::Component(_) => {
1537                self.total_components += 1;
1538                self.component_mut().components.push((section_index, nth));
1539            }
1540        }
1541    }
1542
1543    fn core_function_type(&self, core_func_index: u32) -> &Rc<crate::core::FuncType> {
1544        self.component().funcs[self.component().core_funcs[core_func_index as usize] as usize]
1545            .as_core()
1546    }
1547
1548    fn component_function_type(&self, func_index: u32) -> &Rc<FuncType> {
1549        self.component().funcs[self.component().component_funcs[func_index as usize] as usize]
1550            .as_component()
1551    }
1552
1553    fn push_func(&mut self, func: Func) {
1554        let nth = match self.component_mut().component.sections.last_mut() {
1555            Some(Section::Canonical(CanonicalSection { funcs })) => funcs.len(),
1556            _ => {
1557                self.push_section(Section::Canonical(CanonicalSection { funcs: vec![] }));
1558                0
1559            }
1560        };
1561        let section_index = self.component().component.sections.len() - 1;
1562
1563        let func_index = u32::try_from(self.component().funcs.len()).unwrap();
1564
1565        let ty = match &func {
1566            Func::CanonLift { func_ty, .. } => {
1567                let ty = Rc::clone(self.current_type_scope().get_func(*func_ty));
1568                if ty.is_scalar() {
1569                    let func_index = u32::try_from(self.component().component_funcs.len()).unwrap();
1570                    self.component_mut().scalar_component_funcs.push(func_index);
1571                }
1572                self.component_mut().component_funcs.push(func_index);
1573                ComponentOrCoreFuncType::Component(ty)
1574            }
1575            Func::CanonLower {
1576                func_index: comp_func_index,
1577                ..
1578            } => {
1579                let comp_func_ty = self.component_function_type(*comp_func_index);
1580                let core_func_ty = canonical_abi_for(comp_func_ty);
1581                self.component_mut().core_funcs.push(func_index);
1582                ComponentOrCoreFuncType::Core(core_func_ty)
1583            }
1584        };
1585
1586        self.component_mut().funcs.push(ty);
1587
1588        match self.component_mut().component.sections.last_mut() {
1589            Some(Section::Canonical(CanonicalSection { funcs })) => funcs.push(func),
1590            _ => unreachable!(),
1591        }
1592    }
1593
1594    fn arbitrary_import_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1595        self.push_section(Section::Import(ImportSection { imports: vec![] }));
1596
1597        let min = if self.fill_minimums {
1598            self.config
1599                .min_imports
1600                .saturating_sub(self.component().num_imports)
1601        } else {
1602            // Allow generating empty sections. We can always fill in the required
1603            // minimum later.
1604            0
1605        };
1606        let max = self.config.max_imports - self.component().num_imports;
1607
1608        crate::arbitrary_loop(u, min, max, |u| {
1609            match self.arbitrary_type_ref(u, true, false)? {
1610                Some(ty) => {
1611                    let name =
1612                        crate::unique_kebab_string(100, &mut self.component_mut().import_names, u)?;
1613                    let url = if u.arbitrary()? {
1614                        Some(crate::unique_url(
1615                            100,
1616                            &mut self.component_mut().import_urls,
1617                            u,
1618                        )?)
1619                    } else {
1620                        None
1621                    };
1622                    self.push_import(name, url, ty);
1623                    Ok(true)
1624                }
1625                None => Ok(false),
1626            }
1627        })?;
1628
1629        Ok(Step::StillBuilding)
1630    }
1631
1632    fn arbitrary_canonical_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1633        self.push_section(Section::Canonical(CanonicalSection { funcs: vec![] }));
1634
1635        let min = if self.fill_minimums {
1636            self.config
1637                .min_funcs
1638                .saturating_sub(self.component().funcs.len())
1639        } else {
1640            // Allow generating empty sections. We can always fill in the
1641            // required minimum later.
1642            0
1643        };
1644        let max = self.config.max_funcs - self.component().funcs.len();
1645
1646        let mut choices: Vec<fn(&mut Unstructured, &mut ComponentBuilder) -> Result<Option<Func>>> =
1647            Vec::with_capacity(2);
1648
1649        crate::arbitrary_loop(u, min, max, |u| {
1650            choices.clear();
1651
1652            // NB: We only lift/lower scalar component functions.
1653            //
1654            // If we generated lifting and lowering of compound value types,
1655            // the probability of generating a corresponding Wasm module that
1656            // generates valid instances of the compound value types would
1657            // be vanishingly tiny (e.g. for `list<string>` we would have to
1658            // generate a core Wasm module that correctly produces a pointer and
1659            // length for a memory region that itself is a series of pointers
1660            // and lengths of valid strings, as well as `canonical_abi_realloc`
1661            // and `canonical_abi_free` functions that do the right thing).
1662            //
1663            // This is a pretty serious limitation of `wasm-smith`'s component
1664            // types support, but it is one we are intentionally
1665            // accepting. `wasm-smith` will focus on generating arbitrary
1666            // component sections, structures, and import/export topologies; not
1667            // component functions and core Wasm implementations of component
1668            // functions. In the future, we intend to build a new, distinct test
1669            // case generator specifically for exercising component functions
1670            // and the canonical ABI. This new generator won't emit arbitrary
1671            // component sections, structures, or import/export topologies, and
1672            // will instead leave that to `wasm-smith`.
1673
1674            if !self.component().scalar_component_funcs.is_empty() {
1675                choices.push(|u, c| {
1676                    let func_index = *u.choose(&c.component().scalar_component_funcs)?;
1677                    Ok(Some(Func::CanonLower {
1678                        // Scalar component functions don't use any canonical options.
1679                        options: vec![],
1680                        func_index,
1681                    }))
1682                });
1683            }
1684
1685            if !self.component().core_funcs.is_empty() {
1686                choices.push(|u, c| {
1687                    let core_func_index = u.int_in_range(
1688                        0..=u32::try_from(c.component().core_funcs.len() - 1).unwrap(),
1689                    )?;
1690                    let core_func_ty = c.core_function_type(core_func_index);
1691                    let comp_func_ty = inverse_scalar_canonical_abi_for(u, core_func_ty)?;
1692
1693                    let func_ty = if let Some(indices) = c
1694                        .current_type_scope()
1695                        .func_type_to_indices
1696                        .get(&comp_func_ty)
1697                    {
1698                        // If we've already defined this component function type
1699                        // one or more times, then choose one of those
1700                        // definitions arbitrarily.
1701                        debug_assert!(!indices.is_empty());
1702                        *u.choose(indices)?
1703                    } else if c.current_type_scope().types.len() < c.config.max_types {
1704                        // If we haven't already defined this component function
1705                        // type, and we haven't defined the configured maximum
1706                        // amount of types yet, then just define this type.
1707                        let ty = Rc::new(Type::Func(Rc::new(comp_func_ty)));
1708                        c.push_type(ty)
1709                    } else {
1710                        // Otherwise, give up on lifting this function.
1711                        return Ok(None);
1712                    };
1713
1714                    Ok(Some(Func::CanonLift {
1715                        func_ty,
1716                        // Scalar functions don't use any canonical options.
1717                        options: vec![],
1718                        core_func_index,
1719                    }))
1720                });
1721            }
1722
1723            if choices.is_empty() {
1724                return Ok(false);
1725            }
1726
1727            let f = u.choose(&choices)?;
1728            if let Some(func) = f(u, self)? {
1729                self.push_func(func);
1730            }
1731
1732            Ok(true)
1733        })?;
1734
1735        Ok(Step::StillBuilding)
1736    }
1737
1738    fn arbitrary_core_module_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1739        let module = crate::core::Module::new_internal(
1740            self.config.clone(),
1741            u,
1742            crate::core::DuplicateImportsBehavior::Disallowed,
1743        )?;
1744        self.push_section(Section::CoreModule(module));
1745        self.total_modules += 1;
1746        Ok(Step::StillBuilding)
1747    }
1748
1749    fn arbitrary_component_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1750        self.types.push(TypesScope::default());
1751        self.components.push(ComponentContext::empty());
1752        self.total_components += 1;
1753        Ok(Step::StillBuilding)
1754    }
1755
1756    fn arbitrary_instance_section(&mut self, u: &mut Unstructured) -> Result<()> {
1757        todo!()
1758    }
1759
1760    fn arbitrary_export_section(&mut self, u: &mut Unstructured) -> Result<()> {
1761        todo!()
1762    }
1763
1764    fn arbitrary_start_section(&mut self, u: &mut Unstructured) -> Result<()> {
1765        todo!()
1766    }
1767
1768    fn arbitrary_alias_section(&mut self, u: &mut Unstructured) -> Result<()> {
1769        todo!()
1770    }
1771}
1772
1773fn canonical_abi_for(func_ty: &FuncType) -> Rc<crate::core::FuncType> {
1774    let to_core_ty = |ty| match ty {
1775        ComponentValType::Primitive(prim_ty) => match prim_ty {
1776            PrimitiveValType::Char
1777            | PrimitiveValType::Bool
1778            | PrimitiveValType::S8
1779            | PrimitiveValType::U8
1780            | PrimitiveValType::S16
1781            | PrimitiveValType::U16
1782            | PrimitiveValType::S32
1783            | PrimitiveValType::U32 => ValType::I32,
1784            PrimitiveValType::S64 | PrimitiveValType::U64 => ValType::I64,
1785            PrimitiveValType::F32 => ValType::F32,
1786            PrimitiveValType::F64 => ValType::F64,
1787            PrimitiveValType::String => {
1788                unimplemented!("non-scalar types are not supported yet")
1789            }
1790        },
1791        ComponentValType::Type(_) => unimplemented!("non-scalar types are not supported yet"),
1792    };
1793
1794    Rc::new(crate::core::FuncType {
1795        params: func_ty
1796            .params
1797            .iter()
1798            .map(|(_, ty)| to_core_ty(*ty))
1799            .collect(),
1800        results: func_ty
1801            .results
1802            .iter()
1803            .map(|(_, ty)| to_core_ty(*ty))
1804            .collect(),
1805    })
1806}
1807
1808fn inverse_scalar_canonical_abi_for(
1809    u: &mut Unstructured,
1810    core_func_ty: &crate::core::FuncType,
1811) -> Result<FuncType> {
1812    let from_core_ty = |u: &mut Unstructured, core_ty| match core_ty {
1813        ValType::I32 => u
1814            .choose(&[
1815                ComponentValType::Primitive(PrimitiveValType::Char),
1816                ComponentValType::Primitive(PrimitiveValType::Bool),
1817                ComponentValType::Primitive(PrimitiveValType::S8),
1818                ComponentValType::Primitive(PrimitiveValType::U8),
1819                ComponentValType::Primitive(PrimitiveValType::S16),
1820                ComponentValType::Primitive(PrimitiveValType::U16),
1821                ComponentValType::Primitive(PrimitiveValType::S32),
1822                ComponentValType::Primitive(PrimitiveValType::U32),
1823            ])
1824            .cloned(),
1825        ValType::I64 => u
1826            .choose(&[
1827                ComponentValType::Primitive(PrimitiveValType::S64),
1828                ComponentValType::Primitive(PrimitiveValType::U64),
1829            ])
1830            .cloned(),
1831        ValType::F32 => Ok(ComponentValType::Primitive(PrimitiveValType::F32)),
1832        ValType::F64 => Ok(ComponentValType::Primitive(PrimitiveValType::F64)),
1833        ValType::V128 | ValType::Ref(_) => {
1834            unreachable!("not used in canonical ABI")
1835        }
1836    };
1837
1838    let mut names = HashSet::default();
1839    let mut params = vec![];
1840
1841    for core_ty in &core_func_ty.params {
1842        params.push((
1843            crate::unique_kebab_string(100, &mut names, u)?,
1844            from_core_ty(u, *core_ty)?,
1845        ));
1846    }
1847
1848    names.clear();
1849
1850    let results = match core_func_ty.results.len() {
1851        0 => Vec::new(),
1852        1 => vec![(
1853            if u.arbitrary()? {
1854                Some(crate::unique_kebab_string(100, &mut names, u)?)
1855            } else {
1856                None
1857            },
1858            from_core_ty(u, core_func_ty.results[0])?,
1859        )],
1860        _ => unimplemented!("non-scalar types are not supported yet"),
1861    };
1862
1863    Ok(FuncType { params, results })
1864}
1865
1866#[derive(Debug)]
1867enum Section {
1868    Custom(CustomSection),
1869    CoreModule(crate::Module),
1870    CoreInstance(CoreInstanceSection),
1871    CoreType(CoreTypeSection),
1872    Component(Component),
1873    Instance(InstanceSection),
1874    Alias(AliasSection),
1875    Type(TypeSection),
1876    Canonical(CanonicalSection),
1877    Start(StartSection),
1878    Import(ImportSection),
1879    Export(ExportSection),
1880}
1881
1882#[derive(Debug)]
1883struct CustomSection {
1884    name: String,
1885    data: Vec<u8>,
1886}
1887
1888impl<'a> Arbitrary<'a> for CustomSection {
1889    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1890        let name = crate::limited_string(1_000, u)?;
1891        let data = u.arbitrary()?;
1892        Ok(CustomSection { name, data })
1893    }
1894}
1895
1896#[derive(Debug)]
1897struct TypeSection {
1898    types: Vec<Rc<Type>>,
1899}
1900
1901#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1902enum CoreType {
1903    Func(Rc<crate::core::FuncType>),
1904    Module(Rc<ModuleType>),
1905}
1906
1907#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
1908struct ModuleType {
1909    defs: Vec<ModuleTypeDef>,
1910    has_memory: bool,
1911    has_canonical_abi_realloc: bool,
1912    has_canonical_abi_free: bool,
1913}
1914
1915#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1916enum ModuleTypeDef {
1917    TypeDef(crate::core::CompositeType),
1918    Import(crate::core::Import),
1919    OuterAlias {
1920        count: u32,
1921        i: u32,
1922        kind: CoreOuterAliasKind,
1923    },
1924    Export(String, crate::core::EntityType),
1925}
1926
1927#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1928enum Type {
1929    Defined(DefinedType),
1930    Func(Rc<FuncType>),
1931    Component(Rc<ComponentType>),
1932    Instance(Rc<InstanceType>),
1933}
1934
1935#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1936enum CoreInstanceExportAliasKind {
1937    Func,
1938    Table,
1939    Memory,
1940    Global,
1941    Tag,
1942}
1943
1944#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1945enum CoreOuterAliasKind {
1946    Type(Rc<crate::core::FuncType>),
1947}
1948
1949#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1950enum Alias {
1951    InstanceExport {
1952        instance: u32,
1953        name: String,
1954        kind: InstanceExportAliasKind,
1955    },
1956    CoreInstanceExport {
1957        instance: u32,
1958        name: String,
1959        kind: CoreInstanceExportAliasKind,
1960    },
1961    Outer {
1962        count: u32,
1963        i: u32,
1964        kind: OuterAliasKind,
1965    },
1966}
1967
1968#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1969enum InstanceExportAliasKind {
1970    Module,
1971    Component,
1972    Instance,
1973    Func,
1974    Value,
1975}
1976
1977#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1978enum OuterAliasKind {
1979    Module,
1980    Component,
1981    CoreType(Rc<CoreType>),
1982    Type(Rc<Type>),
1983}
1984
1985#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1986struct ComponentType {
1987    defs: Vec<ComponentTypeDef>,
1988}
1989
1990#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1991enum ComponentTypeDef {
1992    CoreType(Rc<CoreType>),
1993    Type(Rc<Type>),
1994    Alias(Alias),
1995    Import(Import),
1996    Export {
1997        name: String,
1998        url: Option<String>,
1999        ty: ComponentTypeRef,
2000    },
2001}
2002
2003impl From<InstanceTypeDecl> for ComponentTypeDef {
2004    fn from(def: InstanceTypeDecl) -> Self {
2005        match def {
2006            InstanceTypeDecl::CoreType(t) => Self::CoreType(t),
2007            InstanceTypeDecl::Type(t) => Self::Type(t),
2008            InstanceTypeDecl::Export { name, url, ty } => Self::Export { name, url, ty },
2009            InstanceTypeDecl::Alias(a) => Self::Alias(a),
2010        }
2011    }
2012}
2013
2014#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2015struct InstanceType {
2016    defs: Vec<InstanceTypeDecl>,
2017}
2018
2019#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2020enum InstanceTypeDecl {
2021    CoreType(Rc<CoreType>),
2022    Type(Rc<Type>),
2023    Alias(Alias),
2024    Export {
2025        name: String,
2026        url: Option<String>,
2027        ty: ComponentTypeRef,
2028    },
2029}
2030
2031#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2032struct FuncType {
2033    params: Vec<(String, ComponentValType)>,
2034    results: Vec<(Option<String>, ComponentValType)>,
2035}
2036
2037impl FuncType {
2038    fn unnamed_result_ty(&self) -> Option<ComponentValType> {
2039        if self.results.len() == 1 {
2040            let (name, ty) = &self.results[0];
2041            if name.is_none() {
2042                return Some(*ty);
2043            }
2044        }
2045        None
2046    }
2047
2048    fn is_scalar(&self) -> bool {
2049        self.params.iter().all(|(_, ty)| is_scalar(ty))
2050            && self.results.len() == 1
2051            && is_scalar(&self.results[0].1)
2052    }
2053}
2054
2055fn is_scalar(ty: &ComponentValType) -> bool {
2056    match ty {
2057        ComponentValType::Primitive(prim) => match prim {
2058            PrimitiveValType::Bool
2059            | PrimitiveValType::S8
2060            | PrimitiveValType::U8
2061            | PrimitiveValType::S16
2062            | PrimitiveValType::U16
2063            | PrimitiveValType::S32
2064            | PrimitiveValType::U32
2065            | PrimitiveValType::S64
2066            | PrimitiveValType::U64
2067            | PrimitiveValType::F32
2068            | PrimitiveValType::F64
2069            | PrimitiveValType::Char => true,
2070            PrimitiveValType::String => false,
2071        },
2072        ComponentValType::Type(_) => false,
2073    }
2074}
2075
2076#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2077enum DefinedType {
2078    Primitive(PrimitiveValType),
2079    Record(RecordType),
2080    Variant(VariantType),
2081    List(ListType),
2082    Tuple(TupleType),
2083    Flags(FlagsType),
2084    Enum(EnumType),
2085    Option(OptionType),
2086    Result(ResultType),
2087}
2088
2089#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2090struct RecordType {
2091    fields: Vec<(String, ComponentValType)>,
2092}
2093
2094#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2095struct VariantType {
2096    cases: Vec<(String, Option<ComponentValType>, Option<u32>)>,
2097}
2098
2099#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2100struct ListType {
2101    elem_ty: ComponentValType,
2102}
2103
2104#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2105struct TupleType {
2106    fields: Vec<ComponentValType>,
2107}
2108
2109#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2110struct FlagsType {
2111    fields: Vec<String>,
2112}
2113
2114#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2115struct EnumType {
2116    variants: Vec<String>,
2117}
2118
2119#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2120struct OptionType {
2121    inner_ty: ComponentValType,
2122}
2123
2124#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2125struct ResultType {
2126    ok_ty: Option<ComponentValType>,
2127    err_ty: Option<ComponentValType>,
2128}
2129
2130#[derive(Debug)]
2131struct ImportSection {
2132    imports: Vec<Import>,
2133}
2134
2135#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2136struct Import {
2137    name: String,
2138    url: Option<String>,
2139    ty: ComponentTypeRef,
2140}
2141
2142#[derive(Debug)]
2143struct CanonicalSection {
2144    funcs: Vec<Func>,
2145}
2146
2147#[derive(Debug)]
2148enum Func {
2149    CanonLift {
2150        func_ty: u32,
2151        options: Vec<CanonOpt>,
2152        core_func_index: u32,
2153    },
2154    CanonLower {
2155        options: Vec<CanonOpt>,
2156        func_index: u32,
2157    },
2158}
2159
2160#[derive(Debug)]
2161enum CanonOpt {
2162    StringUtf8,
2163    StringUtf16,
2164    StringLatin1Utf16,
2165    Memory(u32),
2166    Realloc(u32),
2167    PostReturn(u32),
2168}
2169
2170#[derive(Debug)]
2171struct InstanceSection {}
2172
2173#[derive(Debug)]
2174struct ExportSection {}
2175
2176#[derive(Debug)]
2177struct StartSection {}
2178
2179#[derive(Debug)]
2180struct AliasSection {}
2181
2182#[derive(Debug)]
2183struct CoreInstanceSection {}
2184
2185#[derive(Debug)]
2186struct CoreTypeSection {
2187    types: Vec<Rc<CoreType>>,
2188}
2189
2190fn arbitrary_func_type(
2191    u: &mut Unstructured,
2192    config: &Config,
2193    valtypes: &[ValType],
2194    max_results: Option<usize>,
2195    type_ref_limit: u32,
2196) -> Result<Rc<crate::core::FuncType>> {
2197    let mut params = vec![];
2198    let mut results = vec![];
2199    arbitrary_loop(u, 0, 20, |u| {
2200        params.push(arbitrary_valtype(u, config, valtypes, type_ref_limit)?);
2201        Ok(true)
2202    })?;
2203    arbitrary_loop(u, 0, max_results.unwrap_or(20), |u| {
2204        results.push(arbitrary_valtype(u, config, valtypes, type_ref_limit)?);
2205        Ok(true)
2206    })?;
2207    Ok(Rc::new(crate::core::FuncType { params, results }))
2208}
2209
2210fn arbitrary_valtype(
2211    u: &mut Unstructured,
2212    config: &Config,
2213    valtypes: &[ValType],
2214    type_ref_limit: u32,
2215) -> Result<ValType> {
2216    if config.gc_enabled && type_ref_limit > 0 && u.ratio(1, 20)? {
2217        Ok(ValType::Ref(RefType {
2218            // TODO: For now, only create allow nullable reference
2219            // types. Eventually we should support non-nullable reference types,
2220            // but this means that we will also need to recognize when it is
2221            // impossible to create an instance of the reference (eg `(ref
2222            // nofunc)` has no instances, and self-referential types that
2223            // contain a non-null self-reference are also impossible to create).
2224            nullable: true,
2225            heap_type: HeapType::Concrete(u.int_in_range(0..=type_ref_limit - 1)?),
2226        }))
2227    } else {
2228        Ok(*u.choose(valtypes)?)
2229    }
2230}