Skip to main content

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::{Config, arbitrary_loop};
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/main/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 name = 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                        name,
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            cases.push((name, ty));
1371            Ok(true)
1372        })?;
1373
1374        Ok(VariantType { cases })
1375    }
1376
1377    fn arbitrary_list_type(&self, u: &mut Unstructured) -> Result<ListType> {
1378        Ok(ListType {
1379            elem_ty: self.arbitrary_component_val_type(u)?,
1380        })
1381    }
1382
1383    fn arbitrary_tuple_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<TupleType> {
1384        let mut fields = vec![];
1385        arbitrary_loop(u, 0, 100, |u| {
1386            *type_fuel = type_fuel.saturating_sub(1);
1387            if *type_fuel == 0 {
1388                return Ok(false);
1389            }
1390
1391            fields.push(self.arbitrary_component_val_type(u)?);
1392            Ok(true)
1393        })?;
1394        Ok(TupleType { fields })
1395    }
1396
1397    fn arbitrary_flags_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<FlagsType> {
1398        let mut fields = vec![];
1399        let mut field_names = HashSet::new();
1400        arbitrary_loop(u, 0, 100, |u| {
1401            *type_fuel = type_fuel.saturating_sub(1);
1402            if *type_fuel == 0 {
1403                return Ok(false);
1404            }
1405
1406            fields.push(crate::unique_kebab_string(100, &mut field_names, u)?);
1407            Ok(true)
1408        })?;
1409        Ok(FlagsType { fields })
1410    }
1411
1412    fn arbitrary_enum_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<EnumType> {
1413        let mut variants = vec![];
1414        let mut variant_names = HashSet::new();
1415        arbitrary_loop(u, 1, 100, |u| {
1416            *type_fuel = type_fuel.saturating_sub(1);
1417            if *type_fuel == 0 {
1418                return Ok(false);
1419            }
1420
1421            variants.push(crate::unique_kebab_string(100, &mut variant_names, u)?);
1422            Ok(true)
1423        })?;
1424        Ok(EnumType { variants })
1425    }
1426
1427    fn arbitrary_option_type(&self, u: &mut Unstructured) -> Result<OptionType> {
1428        Ok(OptionType {
1429            inner_ty: self.arbitrary_component_val_type(u)?,
1430        })
1431    }
1432
1433    fn arbitrary_result_type(&self, u: &mut Unstructured) -> Result<ResultType> {
1434        Ok(ResultType {
1435            ok_ty: u
1436                .arbitrary::<bool>()?
1437                .then(|| self.arbitrary_component_val_type(u))
1438                .transpose()?,
1439            err_ty: u
1440                .arbitrary::<bool>()?
1441                .then(|| self.arbitrary_component_val_type(u))
1442                .transpose()?,
1443        })
1444    }
1445
1446    fn arbitrary_defined_type(
1447        &self,
1448        u: &mut Unstructured,
1449        type_fuel: &mut u32,
1450    ) -> Result<DefinedType> {
1451        match u.int_in_range(0..=8)? {
1452            0 => Ok(DefinedType::Primitive(
1453                self.arbitrary_primitive_val_type(u)?,
1454            )),
1455            1 => Ok(DefinedType::Record(
1456                self.arbitrary_record_type(u, type_fuel)?,
1457            )),
1458            2 => Ok(DefinedType::Variant(
1459                self.arbitrary_variant_type(u, type_fuel)?,
1460            )),
1461            3 => Ok(DefinedType::List(self.arbitrary_list_type(u)?)),
1462            4 => Ok(DefinedType::Tuple(self.arbitrary_tuple_type(u, type_fuel)?)),
1463            5 => Ok(DefinedType::Flags(self.arbitrary_flags_type(u, type_fuel)?)),
1464            6 => Ok(DefinedType::Enum(self.arbitrary_enum_type(u, type_fuel)?)),
1465            7 => Ok(DefinedType::Option(self.arbitrary_option_type(u)?)),
1466            8 => Ok(DefinedType::Result(self.arbitrary_result_type(u)?)),
1467            _ => unreachable!(),
1468        }
1469    }
1470
1471    fn push_import(&mut self, name: String, url: Option<String>, ty: ComponentTypeRef) {
1472        let nth = match self.ensure_section(
1473            |sec| matches!(sec, Section::Import(_)),
1474            || Section::Import(ImportSection { imports: vec![] }),
1475        ) {
1476            Section::Import(sec) => {
1477                sec.imports.push(Import { name, url, ty });
1478                sec.imports.len() - 1
1479            }
1480            _ => unreachable!(),
1481        };
1482        let section_index = self.component().component.sections.len() - 1;
1483
1484        match ty {
1485            ComponentTypeRef::Module(_) => {
1486                self.total_modules += 1;
1487                self.component_mut().modules.push((section_index, nth));
1488            }
1489            ComponentTypeRef::Func(ty_index) => {
1490                let func_ty = match self.current_type_scope().get(ty_index).as_ref() {
1491                    Type::Func(ty) => ty.clone(),
1492                    _ => unreachable!(),
1493                };
1494
1495                if func_ty.is_scalar() {
1496                    let func_index = u32::try_from(self.component().component_funcs.len()).unwrap();
1497                    self.component_mut().scalar_component_funcs.push(func_index);
1498                }
1499
1500                let func_index = u32::try_from(self.component().funcs.len()).unwrap();
1501                self.component_mut()
1502                    .funcs
1503                    .push(ComponentOrCoreFuncType::Component(func_ty));
1504
1505                self.component_mut().component_funcs.push(func_index);
1506            }
1507            ComponentTypeRef::Value(ty) => {
1508                self.total_values += 1;
1509                self.component_mut().values.push(ty);
1510            }
1511            ComponentTypeRef::Type(TypeBounds::Eq(ty_index)) => {
1512                let ty = self.current_type_scope().get(ty_index).clone();
1513                self.current_type_scope_mut().push(ty);
1514            }
1515            ComponentTypeRef::Type(TypeBounds::SubResource) => {
1516                unimplemented!()
1517            }
1518            ComponentTypeRef::Instance(ty_index) => {
1519                let instance_ty = match self.current_type_scope().get(ty_index).as_ref() {
1520                    Type::Instance(ty) => ty.clone(),
1521                    _ => unreachable!(),
1522                };
1523
1524                self.total_instances += 1;
1525                self.component_mut()
1526                    .instances
1527                    .push(ComponentOrCoreInstanceType::Component(instance_ty));
1528            }
1529            ComponentTypeRef::Component(_) => {
1530                self.total_components += 1;
1531                self.component_mut().components.push((section_index, nth));
1532            }
1533        }
1534    }
1535
1536    fn core_function_type(&self, core_func_index: u32) -> &Rc<crate::core::FuncType> {
1537        self.component().funcs[self.component().core_funcs[core_func_index as usize] as usize]
1538            .as_core()
1539    }
1540
1541    fn component_function_type(&self, func_index: u32) -> &Rc<FuncType> {
1542        self.component().funcs[self.component().component_funcs[func_index as usize] as usize]
1543            .as_component()
1544    }
1545
1546    fn push_func(&mut self, func: Func) {
1547        let nth = match self.component_mut().component.sections.last_mut() {
1548            Some(Section::Canonical(CanonicalSection { funcs })) => funcs.len(),
1549            _ => {
1550                self.push_section(Section::Canonical(CanonicalSection { funcs: vec![] }));
1551                0
1552            }
1553        };
1554        let section_index = self.component().component.sections.len() - 1;
1555
1556        let func_index = u32::try_from(self.component().funcs.len()).unwrap();
1557
1558        let ty = match &func {
1559            Func::CanonLift { func_ty, .. } => {
1560                let ty = Rc::clone(self.current_type_scope().get_func(*func_ty));
1561                if ty.is_scalar() {
1562                    let func_index = u32::try_from(self.component().component_funcs.len()).unwrap();
1563                    self.component_mut().scalar_component_funcs.push(func_index);
1564                }
1565                self.component_mut().component_funcs.push(func_index);
1566                ComponentOrCoreFuncType::Component(ty)
1567            }
1568            Func::CanonLower {
1569                func_index: comp_func_index,
1570                ..
1571            } => {
1572                let comp_func_ty = self.component_function_type(*comp_func_index);
1573                let core_func_ty = canonical_abi_for(comp_func_ty);
1574                self.component_mut().core_funcs.push(func_index);
1575                ComponentOrCoreFuncType::Core(core_func_ty)
1576            }
1577        };
1578
1579        self.component_mut().funcs.push(ty);
1580
1581        match self.component_mut().component.sections.last_mut() {
1582            Some(Section::Canonical(CanonicalSection { funcs })) => funcs.push(func),
1583            _ => unreachable!(),
1584        }
1585    }
1586
1587    fn arbitrary_import_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1588        self.push_section(Section::Import(ImportSection { imports: vec![] }));
1589
1590        let min = if self.fill_minimums {
1591            self.config
1592                .min_imports
1593                .saturating_sub(self.component().num_imports)
1594        } else {
1595            // Allow generating empty sections. We can always fill in the required
1596            // minimum later.
1597            0
1598        };
1599        let max = self.config.max_imports - self.component().num_imports;
1600
1601        crate::arbitrary_loop(u, min, max, |u| {
1602            match self.arbitrary_type_ref(u, true, false)? {
1603                Some(ty) => {
1604                    let name =
1605                        crate::unique_kebab_string(100, &mut self.component_mut().import_names, u)?;
1606                    let url = if u.arbitrary()? {
1607                        Some(crate::unique_url(
1608                            100,
1609                            &mut self.component_mut().import_urls,
1610                            u,
1611                        )?)
1612                    } else {
1613                        None
1614                    };
1615                    self.push_import(name, url, ty);
1616                    Ok(true)
1617                }
1618                None => Ok(false),
1619            }
1620        })?;
1621
1622        Ok(Step::StillBuilding)
1623    }
1624
1625    fn arbitrary_canonical_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1626        self.push_section(Section::Canonical(CanonicalSection { funcs: vec![] }));
1627
1628        let min = if self.fill_minimums {
1629            self.config
1630                .min_funcs
1631                .saturating_sub(self.component().funcs.len())
1632        } else {
1633            // Allow generating empty sections. We can always fill in the
1634            // required minimum later.
1635            0
1636        };
1637        let max = self.config.max_funcs - self.component().funcs.len();
1638
1639        let mut choices: Vec<fn(&mut Unstructured, &mut ComponentBuilder) -> Result<Option<Func>>> =
1640            Vec::with_capacity(2);
1641
1642        crate::arbitrary_loop(u, min, max, |u| {
1643            choices.clear();
1644
1645            // NB: We only lift/lower scalar component functions.
1646            //
1647            // If we generated lifting and lowering of compound value types,
1648            // the probability of generating a corresponding Wasm module that
1649            // generates valid instances of the compound value types would
1650            // be vanishingly tiny (e.g. for `list<string>` we would have to
1651            // generate a core Wasm module that correctly produces a pointer and
1652            // length for a memory region that itself is a series of pointers
1653            // and lengths of valid strings, as well as `canonical_abi_realloc`
1654            // and `canonical_abi_free` functions that do the right thing).
1655            //
1656            // This is a pretty serious limitation of `wasm-smith`'s component
1657            // types support, but it is one we are intentionally
1658            // accepting. `wasm-smith` will focus on generating arbitrary
1659            // component sections, structures, and import/export topologies; not
1660            // component functions and core Wasm implementations of component
1661            // functions. In the future, we intend to build a new, distinct test
1662            // case generator specifically for exercising component functions
1663            // and the canonical ABI. This new generator won't emit arbitrary
1664            // component sections, structures, or import/export topologies, and
1665            // will instead leave that to `wasm-smith`.
1666
1667            if !self.component().scalar_component_funcs.is_empty() {
1668                choices.push(|u, c| {
1669                    let func_index = *u.choose(&c.component().scalar_component_funcs)?;
1670                    Ok(Some(Func::CanonLower {
1671                        // Scalar component functions don't use any canonical options.
1672                        options: vec![],
1673                        func_index,
1674                    }))
1675                });
1676            }
1677
1678            if !self.component().core_funcs.is_empty() {
1679                choices.push(|u, c| {
1680                    let core_func_index = u.int_in_range(
1681                        0..=u32::try_from(c.component().core_funcs.len() - 1).unwrap(),
1682                    )?;
1683                    let core_func_ty = c.core_function_type(core_func_index);
1684                    let comp_func_ty = inverse_scalar_canonical_abi_for(u, core_func_ty)?;
1685
1686                    let func_ty = if let Some(indices) = c
1687                        .current_type_scope()
1688                        .func_type_to_indices
1689                        .get(&comp_func_ty)
1690                    {
1691                        // If we've already defined this component function type
1692                        // one or more times, then choose one of those
1693                        // definitions arbitrarily.
1694                        debug_assert!(!indices.is_empty());
1695                        *u.choose(indices)?
1696                    } else if c.current_type_scope().types.len() < c.config.max_types {
1697                        // If we haven't already defined this component function
1698                        // type, and we haven't defined the configured maximum
1699                        // amount of types yet, then just define this type.
1700                        let ty = Rc::new(Type::Func(Rc::new(comp_func_ty)));
1701                        c.push_type(ty)
1702                    } else {
1703                        // Otherwise, give up on lifting this function.
1704                        return Ok(None);
1705                    };
1706
1707                    Ok(Some(Func::CanonLift {
1708                        func_ty,
1709                        // Scalar functions don't use any canonical options.
1710                        options: vec![],
1711                        core_func_index,
1712                    }))
1713                });
1714            }
1715
1716            if choices.is_empty() {
1717                return Ok(false);
1718            }
1719
1720            let f = u.choose(&choices)?;
1721            if let Some(func) = f(u, self)? {
1722                self.push_func(func);
1723            }
1724
1725            Ok(true)
1726        })?;
1727
1728        Ok(Step::StillBuilding)
1729    }
1730
1731    fn arbitrary_core_module_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1732        let module = crate::core::Module::new_internal(
1733            self.config.clone(),
1734            u,
1735            crate::core::DuplicateImportsBehavior::Disallowed,
1736        )?;
1737        self.push_section(Section::CoreModule(module));
1738        self.total_modules += 1;
1739        Ok(Step::StillBuilding)
1740    }
1741
1742    fn arbitrary_component_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1743        self.types.push(TypesScope::default());
1744        self.components.push(ComponentContext::empty());
1745        self.total_components += 1;
1746        Ok(Step::StillBuilding)
1747    }
1748
1749    fn arbitrary_instance_section(&mut self, u: &mut Unstructured) -> Result<()> {
1750        todo!()
1751    }
1752
1753    fn arbitrary_export_section(&mut self, u: &mut Unstructured) -> Result<()> {
1754        todo!()
1755    }
1756
1757    fn arbitrary_start_section(&mut self, u: &mut Unstructured) -> Result<()> {
1758        todo!()
1759    }
1760
1761    fn arbitrary_alias_section(&mut self, u: &mut Unstructured) -> Result<()> {
1762        todo!()
1763    }
1764}
1765
1766fn canonical_abi_for(func_ty: &FuncType) -> Rc<crate::core::FuncType> {
1767    let to_core_ty = |ty| match ty {
1768        ComponentValType::Primitive(prim_ty) => match prim_ty {
1769            PrimitiveValType::Char
1770            | PrimitiveValType::Bool
1771            | PrimitiveValType::S8
1772            | PrimitiveValType::U8
1773            | PrimitiveValType::S16
1774            | PrimitiveValType::U16
1775            | PrimitiveValType::S32
1776            | PrimitiveValType::U32 => ValType::I32,
1777            PrimitiveValType::S64 | PrimitiveValType::U64 => ValType::I64,
1778            PrimitiveValType::F32 => ValType::F32,
1779            PrimitiveValType::F64 => ValType::F64,
1780            PrimitiveValType::String | PrimitiveValType::ErrorContext => {
1781                unimplemented!("non-scalar types are not supported yet")
1782            }
1783        },
1784        ComponentValType::Type(_) => unimplemented!("non-scalar types are not supported yet"),
1785    };
1786
1787    Rc::new(crate::core::FuncType {
1788        params: func_ty
1789            .params
1790            .iter()
1791            .map(|(_, ty)| to_core_ty(*ty))
1792            .collect(),
1793        results: func_ty
1794            .results
1795            .iter()
1796            .map(|(_, ty)| to_core_ty(*ty))
1797            .collect(),
1798    })
1799}
1800
1801fn inverse_scalar_canonical_abi_for(
1802    u: &mut Unstructured,
1803    core_func_ty: &crate::core::FuncType,
1804) -> Result<FuncType> {
1805    let from_core_ty = |u: &mut Unstructured, core_ty| match core_ty {
1806        ValType::I32 => u
1807            .choose(&[
1808                ComponentValType::Primitive(PrimitiveValType::Char),
1809                ComponentValType::Primitive(PrimitiveValType::Bool),
1810                ComponentValType::Primitive(PrimitiveValType::S8),
1811                ComponentValType::Primitive(PrimitiveValType::U8),
1812                ComponentValType::Primitive(PrimitiveValType::S16),
1813                ComponentValType::Primitive(PrimitiveValType::U16),
1814                ComponentValType::Primitive(PrimitiveValType::S32),
1815                ComponentValType::Primitive(PrimitiveValType::U32),
1816            ])
1817            .cloned(),
1818        ValType::I64 => u
1819            .choose(&[
1820                ComponentValType::Primitive(PrimitiveValType::S64),
1821                ComponentValType::Primitive(PrimitiveValType::U64),
1822            ])
1823            .cloned(),
1824        ValType::F32 => Ok(ComponentValType::Primitive(PrimitiveValType::F32)),
1825        ValType::F64 => Ok(ComponentValType::Primitive(PrimitiveValType::F64)),
1826        ValType::V128 | ValType::Ref(_) => {
1827            unreachable!("not used in canonical ABI")
1828        }
1829    };
1830
1831    let mut names = HashSet::default();
1832    let mut params = vec![];
1833
1834    for core_ty in &core_func_ty.params {
1835        params.push((
1836            crate::unique_kebab_string(100, &mut names, u)?,
1837            from_core_ty(u, *core_ty)?,
1838        ));
1839    }
1840
1841    names.clear();
1842
1843    let results = match core_func_ty.results.len() {
1844        0 => Vec::new(),
1845        1 => vec![(
1846            if u.arbitrary()? {
1847                Some(crate::unique_kebab_string(100, &mut names, u)?)
1848            } else {
1849                None
1850            },
1851            from_core_ty(u, core_func_ty.results[0])?,
1852        )],
1853        _ => unimplemented!("non-scalar types are not supported yet"),
1854    };
1855
1856    Ok(FuncType { params, results })
1857}
1858
1859#[derive(Debug)]
1860enum Section {
1861    Custom(CustomSection),
1862    CoreModule(crate::Module),
1863    CoreInstance(CoreInstanceSection),
1864    CoreType(CoreTypeSection),
1865    Component(Component),
1866    Instance(InstanceSection),
1867    Alias(AliasSection),
1868    Type(TypeSection),
1869    Canonical(CanonicalSection),
1870    Start(StartSection),
1871    Import(ImportSection),
1872    Export(ExportSection),
1873}
1874
1875#[derive(Debug)]
1876struct CustomSection {
1877    name: String,
1878    data: Vec<u8>,
1879}
1880
1881impl<'a> Arbitrary<'a> for CustomSection {
1882    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1883        let name = crate::limited_string(1_000, u)?;
1884        let data = u.arbitrary()?;
1885        Ok(CustomSection { name, data })
1886    }
1887}
1888
1889#[derive(Debug)]
1890struct TypeSection {
1891    types: Vec<Rc<Type>>,
1892}
1893
1894#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1895enum CoreType {
1896    Func(Rc<crate::core::FuncType>),
1897    Module(Rc<ModuleType>),
1898}
1899
1900#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
1901struct ModuleType {
1902    defs: Vec<ModuleTypeDef>,
1903    has_memory: bool,
1904    has_canonical_abi_realloc: bool,
1905    has_canonical_abi_free: bool,
1906}
1907
1908#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1909enum ModuleTypeDef {
1910    TypeDef(crate::core::CompositeType),
1911    Import(crate::core::Import),
1912    OuterAlias {
1913        count: u32,
1914        i: u32,
1915        kind: CoreOuterAliasKind,
1916    },
1917    Export(String, crate::core::EntityType),
1918}
1919
1920#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1921enum Type {
1922    Defined(DefinedType),
1923    Func(Rc<FuncType>),
1924    Component(Rc<ComponentType>),
1925    Instance(Rc<InstanceType>),
1926}
1927
1928#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1929enum CoreInstanceExportAliasKind {
1930    Func,
1931    Table,
1932    Memory,
1933    Global,
1934    Tag,
1935}
1936
1937#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1938enum CoreOuterAliasKind {
1939    Type(Rc<crate::core::FuncType>),
1940}
1941
1942#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1943enum Alias {
1944    InstanceExport {
1945        instance: u32,
1946        name: String,
1947        kind: InstanceExportAliasKind,
1948    },
1949    CoreInstanceExport {
1950        instance: u32,
1951        name: String,
1952        kind: CoreInstanceExportAliasKind,
1953    },
1954    Outer {
1955        count: u32,
1956        i: u32,
1957        kind: OuterAliasKind,
1958    },
1959}
1960
1961#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1962enum InstanceExportAliasKind {
1963    Module,
1964    Component,
1965    Instance,
1966    Func,
1967    Value,
1968}
1969
1970#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1971enum OuterAliasKind {
1972    Module,
1973    Component,
1974    CoreType(Rc<CoreType>),
1975    Type(Rc<Type>),
1976}
1977
1978#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1979struct ComponentType {
1980    defs: Vec<ComponentTypeDef>,
1981}
1982
1983#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1984enum ComponentTypeDef {
1985    CoreType(Rc<CoreType>),
1986    Type(Rc<Type>),
1987    Alias(Alias),
1988    Import(Import),
1989    Export {
1990        name: String,
1991        url: Option<String>,
1992        ty: ComponentTypeRef,
1993    },
1994}
1995
1996impl From<InstanceTypeDecl> for ComponentTypeDef {
1997    fn from(def: InstanceTypeDecl) -> Self {
1998        match def {
1999            InstanceTypeDecl::CoreType(t) => Self::CoreType(t),
2000            InstanceTypeDecl::Type(t) => Self::Type(t),
2001            InstanceTypeDecl::Export { name, url, ty } => Self::Export { name, url, ty },
2002            InstanceTypeDecl::Alias(a) => Self::Alias(a),
2003        }
2004    }
2005}
2006
2007#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2008struct InstanceType {
2009    defs: Vec<InstanceTypeDecl>,
2010}
2011
2012#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2013enum InstanceTypeDecl {
2014    CoreType(Rc<CoreType>),
2015    Type(Rc<Type>),
2016    Alias(Alias),
2017    Export {
2018        name: String,
2019        url: Option<String>,
2020        ty: ComponentTypeRef,
2021    },
2022}
2023
2024#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2025struct FuncType {
2026    params: Vec<(String, ComponentValType)>,
2027    results: Vec<(Option<String>, ComponentValType)>,
2028}
2029
2030impl FuncType {
2031    fn unnamed_result_ty(&self) -> Option<ComponentValType> {
2032        if self.results.len() == 1 {
2033            let (name, ty) = &self.results[0];
2034            if name.is_none() {
2035                return Some(*ty);
2036            }
2037        }
2038        None
2039    }
2040
2041    fn is_scalar(&self) -> bool {
2042        self.params.iter().all(|(_, ty)| is_scalar(ty))
2043            && self.results.len() == 1
2044            && is_scalar(&self.results[0].1)
2045    }
2046}
2047
2048fn is_scalar(ty: &ComponentValType) -> bool {
2049    match ty {
2050        ComponentValType::Primitive(prim) => match prim {
2051            PrimitiveValType::Bool
2052            | PrimitiveValType::S8
2053            | PrimitiveValType::U8
2054            | PrimitiveValType::S16
2055            | PrimitiveValType::U16
2056            | PrimitiveValType::S32
2057            | PrimitiveValType::U32
2058            | PrimitiveValType::S64
2059            | PrimitiveValType::U64
2060            | PrimitiveValType::F32
2061            | PrimitiveValType::F64
2062            | PrimitiveValType::Char => true,
2063            PrimitiveValType::String | PrimitiveValType::ErrorContext => false,
2064        },
2065        ComponentValType::Type(_) => false,
2066    }
2067}
2068
2069#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2070enum DefinedType {
2071    Primitive(PrimitiveValType),
2072    Record(RecordType),
2073    Variant(VariantType),
2074    List(ListType),
2075    Tuple(TupleType),
2076    Flags(FlagsType),
2077    Enum(EnumType),
2078    Option(OptionType),
2079    Result(ResultType),
2080}
2081
2082#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2083struct RecordType {
2084    fields: Vec<(String, ComponentValType)>,
2085}
2086
2087#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2088struct VariantType {
2089    cases: Vec<(String, Option<ComponentValType>)>,
2090}
2091
2092#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2093struct ListType {
2094    elem_ty: ComponentValType,
2095}
2096
2097#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2098struct TupleType {
2099    fields: Vec<ComponentValType>,
2100}
2101
2102#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2103struct FlagsType {
2104    fields: Vec<String>,
2105}
2106
2107#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2108struct EnumType {
2109    variants: Vec<String>,
2110}
2111
2112#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2113struct OptionType {
2114    inner_ty: ComponentValType,
2115}
2116
2117#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2118struct ResultType {
2119    ok_ty: Option<ComponentValType>,
2120    err_ty: Option<ComponentValType>,
2121}
2122
2123#[derive(Debug)]
2124struct ImportSection {
2125    imports: Vec<Import>,
2126}
2127
2128#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2129struct Import {
2130    name: String,
2131    url: Option<String>,
2132    ty: ComponentTypeRef,
2133}
2134
2135#[derive(Debug)]
2136struct CanonicalSection {
2137    funcs: Vec<Func>,
2138}
2139
2140#[derive(Debug)]
2141enum Func {
2142    CanonLift {
2143        func_ty: u32,
2144        options: Vec<CanonOpt>,
2145        core_func_index: u32,
2146    },
2147    CanonLower {
2148        options: Vec<CanonOpt>,
2149        func_index: u32,
2150    },
2151}
2152
2153#[derive(Debug)]
2154enum CanonOpt {
2155    StringUtf8,
2156    StringUtf16,
2157    StringLatin1Utf16,
2158    Memory(u32),
2159    Realloc(u32),
2160    PostReturn(u32),
2161}
2162
2163#[derive(Debug)]
2164struct InstanceSection {}
2165
2166#[derive(Debug)]
2167struct ExportSection {}
2168
2169#[derive(Debug)]
2170struct StartSection {}
2171
2172#[derive(Debug)]
2173struct AliasSection {}
2174
2175#[derive(Debug)]
2176struct CoreInstanceSection {}
2177
2178#[derive(Debug)]
2179struct CoreTypeSection {
2180    types: Vec<Rc<CoreType>>,
2181}
2182
2183fn arbitrary_func_type(
2184    u: &mut Unstructured,
2185    config: &Config,
2186    valtypes: &[ValType],
2187    max_results: Option<usize>,
2188    type_ref_limit: u32,
2189) -> Result<Rc<crate::core::FuncType>> {
2190    let mut params = vec![];
2191    let mut results = vec![];
2192    arbitrary_loop(u, 0, 20, |u| {
2193        params.push(arbitrary_valtype(u, config, valtypes, type_ref_limit)?);
2194        Ok(true)
2195    })?;
2196    arbitrary_loop(u, 0, max_results.unwrap_or(20), |u| {
2197        results.push(arbitrary_valtype(u, config, valtypes, type_ref_limit)?);
2198        Ok(true)
2199    })?;
2200    Ok(Rc::new(crate::core::FuncType { params, results }))
2201}
2202
2203fn arbitrary_valtype(
2204    u: &mut Unstructured,
2205    config: &Config,
2206    valtypes: &[ValType],
2207    type_ref_limit: u32,
2208) -> Result<ValType> {
2209    if config.gc_enabled && type_ref_limit > 0 && u.ratio(1, 20)? {
2210        Ok(ValType::Ref(RefType {
2211            // TODO: For now, only create allow nullable reference
2212            // types. Eventually we should support non-nullable reference types,
2213            // but this means that we will also need to recognize when it is
2214            // impossible to create an instance of the reference (eg `(ref
2215            // nofunc)` has no instances, and self-referential types that
2216            // contain a non-null self-reference are also impossible to create).
2217            nullable: true,
2218            heap_type: HeapType::Concrete(u.int_in_range(0..=type_ref_limit - 1)?),
2219        }))
2220    } else {
2221        Ok(*u.choose(valtypes)?)
2222    }
2223}