Coverage Report

Created: 2026-06-21 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wasm-smith/src/component.rs
Line
Count
Source
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
7
use crate::{Config, arbitrary_loop};
8
use arbitrary::{Arbitrary, Result, Unstructured};
9
use std::collections::BTreeMap;
10
use std::{
11
    collections::{HashMap, HashSet},
12
    rc::Rc,
13
};
14
use wasm_encoder::{
15
    ComponentTypeRef, ComponentValType, HeapType, PrimitiveValType, RefType, TypeBounds, ValType,
16
};
17
18
mod 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)]
34
pub 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)]
48
struct 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)]
87
enum ComponentOrCoreFuncType {
88
    Component(Rc<FuncType>),
89
    Core(Rc<crate::core::FuncType>),
90
}
91
92
impl ComponentOrCoreFuncType {
93
0
    fn as_core(&self) -> &Rc<crate::core::FuncType> {
94
0
        match self {
95
0
            ComponentOrCoreFuncType::Core(t) => t,
96
0
            ComponentOrCoreFuncType::Component(_) => panic!("not a core func type"),
97
        }
98
0
    }
99
100
0
    fn as_component(&self) -> &Rc<FuncType> {
101
0
        match self {
102
0
            ComponentOrCoreFuncType::Core(_) => panic!("not a component func type"),
103
0
            ComponentOrCoreFuncType::Component(t) => t,
104
        }
105
0
    }
106
}
107
108
#[derive(Debug, Clone)]
109
enum 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)]
117
struct 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
185
impl ComponentContext {
186
0
    fn empty() -> Self {
187
0
        ComponentContext {
188
0
            component: Component::empty(),
189
0
            num_imports: 0,
190
0
            import_names: HashSet::default(),
191
0
            import_urls: HashSet::default(),
192
0
            funcs: vec![],
193
0
            component_funcs: vec![],
194
0
            scalar_component_funcs: vec![],
195
0
            core_funcs: vec![],
196
0
            components: vec![],
197
0
            modules: vec![],
198
0
            instances: vec![],
199
0
            values: vec![],
200
0
        }
201
0
    }
202
203
0
    fn num_modules(&self) -> usize {
204
0
        self.modules.len()
205
0
    }
206
207
0
    fn num_components(&self) -> usize {
208
0
        self.components.len()
209
0
    }
210
211
0
    fn num_instances(&self) -> usize {
212
0
        self.instances.len()
213
0
    }
214
215
0
    fn num_funcs(&self) -> usize {
216
0
        self.funcs.len()
217
0
    }
218
219
0
    fn num_values(&self) -> usize {
220
0
        self.values.len()
221
0
    }
222
}
223
224
#[derive(Debug, Default)]
225
struct 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
254
impl TypesScope {
255
0
    fn push(&mut self, ty: Rc<Type>) -> u32 {
256
0
        let ty_idx = u32::try_from(self.types.len()).unwrap();
257
258
0
        let kind_list = match &*ty {
259
0
            Type::Defined(_) => &mut self.defined_types,
260
0
            Type::Func(func_ty) => {
261
0
                self.func_type_to_indices
262
0
                    .entry(func_ty.clone())
263
0
                    .or_default()
264
0
                    .push(ty_idx);
265
0
                &mut self.func_types
266
            }
267
0
            Type::Component(_) => &mut self.component_types,
268
0
            Type::Instance(_) => &mut self.instance_types,
269
        };
270
0
        kind_list.push(ty_idx);
271
272
0
        self.types.push(ty);
273
0
        ty_idx
274
0
    }
275
276
0
    fn push_core(&mut self, ty: Rc<CoreType>) -> u32 {
277
0
        let ty_idx = u32::try_from(self.core_types.len()).unwrap();
278
279
0
        let kind_list = match &*ty {
280
0
            CoreType::Func(_) => &mut self.core_func_types,
281
0
            CoreType::Module(_) => &mut self.module_types,
282
        };
283
0
        kind_list.push(ty_idx);
284
285
0
        self.core_types.push(ty);
286
0
        ty_idx
287
0
    }
288
289
0
    fn get(&self, index: u32) -> &Rc<Type> {
290
0
        &self.types[index as usize]
291
0
    }
292
293
0
    fn get_core(&self, index: u32) -> &Rc<CoreType> {
294
0
        &self.core_types[index as usize]
295
0
    }
296
297
0
    fn get_func(&self, index: u32) -> &Rc<FuncType> {
298
0
        match &**self.get(index) {
299
0
            Type::Func(f) => f,
300
0
            _ => panic!("get_func on non-function type"),
301
        }
302
0
    }
303
304
0
    fn can_ref_type(&self) -> bool {
305
        // All component types and core module types may be referenced
306
0
        !self.types.is_empty() || !self.module_types.is_empty()
307
0
    }
308
}
309
310
impl<'a> Arbitrary<'a> for Component {
311
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
312
0
        Component::new(Config::default(), u)
313
0
    }
314
}
315
316
#[derive(Default)]
317
struct EntityCounts {
318
    globals: usize,
319
    tables: usize,
320
    memories: usize,
321
    tags: usize,
322
    funcs: usize,
323
}
324
325
impl Component {
326
    /// Construct a new `Component` using the given configuration.
327
0
    pub fn new(config: Config, u: &mut Unstructured) -> Result<Self> {
328
0
        let mut builder = ComponentBuilder::new(config);
329
0
        builder.build(u)
330
0
    }
331
332
0
    fn empty() -> Self {
333
0
        Component { sections: vec![] }
334
0
    }
335
}
336
337
#[must_use]
338
enum Step {
339
    Finished(Component),
340
    StillBuilding,
341
}
342
343
impl Step {
344
0
    fn unwrap_still_building(self) {
345
0
        match self {
346
0
            Step::Finished(_) => panic!(
347
                "`Step::unwrap_still_building` called on a `Step` that is not `StillBuilding`"
348
            ),
349
0
            Step::StillBuilding => {}
350
        }
351
0
    }
352
}
353
354
impl ComponentBuilder {
355
0
    fn new(config: Config) -> Self {
356
0
        ComponentBuilder {
357
0
            config,
358
0
            core_valtypes: vec![],
359
0
            types: vec![Default::default()],
360
0
            components: vec![ComponentContext::empty()],
361
0
            fill_minimums: false,
362
0
            total_components: 0,
363
0
            total_modules: 0,
364
0
            total_instances: 0,
365
0
            total_values: 0,
366
0
        }
367
0
    }
368
369
0
    fn build(&mut self, u: &mut Unstructured) -> Result<Component> {
370
0
        self.core_valtypes = crate::core::configured_valtypes(&self.config);
371
372
0
        let mut choices: Vec<fn(&mut ComponentBuilder, &mut Unstructured) -> Result<Step>> = vec![];
373
374
        loop {
375
0
            choices.clear();
376
0
            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
0
            if !u.is_empty() {
381
0
                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
0
                choices.push(Self::arbitrary_core_type_section);
387
0
                choices.push(Self::arbitrary_type_section);
388
0
                choices.push(Self::arbitrary_import_section);
389
0
                choices.push(Self::arbitrary_canonical_section);
390
391
0
                if self.total_modules < self.config.max_modules {
392
0
                    choices.push(Self::arbitrary_core_module_section);
393
0
                }
394
395
0
                if self.components.len() < self.config.max_nesting_depth
396
0
                    && self.total_components < self.config.max_components
397
0
                {
398
0
                    choices.push(Self::arbitrary_component_section);
399
0
                }
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
0
            }
408
409
0
            let f = u.choose(&choices)?;
410
0
            match f(self, u)? {
411
0
                Step::StillBuilding => {}
412
0
                Step::Finished(component) => {
413
0
                    if self.components.is_empty() {
414
                        // If we just finished the root component, then return it.
415
0
                        return Ok(component);
416
0
                    } else {
417
0
                        // Otherwise, add it as a nested component in the parent.
418
0
                        self.push_section(Section::Component(component));
419
0
                    }
420
                }
421
            }
422
        }
423
0
    }
424
425
0
    fn finish_component(&mut self, u: &mut Unstructured) -> Result<Step> {
426
        // Ensure we've generated all of our minimums.
427
0
        self.fill_minimums = true;
428
        {
429
0
            if self.current_type_scope().types.len() < self.config.min_types {
430
0
                self.arbitrary_type_section(u)?.unwrap_still_building();
431
0
            }
432
0
            if self.component().num_imports < self.config.min_imports {
433
0
                self.arbitrary_import_section(u)?.unwrap_still_building();
434
0
            }
435
0
            if self.component().funcs.len() < self.config.min_funcs {
436
0
                self.arbitrary_canonical_section(u)?.unwrap_still_building();
437
0
            }
438
        }
439
0
        self.fill_minimums = false;
440
441
0
        self.types
442
0
            .pop()
443
0
            .expect("should have a types scope for the component we are finishing");
444
0
        Ok(Step::Finished(self.components.pop().unwrap().component))
445
0
    }
446
447
0
    fn component(&self) -> &ComponentContext {
448
0
        self.components.last().unwrap()
449
0
    }
450
451
0
    fn component_mut(&mut self) -> &mut ComponentContext {
452
0
        self.components.last_mut().unwrap()
453
0
    }
454
455
0
    fn last_section(&self) -> Option<&Section> {
456
0
        self.component().component.sections.last()
457
0
    }
458
459
0
    fn last_section_mut(&mut self) -> Option<&mut Section> {
460
0
        self.component_mut().component.sections.last_mut()
461
0
    }
462
463
0
    fn push_section(&mut self, section: Section) {
464
0
        self.component_mut().component.sections.push(section);
465
0
    }
466
467
0
    fn ensure_section(
468
0
        &mut self,
469
0
        mut predicate: impl FnMut(&Section) -> bool,
470
0
        mut make_section: impl FnMut() -> Section,
471
0
    ) -> &mut Section {
472
0
        match self.last_section() {
473
0
            Some(sec) if predicate(sec) => {}
474
0
            _ => self.push_section(make_section()),
475
        }
476
0
        self.last_section_mut().unwrap()
477
0
    }
Unexecuted instantiation: <wasm_smith::component::ComponentBuilder>::ensure_section::<<wasm_smith::component::ComponentBuilder>::push_import::{closure#0}, <wasm_smith::component::ComponentBuilder>::push_import::{closure#1}>
Unexecuted instantiation: <wasm_smith::component::ComponentBuilder>::ensure_section::<<wasm_smith::component::ComponentBuilder>::push_core_type::{closure#0}, <wasm_smith::component::ComponentBuilder>::push_core_type::{closure#1}>
Unexecuted instantiation: <wasm_smith::component::ComponentBuilder>::ensure_section::<<wasm_smith::component::ComponentBuilder>::push_type::{closure#0}, <wasm_smith::component::ComponentBuilder>::push_type::{closure#1}>
478
479
0
    fn arbitrary_custom_section(&mut self, u: &mut Unstructured) -> Result<Step> {
480
0
        self.push_section(Section::Custom(u.arbitrary()?));
481
0
        Ok(Step::StillBuilding)
482
0
    }
483
484
0
    fn push_type(&mut self, ty: Rc<Type>) -> u32 {
485
0
        match self.ensure_section(
486
0
            |s| matches!(s, Section::Type(_)),
487
0
            || Section::Type(TypeSection { types: vec![] }),
488
        ) {
489
0
            Section::Type(TypeSection { types }) => {
490
0
                types.push(ty.clone());
491
0
                self.current_type_scope_mut().push(ty)
492
            }
493
0
            _ => unreachable!(),
494
        }
495
0
    }
496
497
0
    fn push_core_type(&mut self, ty: Rc<CoreType>) -> u32 {
498
0
        match self.ensure_section(
499
0
            |s| matches!(s, Section::CoreType(_)),
500
0
            || Section::CoreType(CoreTypeSection { types: vec![] }),
501
        ) {
502
0
            Section::CoreType(CoreTypeSection { types }) => {
503
0
                types.push(ty.clone());
504
0
                self.current_type_scope_mut().push_core(ty)
505
            }
506
0
            _ => unreachable!(),
507
        }
508
0
    }
509
510
0
    fn arbitrary_core_type_section(&mut self, u: &mut Unstructured) -> Result<Step> {
511
0
        self.push_section(Section::CoreType(CoreTypeSection { types: vec![] }));
512
513
0
        let min = if self.fill_minimums {
514
0
            self.config
515
0
                .min_types
516
0
                .saturating_sub(self.current_type_scope().types.len())
517
        } else {
518
0
            0
519
        };
520
521
0
        let max = self.config.max_types - self.current_type_scope().types.len();
522
523
0
        arbitrary_loop(u, min, max, |u| {
524
0
            let mut type_fuel = self.config.max_type_size;
525
0
            let ty = self.arbitrary_core_type(u, &mut type_fuel)?;
526
0
            self.push_core_type(ty);
527
0
            Ok(true)
528
0
        })?;
529
530
0
        Ok(Step::StillBuilding)
531
0
    }
532
533
0
    fn arbitrary_core_type(
534
0
        &self,
535
0
        u: &mut Unstructured,
536
0
        type_fuel: &mut u32,
537
0
    ) -> Result<Rc<CoreType>> {
538
0
        *type_fuel = type_fuel.saturating_sub(1);
539
0
        if *type_fuel == 0 {
540
0
            return Ok(Rc::new(CoreType::Module(Rc::new(ModuleType::default()))));
541
0
        }
542
543
0
        let ty = match u.int_in_range::<u8>(0..=1)? {
544
0
            0 => CoreType::Func(arbitrary_func_type(
545
0
                u,
546
0
                &self.config,
547
0
                &self.core_valtypes,
548
0
                if self.config.multi_value_enabled {
549
0
                    None
550
                } else {
551
0
                    Some(1)
552
                },
553
                0,
554
0
            )?),
555
0
            1 => CoreType::Module(self.arbitrary_module_type(u, type_fuel)?),
556
0
            _ => unreachable!(),
557
        };
558
0
        Ok(Rc::new(ty))
559
0
    }
560
561
0
    fn arbitrary_type_section(&mut self, u: &mut Unstructured) -> Result<Step> {
562
0
        self.push_section(Section::Type(TypeSection { types: vec![] }));
563
564
0
        let min = if self.fill_minimums {
565
0
            self.config
566
0
                .min_types
567
0
                .saturating_sub(self.current_type_scope().types.len())
568
        } else {
569
0
            0
570
        };
571
572
0
        let max = self.config.max_types - self.current_type_scope().types.len();
573
574
0
        arbitrary_loop(u, min, max, |u| {
575
0
            let mut type_fuel = self.config.max_type_size;
576
0
            let ty = self.arbitrary_type(u, &mut type_fuel)?;
577
0
            self.push_type(ty);
578
0
            Ok(true)
579
0
        })?;
580
581
0
        Ok(Step::StillBuilding)
582
0
    }
583
584
0
    fn arbitrary_type_ref<'a>(
585
0
        &self,
586
0
        u: &mut Unstructured<'a>,
587
0
        for_import: bool,
588
0
        for_type_def: bool,
589
0
    ) -> Result<Option<ComponentTypeRef>> {
590
0
        let mut choices: Vec<fn(&Self, &mut Unstructured) -> Result<ComponentTypeRef>> = Vec::new();
591
0
        let scope = self.current_type_scope();
592
593
0
        if !scope.module_types.is_empty()
594
0
            && (for_type_def || !for_import || self.total_modules < self.config.max_modules)
595
        {
596
0
            choices.push(|me, u| {
597
                Ok(ComponentTypeRef::Module(
598
0
                    *u.choose(&me.current_type_scope().module_types)?,
599
                ))
600
0
            });
601
0
        }
602
603
        // Types cannot be imported currently
604
0
        if !for_import
605
0
            && !scope.types.is_empty()
606
0
            && (for_type_def || scope.types.len() < self.config.max_types)
607
        {
608
0
            choices.push(|me, u| {
609
0
                Ok(ComponentTypeRef::Type(TypeBounds::Eq(u.int_in_range(
610
0
                    0..=u32::try_from(me.current_type_scope().types.len() - 1).unwrap(),
611
0
                )?)))
612
0
            });
613
0
        }
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
0
        if !scope.func_types.is_empty()
622
0
            && (for_type_def || !for_import || self.component().num_funcs() < self.config.max_funcs)
623
        {
624
0
            choices.push(|me, u| {
625
                Ok(ComponentTypeRef::Func(
626
0
                    *u.choose(&me.current_type_scope().func_types)?,
627
                ))
628
0
            });
629
0
        }
630
631
0
        if !scope.component_types.is_empty()
632
0
            && (for_type_def || !for_import || self.total_components < self.config.max_components)
633
        {
634
0
            choices.push(|me, u| {
635
                Ok(ComponentTypeRef::Component(
636
0
                    *u.choose(&me.current_type_scope().component_types)?,
637
                ))
638
0
            });
639
0
        }
640
641
0
        if !scope.instance_types.is_empty()
642
0
            && (for_type_def || !for_import || self.total_instances < self.config.max_instances)
643
        {
644
0
            choices.push(|me, u| {
645
                Ok(ComponentTypeRef::Instance(
646
0
                    *u.choose(&me.current_type_scope().instance_types)?,
647
                ))
648
0
            });
649
0
        }
650
651
0
        if choices.is_empty() {
652
0
            return Ok(None);
653
0
        }
654
655
0
        let f = u.choose(&choices)?;
656
0
        f(self, u).map(Option::Some)
657
0
    }
658
659
0
    fn arbitrary_type(&mut self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<Rc<Type>> {
660
0
        *type_fuel = type_fuel.saturating_sub(1);
661
0
        if *type_fuel == 0 {
662
0
            return Ok(Rc::new(Type::Defined(
663
0
                self.arbitrary_defined_type(u, type_fuel)?,
664
            )));
665
0
        }
666
667
0
        let ty = match u.int_in_range::<u8>(0..=3)? {
668
0
            0 => Type::Defined(self.arbitrary_defined_type(u, type_fuel)?),
669
0
            1 => Type::Func(self.arbitrary_func_type(u, type_fuel)?),
670
0
            2 => Type::Component(self.arbitrary_component_type(u, type_fuel)?),
671
0
            3 => Type::Instance(self.arbitrary_instance_type(u, type_fuel)?),
672
0
            _ => unreachable!(),
673
        };
674
0
        Ok(Rc::new(ty))
675
0
    }
676
677
0
    fn arbitrary_module_type(
678
0
        &self,
679
0
        u: &mut Unstructured,
680
0
        type_fuel: &mut u32,
681
0
    ) -> Result<Rc<ModuleType>> {
682
0
        let mut defs = vec![];
683
0
        let mut has_memory = false;
684
0
        let mut has_canonical_abi_realloc = false;
685
0
        let mut has_canonical_abi_free = false;
686
0
        let mut types: Vec<Rc<crate::core::FuncType>> = vec![];
687
0
        let mut imports = HashMap::new();
688
0
        let mut exports = HashSet::new();
689
0
        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
0
        if counts.memories < self.config.max_memories && u.ratio::<u8>(99, 100)? {
697
0
            defs.push(ModuleTypeDef::Export(
698
0
                "memory".into(),
699
0
                crate::core::EntityType::Memory(self.arbitrary_core_memory_type(u)?),
700
            ));
701
0
            exports.insert("memory".into());
702
0
            counts.memories += 1;
703
0
            has_memory = true;
704
0
        }
705
706
        // `canonical_abi_realloc`
707
0
        if counts.funcs < self.config.max_funcs
708
0
            && types.len() < self.config.max_types
709
0
            && u.ratio::<u8>(99, 100)?
710
0
        {
711
0
            let realloc_ty = Rc::new(crate::core::FuncType {
712
0
                params: vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32],
713
0
                results: vec![ValType::I32],
714
0
            });
715
0
            let ty_idx = u32::try_from(types.len()).unwrap();
716
0
            types.push(realloc_ty.clone());
717
0
            defs.push(ModuleTypeDef::TypeDef(
718
0
                crate::core::CompositeType::new_func(
719
0
                    realloc_ty.clone(),
720
0
                    false, // TODO: handle shared
721
0
                ),
722
0
            ));
723
0
            defs.push(ModuleTypeDef::Export(
724
0
                "canonical_abi_realloc".into(),
725
0
                crate::core::EntityType::Func(ty_idx, realloc_ty),
726
0
            ));
727
0
            exports.insert("canonical_abi_realloc".into());
728
0
            counts.funcs += 1;
729
0
            has_canonical_abi_realloc = true;
730
0
        }
731
732
        // `canonical_abi_free`
733
0
        if counts.funcs < self.config.max_funcs
734
0
            && types.len() < self.config.max_types
735
0
            && u.ratio::<u8>(99, 100)?
736
0
        {
737
0
            let free_ty = Rc::new(crate::core::FuncType {
738
0
                params: vec![ValType::I32, ValType::I32, ValType::I32],
739
0
                results: vec![],
740
0
            });
741
0
            let ty_idx = u32::try_from(types.len()).unwrap();
742
0
            types.push(free_ty.clone());
743
0
            defs.push(ModuleTypeDef::TypeDef(
744
0
                crate::core::CompositeType::new_func(
745
0
                    free_ty.clone(),
746
0
                    false, // TODO: handle shared
747
0
                ),
748
0
            ));
749
0
            defs.push(ModuleTypeDef::Export(
750
0
                "canonical_abi_free".into(),
751
0
                crate::core::EntityType::Func(ty_idx, free_ty),
752
0
            ));
753
0
            exports.insert("canonical_abi_free".into());
754
0
            counts.funcs += 1;
755
0
            has_canonical_abi_free = true;
756
0
        }
757
758
0
        let mut entity_choices: Vec<
759
0
            fn(
760
0
                &ComponentBuilder,
761
0
                &mut Unstructured,
762
0
                &mut EntityCounts,
763
0
                &[Rc<crate::core::FuncType>],
764
0
            ) -> Result<crate::core::EntityType>,
765
0
        > = Vec::with_capacity(5);
766
767
0
        arbitrary_loop(u, 0, 100, |u| {
768
0
            *type_fuel = type_fuel.saturating_sub(1);
769
0
            if *type_fuel == 0 {
770
0
                return Ok(false);
771
0
            }
772
773
0
            let max_choice = if types.len() < self.config.max_types {
774
                // Check if the parent scope has core function types to alias
775
0
                if !types.is_empty()
776
0
                    || (!self.types.is_empty()
777
0
                        && !self.types.last().unwrap().core_func_types.is_empty())
778
                {
779
                    // Imports, exports, types, and aliases
780
0
                    3
781
                } else {
782
                    // Imports, exports, and types
783
0
                    2
784
                }
785
            } else {
786
                // Imports and exports
787
0
                1
788
            };
789
790
0
            match u.int_in_range::<u8>(0..=max_choice)? {
791
                // Import.
792
                0 => {
793
0
                    let module = crate::limited_string(100, u)?;
794
0
                    let existing_module_imports = imports.entry(module.clone()).or_default();
795
0
                    let name = crate::unique_string(100, existing_module_imports, u)?;
796
0
                    let entity_type = match self.arbitrary_core_entity_type(
797
0
                        u,
798
0
                        &types,
799
0
                        &mut entity_choices,
800
0
                        &mut counts,
801
0
                    )? {
802
0
                        None => return Ok(false),
803
0
                        Some(x) => x,
804
                    };
805
0
                    defs.push(ModuleTypeDef::Import(crate::core::Import {
806
0
                        module,
807
0
                        name,
808
0
                        entity_type,
809
0
                    }));
810
                }
811
812
                // Export.
813
                1 => {
814
0
                    let name = crate::unique_string(100, &mut exports, u)?;
815
0
                    let entity_ty = match self.arbitrary_core_entity_type(
816
0
                        u,
817
0
                        &types,
818
0
                        &mut entity_choices,
819
0
                        &mut counts,
820
0
                    )? {
821
0
                        None => return Ok(false),
822
0
                        Some(x) => x,
823
                    };
824
0
                    defs.push(ModuleTypeDef::Export(name, entity_ty));
825
                }
826
827
                // Type definition.
828
                2 => {
829
0
                    let ty = arbitrary_func_type(
830
0
                        u,
831
0
                        &self.config,
832
0
                        &self.core_valtypes,
833
0
                        if self.config.multi_value_enabled {
834
0
                            None
835
                        } else {
836
0
                            Some(1)
837
                        },
838
                        0,
839
0
                    )?;
840
0
                    types.push(ty.clone());
841
0
                    defs.push(ModuleTypeDef::TypeDef(
842
0
                        crate::core::CompositeType::new_func(ty, false),
843
0
                    )); // TODO: handle shared
844
                }
845
846
                // Alias
847
                3 => {
848
0
                    let (count, index, kind) = self.arbitrary_outer_core_type_alias(u, &types)?;
849
0
                    let ty = match &kind {
850
0
                        CoreOuterAliasKind::Type(ty) => ty.clone(),
851
                    };
852
0
                    types.push(ty);
853
0
                    defs.push(ModuleTypeDef::OuterAlias {
854
0
                        count,
855
0
                        i: index,
856
0
                        kind,
857
0
                    });
858
                }
859
860
0
                _ => unreachable!(),
861
            }
862
863
0
            Ok(true)
864
0
        })?;
865
866
0
        Ok(Rc::new(ModuleType {
867
0
            defs,
868
0
            has_memory,
869
0
            has_canonical_abi_realloc,
870
0
            has_canonical_abi_free,
871
0
        }))
872
0
    }
873
874
0
    fn arbitrary_core_entity_type(
875
0
        &self,
876
0
        u: &mut Unstructured,
877
0
        types: &[Rc<crate::core::FuncType>],
878
0
        choices: &mut Vec<
879
0
            fn(
880
0
                &ComponentBuilder,
881
0
                &mut Unstructured,
882
0
                &mut EntityCounts,
883
0
                &[Rc<crate::core::FuncType>],
884
0
            ) -> Result<crate::core::EntityType>,
885
0
        >,
886
0
        counts: &mut EntityCounts,
887
0
    ) -> Result<Option<crate::core::EntityType>> {
888
0
        choices.clear();
889
890
0
        if counts.globals < self.config.max_globals {
891
0
            choices.push(|c, u, counts, _types| {
892
0
                counts.globals += 1;
893
                Ok(crate::core::EntityType::Global(
894
0
                    c.arbitrary_core_global_type(u)?,
895
                ))
896
0
            });
897
0
        }
898
899
0
        if counts.tables < self.config.max_tables {
900
0
            choices.push(|c, u, counts, _types| {
901
0
                counts.tables += 1;
902
                Ok(crate::core::EntityType::Table(
903
0
                    c.arbitrary_core_table_type(u)?,
904
                ))
905
0
            });
906
0
        }
907
908
0
        if counts.memories < self.config.max_memories {
909
0
            choices.push(|c, u, counts, _types| {
910
0
                counts.memories += 1;
911
                Ok(crate::core::EntityType::Memory(
912
0
                    c.arbitrary_core_memory_type(u)?,
913
                ))
914
0
            });
915
0
        }
916
917
0
        if types.iter().any(|ty| ty.results.is_empty())
918
0
            && self.config.exceptions_enabled
919
0
            && counts.tags < self.config.max_tags
920
        {
921
0
            choices.push(|c, u, counts, types| {
922
0
                counts.tags += 1;
923
0
                let tag_func_types = types
924
0
                    .iter()
925
0
                    .enumerate()
926
0
                    .filter(|(_, ty)| ty.results.is_empty())
927
0
                    .map(|(i, _)| u32::try_from(i).unwrap())
928
0
                    .collect::<Vec<_>>();
929
                Ok(crate::core::EntityType::Tag(
930
0
                    crate::core::arbitrary_tag_type(u, &tag_func_types, |idx| {
931
0
                        types[usize::try_from(idx).unwrap()].clone()
932
0
                    })?,
933
                ))
934
0
            });
935
0
        }
936
937
0
        if !types.is_empty() && counts.funcs < self.config.max_funcs {
938
0
            choices.push(|c, u, counts, types| {
939
0
                counts.funcs += 1;
940
0
                let ty_idx = u.int_in_range(0..=u32::try_from(types.len() - 1).unwrap())?;
941
0
                let ty = types[ty_idx as usize].clone();
942
0
                Ok(crate::core::EntityType::Func(ty_idx, ty))
943
0
            });
944
0
        }
945
946
0
        if choices.is_empty() {
947
0
            return Ok(None);
948
0
        }
949
950
0
        let f = u.choose(choices)?;
951
0
        let ty = f(self, u, counts, types)?;
952
0
        Ok(Some(ty))
953
0
    }
954
955
0
    fn arbitrary_core_valtype(&self, u: &mut Unstructured) -> Result<ValType> {
956
0
        Ok(*u.choose(&self.core_valtypes)?)
957
0
    }
958
959
0
    fn arbitrary_core_global_type(&self, u: &mut Unstructured) -> Result<crate::core::GlobalType> {
960
        Ok(crate::core::GlobalType {
961
0
            val_type: self.arbitrary_core_valtype(u)?,
962
0
            mutable: u.arbitrary()?,
963
            shared: false,
964
        })
965
0
    }
966
967
0
    fn arbitrary_core_table_type(&self, u: &mut Unstructured) -> Result<crate::core::TableType> {
968
0
        crate::core::arbitrary_table_type(u, &self.config, None)
969
0
    }
970
971
0
    fn arbitrary_core_memory_type(&self, u: &mut Unstructured) -> Result<crate::core::MemoryType> {
972
0
        crate::core::arbitrary_memtype(u, &self.config)
973
0
    }
974
975
0
    fn with_types_scope<T>(&mut self, f: impl FnOnce(&mut Self) -> Result<T>) -> Result<T> {
976
0
        self.types.push(Default::default());
977
0
        let result = f(self);
978
0
        self.types.pop();
979
0
        result
980
0
    }
Unexecuted instantiation: <wasm_smith::component::ComponentBuilder>::with_types_scope::<(), <wasm_smith::component::ComponentBuilder>::arbitrary_instance_type::{closure#0}>
Unexecuted instantiation: <wasm_smith::component::ComponentBuilder>::with_types_scope::<(), <wasm_smith::component::ComponentBuilder>::arbitrary_component_type::{closure#0}>
981
982
0
    fn current_type_scope(&self) -> &TypesScope {
983
0
        self.types.last().unwrap()
984
0
    }
985
986
0
    fn current_type_scope_mut(&mut self) -> &mut TypesScope {
987
0
        self.types.last_mut().unwrap()
988
0
    }
989
990
0
    fn outer_types_scope(&self, count: u32) -> &TypesScope {
991
0
        &self.types[self.types.len() - 1 - usize::try_from(count).unwrap()]
992
0
    }
993
994
0
    fn outer_type(&self, count: u32, i: u32) -> &Rc<Type> {
995
0
        &self.outer_types_scope(count).types[usize::try_from(i).unwrap()]
996
0
    }
997
998
0
    fn arbitrary_component_type(
999
0
        &mut self,
1000
0
        u: &mut Unstructured,
1001
0
        type_fuel: &mut u32,
1002
0
    ) -> Result<Rc<ComponentType>> {
1003
0
        let mut defs = vec![];
1004
0
        let mut imports = HashSet::new();
1005
0
        let mut import_urls = HashSet::new();
1006
0
        let mut exports = HashSet::new();
1007
0
        let mut export_urls = HashSet::new();
1008
1009
0
        self.with_types_scope(|me| {
1010
0
            arbitrary_loop(u, 0, 100, |u| {
1011
0
                *type_fuel = type_fuel.saturating_sub(1);
1012
0
                if *type_fuel == 0 {
1013
0
                    return Ok(false);
1014
0
                }
1015
1016
0
                if me.current_type_scope().can_ref_type() && u.int_in_range::<u8>(0..=3)? == 0 {
1017
0
                    if let Some(ty) = me.arbitrary_type_ref(u, true, true)? {
1018
                        // Imports.
1019
0
                        let name = crate::unique_kebab_string(100, &mut imports, u)?;
1020
0
                        let url = if u.arbitrary()? {
1021
0
                            Some(crate::unique_url(100, &mut import_urls, u)?)
1022
                        } else {
1023
0
                            None
1024
                        };
1025
0
                        defs.push(ComponentTypeDef::Import(Import { name, url, ty }));
1026
0
                        return Ok(true);
1027
0
                    }
1028
1029
                    // Can't reference an arbitrary type, fallback to another definition.
1030
0
                }
1031
1032
                // Type definitions, exports, and aliases.
1033
0
                let def =
1034
0
                    me.arbitrary_instance_type_def(u, &mut exports, &mut export_urls, type_fuel)?;
1035
0
                defs.push(def.into());
1036
0
                Ok(true)
1037
0
            })
1038
0
        })?;
1039
1040
0
        Ok(Rc::new(ComponentType { defs }))
1041
0
    }
1042
1043
0
    fn arbitrary_instance_type(
1044
0
        &mut self,
1045
0
        u: &mut Unstructured,
1046
0
        type_fuel: &mut u32,
1047
0
    ) -> Result<Rc<InstanceType>> {
1048
0
        let mut defs = vec![];
1049
0
        let mut exports = HashSet::new();
1050
0
        let mut export_urls = HashSet::new();
1051
1052
0
        self.with_types_scope(|me| {
1053
0
            arbitrary_loop(u, 0, 100, |u| {
1054
0
                *type_fuel = type_fuel.saturating_sub(1);
1055
0
                if *type_fuel == 0 {
1056
0
                    return Ok(false);
1057
0
                }
1058
1059
0
                defs.push(me.arbitrary_instance_type_def(
1060
0
                    u,
1061
0
                    &mut exports,
1062
0
                    &mut export_urls,
1063
0
                    type_fuel,
1064
0
                )?);
1065
0
                Ok(true)
1066
0
            })
1067
0
        })?;
1068
1069
0
        Ok(Rc::new(InstanceType { defs }))
1070
0
    }
1071
1072
0
    fn arbitrary_instance_type_def(
1073
0
        &mut self,
1074
0
        u: &mut Unstructured,
1075
0
        exports: &mut HashSet<String>,
1076
0
        export_urls: &mut HashSet<String>,
1077
0
        type_fuel: &mut u32,
1078
0
    ) -> Result<InstanceTypeDecl> {
1079
0
        let mut choices: Vec<
1080
0
            fn(
1081
0
                &mut ComponentBuilder,
1082
0
                &mut HashSet<String>,
1083
0
                &mut HashSet<String>,
1084
0
                &mut Unstructured,
1085
0
                &mut u32,
1086
0
            ) -> Result<InstanceTypeDecl>,
1087
0
        > = Vec::with_capacity(3);
1088
1089
        // Export.
1090
0
        if self.current_type_scope().can_ref_type() {
1091
0
            choices.push(|me, exports, export_urls, u, _type_fuel| {
1092
0
                let ty = me.arbitrary_type_ref(u, false, true)?.unwrap();
1093
0
                if let ComponentTypeRef::Type(TypeBounds::Eq(idx)) = ty {
1094
0
                    let ty = me.current_type_scope().get(idx).clone();
1095
0
                    me.current_type_scope_mut().push(ty);
1096
0
                }
1097
                Ok(InstanceTypeDecl::Export {
1098
0
                    name: crate::unique_kebab_string(100, exports, u)?,
1099
0
                    url: if u.arbitrary()? {
1100
0
                        Some(crate::unique_url(100, export_urls, u)?)
1101
                    } else {
1102
0
                        None
1103
                    },
1104
0
                    ty,
1105
                })
1106
0
            });
1107
0
        }
1108
1109
        // Outer type alias.
1110
0
        if self
1111
0
            .types
1112
0
            .iter()
1113
0
            .any(|scope| !scope.types.is_empty() || !scope.core_types.is_empty())
1114
        {
1115
0
            choices.push(|me, _exports, _export_urls, u, _type_fuel| {
1116
0
                let alias = me.arbitrary_outer_type_alias(u)?;
1117
0
                match &alias {
1118
                    Alias::Outer {
1119
0
                        kind: OuterAliasKind::Type(ty),
1120
                        ..
1121
0
                    } => me.current_type_scope_mut().push(ty.clone()),
1122
                    Alias::Outer {
1123
0
                        kind: OuterAliasKind::CoreType(ty),
1124
                        ..
1125
0
                    } => me.current_type_scope_mut().push_core(ty.clone()),
1126
0
                    _ => unreachable!(),
1127
                };
1128
0
                Ok(InstanceTypeDecl::Alias(alias))
1129
0
            });
1130
0
        }
1131
1132
        // Core type definition.
1133
0
        choices.push(|me, _exports, _export_urls, u, type_fuel| {
1134
0
            let ty = me.arbitrary_core_type(u, type_fuel)?;
1135
0
            me.current_type_scope_mut().push_core(ty.clone());
1136
0
            Ok(InstanceTypeDecl::CoreType(ty))
1137
0
        });
1138
1139
        // Type definition.
1140
0
        if self.types.len() < self.config.max_nesting_depth {
1141
0
            choices.push(|me, _exports, _export_urls, u, type_fuel| {
1142
0
                let ty = me.arbitrary_type(u, type_fuel)?;
1143
0
                me.current_type_scope_mut().push(ty.clone());
1144
0
                Ok(InstanceTypeDecl::Type(ty))
1145
0
            });
1146
0
        }
1147
1148
0
        let f = u.choose(&choices)?;
1149
0
        f(self, exports, export_urls, u, type_fuel)
1150
0
    }
1151
1152
0
    fn arbitrary_outer_core_type_alias(
1153
0
        &self,
1154
0
        u: &mut Unstructured,
1155
0
        local_types: &[Rc<crate::core::FuncType>],
1156
0
    ) -> Result<(u32, u32, CoreOuterAliasKind)> {
1157
0
        let enclosing_type_len = if !self.types.is_empty() {
1158
0
            self.types.last().unwrap().core_func_types.len()
1159
        } else {
1160
0
            0
1161
        };
1162
1163
0
        assert!(!local_types.is_empty() || enclosing_type_len > 0);
1164
1165
0
        let max = enclosing_type_len + local_types.len() - 1;
1166
0
        let i = u.int_in_range(0..=max)?;
1167
0
        let (count, index, ty) = if i < enclosing_type_len {
1168
0
            let enclosing = self.types.last().unwrap();
1169
0
            let index = enclosing.core_func_types[i];
1170
            (
1171
                1,
1172
0
                index,
1173
0
                match enclosing.get_core(index).as_ref() {
1174
0
                    CoreType::Func(ty) => ty.clone(),
1175
0
                    CoreType::Module(_) => unreachable!(),
1176
                },
1177
            )
1178
0
        } else if i - enclosing_type_len < local_types.len() {
1179
0
            let i = i - enclosing_type_len;
1180
0
            (0, u32::try_from(i).unwrap(), local_types[i].clone())
1181
        } else {
1182
0
            unreachable!()
1183
        };
1184
1185
0
        Ok((count, index, CoreOuterAliasKind::Type(ty)))
1186
0
    }
1187
1188
0
    fn arbitrary_outer_type_alias(&self, u: &mut Unstructured) -> Result<Alias> {
1189
0
        let non_empty_types_scopes: Vec<_> = self
1190
0
            .types
1191
0
            .iter()
1192
0
            .rev()
1193
0
            .enumerate()
1194
0
            .filter(|(_, scope)| !scope.types.is_empty() || !scope.core_types.is_empty())
1195
0
            .collect();
1196
0
        assert!(
1197
0
            !non_empty_types_scopes.is_empty(),
1198
            "precondition: there are non-empty types scopes"
1199
        );
1200
1201
0
        let (count, scope) = u.choose(&non_empty_types_scopes)?;
1202
0
        let count = u32::try_from(*count).unwrap();
1203
0
        assert!(!scope.types.is_empty() || !scope.core_types.is_empty());
1204
1205
0
        let max_type_in_scope = scope.types.len() + scope.core_types.len() - 1;
1206
0
        let i = u.int_in_range(0..=max_type_in_scope)?;
1207
1208
0
        let (i, kind) = if i < scope.types.len() {
1209
0
            let i = u32::try_from(i).unwrap();
1210
0
            (i, OuterAliasKind::Type(Rc::clone(scope.get(i))))
1211
0
        } else if i - scope.types.len() < scope.core_types.len() {
1212
0
            let i = u32::try_from(i - scope.types.len()).unwrap();
1213
0
            (i, OuterAliasKind::CoreType(Rc::clone(scope.get_core(i))))
1214
        } else {
1215
0
            unreachable!()
1216
        };
1217
1218
0
        Ok(Alias::Outer { count, i, kind })
1219
0
    }
1220
1221
0
    fn arbitrary_func_type(
1222
0
        &self,
1223
0
        u: &mut Unstructured,
1224
0
        type_fuel: &mut u32,
1225
0
    ) -> Result<Rc<FuncType>> {
1226
0
        let mut params = Vec::new();
1227
0
        let mut results = Vec::new();
1228
0
        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
0
        arbitrary_loop(u, 0, 16, |u| {
1240
0
            *type_fuel = type_fuel.saturating_sub(1);
1241
0
            if *type_fuel == 0 {
1242
0
                return Ok(false);
1243
0
            }
1244
1245
0
            let name = crate::unique_kebab_string(100, &mut names, u)?;
1246
0
            let ty = self.arbitrary_component_val_type(u)?;
1247
1248
0
            params.push((name, ty));
1249
1250
0
            Ok(true)
1251
0
        })?;
1252
1253
0
        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
0
        arbitrary_loop(u, 0, 1, |u| {
1259
0
            *type_fuel = type_fuel.saturating_sub(1);
1260
0
            if *type_fuel == 0 {
1261
0
                return Ok(false);
1262
0
            }
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
0
            let name = if results.is_empty() {
1267
                // Most of the time we should have a single, unnamed result.
1268
0
                u.ratio::<u8>(10, 100)?
1269
0
                    .then(|| crate::unique_kebab_string(100, &mut names, u))
1270
0
                    .transpose()?
1271
            } else {
1272
0
                Some(crate::unique_kebab_string(100, &mut names, u)?)
1273
            };
1274
1275
0
            let ty = self.arbitrary_component_val_type(u)?;
1276
1277
0
            results.push((name, ty));
1278
1279
            // There can be only one unnamed result.
1280
0
            if results.len() == 1 && results[0].0.is_none() {
1281
0
                return Ok(false);
1282
0
            }
1283
1284
0
            Ok(true)
1285
0
        })?;
1286
1287
0
        Ok(Rc::new(FuncType { params, results }))
1288
0
    }
1289
1290
0
    fn arbitrary_component_val_type(&self, u: &mut Unstructured) -> Result<ComponentValType> {
1291
0
        let max_choices = if self.current_type_scope().defined_types.is_empty() {
1292
0
            0
1293
        } else {
1294
0
            1
1295
        };
1296
0
        match u.int_in_range(0..=max_choices)? {
1297
            0 => Ok(ComponentValType::Primitive(
1298
0
                self.arbitrary_primitive_val_type(u)?,
1299
            )),
1300
            1 => {
1301
0
                let index = *u.choose(&self.current_type_scope().defined_types)?;
1302
0
                let ty = Rc::clone(self.current_type_scope().get(index));
1303
0
                Ok(ComponentValType::Type(index))
1304
            }
1305
0
            _ => unreachable!(),
1306
        }
1307
0
    }
1308
1309
0
    fn arbitrary_primitive_val_type(&self, u: &mut Unstructured) -> Result<PrimitiveValType> {
1310
0
        match u.int_in_range(0..=12)? {
1311
0
            0 => Ok(PrimitiveValType::Bool),
1312
0
            1 => Ok(PrimitiveValType::S8),
1313
0
            2 => Ok(PrimitiveValType::U8),
1314
0
            3 => Ok(PrimitiveValType::S16),
1315
0
            4 => Ok(PrimitiveValType::U16),
1316
0
            5 => Ok(PrimitiveValType::S32),
1317
0
            6 => Ok(PrimitiveValType::U32),
1318
0
            7 => Ok(PrimitiveValType::S64),
1319
0
            8 => Ok(PrimitiveValType::U64),
1320
0
            9 => Ok(PrimitiveValType::F32),
1321
0
            10 => Ok(PrimitiveValType::F64),
1322
0
            11 => Ok(PrimitiveValType::Char),
1323
0
            12 => Ok(PrimitiveValType::String),
1324
0
            _ => unreachable!(),
1325
        }
1326
0
    }
1327
1328
0
    fn arbitrary_record_type(
1329
0
        &self,
1330
0
        u: &mut Unstructured,
1331
0
        type_fuel: &mut u32,
1332
0
    ) -> Result<RecordType> {
1333
0
        let mut fields = vec![];
1334
0
        let mut field_names = HashSet::new();
1335
0
        arbitrary_loop(u, 0, 100, |u| {
1336
0
            *type_fuel = type_fuel.saturating_sub(1);
1337
0
            if *type_fuel == 0 {
1338
0
                return Ok(false);
1339
0
            }
1340
1341
0
            let name = crate::unique_kebab_string(100, &mut field_names, u)?;
1342
0
            let ty = self.arbitrary_component_val_type(u)?;
1343
1344
0
            fields.push((name, ty));
1345
0
            Ok(true)
1346
0
        })?;
1347
0
        Ok(RecordType { fields })
1348
0
    }
1349
1350
0
    fn arbitrary_variant_type(
1351
0
        &self,
1352
0
        u: &mut Unstructured,
1353
0
        type_fuel: &mut u32,
1354
0
    ) -> Result<VariantType> {
1355
0
        let mut cases = vec![];
1356
0
        let mut case_names = HashSet::new();
1357
0
        arbitrary_loop(u, 1, 100, |u| {
1358
0
            *type_fuel = type_fuel.saturating_sub(1);
1359
0
            if *type_fuel == 0 {
1360
0
                return Ok(false);
1361
0
            }
1362
1363
0
            let name = crate::unique_kebab_string(100, &mut case_names, u)?;
1364
1365
0
            let ty = u
1366
0
                .arbitrary::<bool>()?
1367
0
                .then(|| self.arbitrary_component_val_type(u))
1368
0
                .transpose()?;
1369
1370
0
            cases.push((name, ty));
1371
0
            Ok(true)
1372
0
        })?;
1373
1374
0
        Ok(VariantType { cases })
1375
0
    }
1376
1377
0
    fn arbitrary_list_type(&self, u: &mut Unstructured) -> Result<ListType> {
1378
        Ok(ListType {
1379
0
            elem_ty: self.arbitrary_component_val_type(u)?,
1380
        })
1381
0
    }
1382
1383
0
    fn arbitrary_tuple_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<TupleType> {
1384
0
        let mut fields = vec![];
1385
0
        arbitrary_loop(u, 0, 100, |u| {
1386
0
            *type_fuel = type_fuel.saturating_sub(1);
1387
0
            if *type_fuel == 0 {
1388
0
                return Ok(false);
1389
0
            }
1390
1391
0
            fields.push(self.arbitrary_component_val_type(u)?);
1392
0
            Ok(true)
1393
0
        })?;
1394
0
        Ok(TupleType { fields })
1395
0
    }
1396
1397
0
    fn arbitrary_flags_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<FlagsType> {
1398
0
        let mut fields = vec![];
1399
0
        let mut field_names = HashSet::new();
1400
0
        arbitrary_loop(u, 0, 100, |u| {
1401
0
            *type_fuel = type_fuel.saturating_sub(1);
1402
0
            if *type_fuel == 0 {
1403
0
                return Ok(false);
1404
0
            }
1405
1406
0
            fields.push(crate::unique_kebab_string(100, &mut field_names, u)?);
1407
0
            Ok(true)
1408
0
        })?;
1409
0
        Ok(FlagsType { fields })
1410
0
    }
1411
1412
0
    fn arbitrary_enum_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<EnumType> {
1413
0
        let mut variants = vec![];
1414
0
        let mut variant_names = HashSet::new();
1415
0
        arbitrary_loop(u, 1, 100, |u| {
1416
0
            *type_fuel = type_fuel.saturating_sub(1);
1417
0
            if *type_fuel == 0 {
1418
0
                return Ok(false);
1419
0
            }
1420
1421
0
            variants.push(crate::unique_kebab_string(100, &mut variant_names, u)?);
1422
0
            Ok(true)
1423
0
        })?;
1424
0
        Ok(EnumType { variants })
1425
0
    }
1426
1427
0
    fn arbitrary_option_type(&self, u: &mut Unstructured) -> Result<OptionType> {
1428
        Ok(OptionType {
1429
0
            inner_ty: self.arbitrary_component_val_type(u)?,
1430
        })
1431
0
    }
1432
1433
0
    fn arbitrary_result_type(&self, u: &mut Unstructured) -> Result<ResultType> {
1434
        Ok(ResultType {
1435
0
            ok_ty: u
1436
0
                .arbitrary::<bool>()?
1437
0
                .then(|| self.arbitrary_component_val_type(u))
1438
0
                .transpose()?,
1439
0
            err_ty: u
1440
0
                .arbitrary::<bool>()?
1441
0
                .then(|| self.arbitrary_component_val_type(u))
1442
0
                .transpose()?,
1443
        })
1444
0
    }
1445
1446
0
    fn arbitrary_defined_type(
1447
0
        &self,
1448
0
        u: &mut Unstructured,
1449
0
        type_fuel: &mut u32,
1450
0
    ) -> Result<DefinedType> {
1451
0
        match u.int_in_range(0..=8)? {
1452
            0 => Ok(DefinedType::Primitive(
1453
0
                self.arbitrary_primitive_val_type(u)?,
1454
            )),
1455
            1 => Ok(DefinedType::Record(
1456
0
                self.arbitrary_record_type(u, type_fuel)?,
1457
            )),
1458
            2 => Ok(DefinedType::Variant(
1459
0
                self.arbitrary_variant_type(u, type_fuel)?,
1460
            )),
1461
0
            3 => Ok(DefinedType::List(self.arbitrary_list_type(u)?)),
1462
0
            4 => Ok(DefinedType::Tuple(self.arbitrary_tuple_type(u, type_fuel)?)),
1463
0
            5 => Ok(DefinedType::Flags(self.arbitrary_flags_type(u, type_fuel)?)),
1464
0
            6 => Ok(DefinedType::Enum(self.arbitrary_enum_type(u, type_fuel)?)),
1465
0
            7 => Ok(DefinedType::Option(self.arbitrary_option_type(u)?)),
1466
0
            8 => Ok(DefinedType::Result(self.arbitrary_result_type(u)?)),
1467
0
            _ => unreachable!(),
1468
        }
1469
0
    }
1470
1471
0
    fn push_import(&mut self, name: String, url: Option<String>, ty: ComponentTypeRef) {
1472
0
        let nth = match self.ensure_section(
1473
0
            |sec| matches!(sec, Section::Import(_)),
1474
0
            || Section::Import(ImportSection { imports: vec![] }),
1475
        ) {
1476
0
            Section::Import(sec) => {
1477
0
                sec.imports.push(Import { name, url, ty });
1478
0
                sec.imports.len() - 1
1479
            }
1480
0
            _ => unreachable!(),
1481
        };
1482
0
        let section_index = self.component().component.sections.len() - 1;
1483
1484
0
        match ty {
1485
0
            ComponentTypeRef::Module(_) => {
1486
0
                self.total_modules += 1;
1487
0
                self.component_mut().modules.push((section_index, nth));
1488
0
            }
1489
0
            ComponentTypeRef::Func(ty_index) => {
1490
0
                let func_ty = match self.current_type_scope().get(ty_index).as_ref() {
1491
0
                    Type::Func(ty) => ty.clone(),
1492
0
                    _ => unreachable!(),
1493
                };
1494
1495
0
                if func_ty.is_scalar() {
1496
0
                    let func_index = u32::try_from(self.component().component_funcs.len()).unwrap();
1497
0
                    self.component_mut().scalar_component_funcs.push(func_index);
1498
0
                }
1499
1500
0
                let func_index = u32::try_from(self.component().funcs.len()).unwrap();
1501
0
                self.component_mut()
1502
0
                    .funcs
1503
0
                    .push(ComponentOrCoreFuncType::Component(func_ty));
1504
1505
0
                self.component_mut().component_funcs.push(func_index);
1506
            }
1507
0
            ComponentTypeRef::Value(ty) => {
1508
0
                self.total_values += 1;
1509
0
                self.component_mut().values.push(ty);
1510
0
            }
1511
0
            ComponentTypeRef::Type(TypeBounds::Eq(ty_index)) => {
1512
0
                let ty = self.current_type_scope().get(ty_index).clone();
1513
0
                self.current_type_scope_mut().push(ty);
1514
0
            }
1515
            ComponentTypeRef::Type(TypeBounds::SubResource) => {
1516
0
                unimplemented!()
1517
            }
1518
0
            ComponentTypeRef::Instance(ty_index) => {
1519
0
                let instance_ty = match self.current_type_scope().get(ty_index).as_ref() {
1520
0
                    Type::Instance(ty) => ty.clone(),
1521
0
                    _ => unreachable!(),
1522
                };
1523
1524
0
                self.total_instances += 1;
1525
0
                self.component_mut()
1526
0
                    .instances
1527
0
                    .push(ComponentOrCoreInstanceType::Component(instance_ty));
1528
            }
1529
0
            ComponentTypeRef::Component(_) => {
1530
0
                self.total_components += 1;
1531
0
                self.component_mut().components.push((section_index, nth));
1532
0
            }
1533
        }
1534
0
    }
1535
1536
0
    fn core_function_type(&self, core_func_index: u32) -> &Rc<crate::core::FuncType> {
1537
0
        self.component().funcs[self.component().core_funcs[core_func_index as usize] as usize]
1538
0
            .as_core()
1539
0
    }
1540
1541
0
    fn component_function_type(&self, func_index: u32) -> &Rc<FuncType> {
1542
0
        self.component().funcs[self.component().component_funcs[func_index as usize] as usize]
1543
0
            .as_component()
1544
0
    }
1545
1546
0
    fn push_func(&mut self, func: Func) {
1547
0
        let nth = match self.component_mut().component.sections.last_mut() {
1548
0
            Some(Section::Canonical(CanonicalSection { funcs })) => funcs.len(),
1549
            _ => {
1550
0
                self.push_section(Section::Canonical(CanonicalSection { funcs: vec![] }));
1551
0
                0
1552
            }
1553
        };
1554
0
        let section_index = self.component().component.sections.len() - 1;
1555
1556
0
        let func_index = u32::try_from(self.component().funcs.len()).unwrap();
1557
1558
0
        let ty = match &func {
1559
0
            Func::CanonLift { func_ty, .. } => {
1560
0
                let ty = Rc::clone(self.current_type_scope().get_func(*func_ty));
1561
0
                if ty.is_scalar() {
1562
0
                    let func_index = u32::try_from(self.component().component_funcs.len()).unwrap();
1563
0
                    self.component_mut().scalar_component_funcs.push(func_index);
1564
0
                }
1565
0
                self.component_mut().component_funcs.push(func_index);
1566
0
                ComponentOrCoreFuncType::Component(ty)
1567
            }
1568
            Func::CanonLower {
1569
0
                func_index: comp_func_index,
1570
                ..
1571
            } => {
1572
0
                let comp_func_ty = self.component_function_type(*comp_func_index);
1573
0
                let core_func_ty = canonical_abi_for(comp_func_ty);
1574
0
                self.component_mut().core_funcs.push(func_index);
1575
0
                ComponentOrCoreFuncType::Core(core_func_ty)
1576
            }
1577
        };
1578
1579
0
        self.component_mut().funcs.push(ty);
1580
1581
0
        match self.component_mut().component.sections.last_mut() {
1582
0
            Some(Section::Canonical(CanonicalSection { funcs })) => funcs.push(func),
1583
0
            _ => unreachable!(),
1584
        }
1585
0
    }
1586
1587
0
    fn arbitrary_import_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1588
0
        self.push_section(Section::Import(ImportSection { imports: vec![] }));
1589
1590
0
        let min = if self.fill_minimums {
1591
0
            self.config
1592
0
                .min_imports
1593
0
                .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
            0
1598
        };
1599
0
        let max = self.config.max_imports - self.component().num_imports;
1600
1601
0
        crate::arbitrary_loop(u, min, max, |u| {
1602
0
            match self.arbitrary_type_ref(u, true, false)? {
1603
0
                Some(ty) => {
1604
0
                    let name =
1605
0
                        crate::unique_kebab_string(100, &mut self.component_mut().import_names, u)?;
1606
0
                    let url = if u.arbitrary()? {
1607
0
                        Some(crate::unique_url(
1608
                            100,
1609
0
                            &mut self.component_mut().import_urls,
1610
0
                            u,
1611
0
                        )?)
1612
                    } else {
1613
0
                        None
1614
                    };
1615
0
                    self.push_import(name, url, ty);
1616
0
                    Ok(true)
1617
                }
1618
0
                None => Ok(false),
1619
            }
1620
0
        })?;
1621
1622
0
        Ok(Step::StillBuilding)
1623
0
    }
1624
1625
0
    fn arbitrary_canonical_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1626
0
        self.push_section(Section::Canonical(CanonicalSection { funcs: vec![] }));
1627
1628
0
        let min = if self.fill_minimums {
1629
0
            self.config
1630
0
                .min_funcs
1631
0
                .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
            0
1636
        };
1637
0
        let max = self.config.max_funcs - self.component().funcs.len();
1638
1639
0
        let mut choices: Vec<fn(&mut Unstructured, &mut ComponentBuilder) -> Result<Option<Func>>> =
1640
0
            Vec::with_capacity(2);
1641
1642
0
        crate::arbitrary_loop(u, min, max, |u| {
1643
0
            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
0
            if !self.component().scalar_component_funcs.is_empty() {
1668
0
                choices.push(|u, c| {
1669
0
                    let func_index = *u.choose(&c.component().scalar_component_funcs)?;
1670
0
                    Ok(Some(Func::CanonLower {
1671
0
                        // Scalar component functions don't use any canonical options.
1672
0
                        options: vec![],
1673
0
                        func_index,
1674
0
                    }))
1675
0
                });
1676
0
            }
1677
1678
0
            if !self.component().core_funcs.is_empty() {
1679
0
                choices.push(|u, c| {
1680
0
                    let core_func_index = u.int_in_range(
1681
0
                        0..=u32::try_from(c.component().core_funcs.len() - 1).unwrap(),
1682
0
                    )?;
1683
0
                    let core_func_ty = c.core_function_type(core_func_index);
1684
0
                    let comp_func_ty = inverse_scalar_canonical_abi_for(u, core_func_ty)?;
1685
1686
0
                    let func_ty = if let Some(indices) = c
1687
0
                        .current_type_scope()
1688
0
                        .func_type_to_indices
1689
0
                        .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
0
                        debug_assert!(!indices.is_empty());
1695
0
                        *u.choose(indices)?
1696
0
                    } 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
0
                        let ty = Rc::new(Type::Func(Rc::new(comp_func_ty)));
1701
0
                        c.push_type(ty)
1702
                    } else {
1703
                        // Otherwise, give up on lifting this function.
1704
0
                        return Ok(None);
1705
                    };
1706
1707
0
                    Ok(Some(Func::CanonLift {
1708
0
                        func_ty,
1709
0
                        // Scalar functions don't use any canonical options.
1710
0
                        options: vec![],
1711
0
                        core_func_index,
1712
0
                    }))
1713
0
                });
1714
0
            }
1715
1716
0
            if choices.is_empty() {
1717
0
                return Ok(false);
1718
0
            }
1719
1720
0
            let f = u.choose(&choices)?;
1721
0
            if let Some(func) = f(u, self)? {
1722
0
                self.push_func(func);
1723
0
            }
1724
1725
0
            Ok(true)
1726
0
        })?;
1727
1728
0
        Ok(Step::StillBuilding)
1729
0
    }
1730
1731
0
    fn arbitrary_core_module_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1732
0
        let module = crate::core::Module::new_internal(
1733
0
            self.config.clone(),
1734
0
            u,
1735
0
            crate::core::DuplicateImportsBehavior::Disallowed,
1736
0
        )?;
1737
0
        self.push_section(Section::CoreModule(module));
1738
0
        self.total_modules += 1;
1739
0
        Ok(Step::StillBuilding)
1740
0
    }
1741
1742
0
    fn arbitrary_component_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1743
0
        self.types.push(TypesScope::default());
1744
0
        self.components.push(ComponentContext::empty());
1745
0
        self.total_components += 1;
1746
0
        Ok(Step::StillBuilding)
1747
0
    }
1748
1749
0
    fn arbitrary_instance_section(&mut self, u: &mut Unstructured) -> Result<()> {
1750
0
        todo!()
1751
    }
1752
1753
0
    fn arbitrary_export_section(&mut self, u: &mut Unstructured) -> Result<()> {
1754
0
        todo!()
1755
    }
1756
1757
0
    fn arbitrary_start_section(&mut self, u: &mut Unstructured) -> Result<()> {
1758
0
        todo!()
1759
    }
1760
1761
0
    fn arbitrary_alias_section(&mut self, u: &mut Unstructured) -> Result<()> {
1762
0
        todo!()
1763
    }
1764
}
1765
1766
0
fn canonical_abi_for(func_ty: &FuncType) -> Rc<crate::core::FuncType> {
1767
0
    let to_core_ty = |ty| match ty {
1768
0
        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
0
            | PrimitiveValType::U32 => ValType::I32,
1777
0
            PrimitiveValType::S64 | PrimitiveValType::U64 => ValType::I64,
1778
0
            PrimitiveValType::F32 => ValType::F32,
1779
0
            PrimitiveValType::F64 => ValType::F64,
1780
            PrimitiveValType::String | PrimitiveValType::ErrorContext => {
1781
0
                unimplemented!("non-scalar types are not supported yet")
1782
            }
1783
        },
1784
0
        ComponentValType::Type(_) => unimplemented!("non-scalar types are not supported yet"),
1785
0
    };
1786
1787
0
    Rc::new(crate::core::FuncType {
1788
0
        params: func_ty
1789
0
            .params
1790
0
            .iter()
1791
0
            .map(|(_, ty)| to_core_ty(*ty))
1792
0
            .collect(),
1793
0
        results: func_ty
1794
0
            .results
1795
0
            .iter()
1796
0
            .map(|(_, ty)| to_core_ty(*ty))
1797
0
            .collect(),
1798
    })
1799
0
}
1800
1801
0
fn inverse_scalar_canonical_abi_for(
1802
0
    u: &mut Unstructured,
1803
0
    core_func_ty: &crate::core::FuncType,
1804
0
) -> Result<FuncType> {
1805
0
    let from_core_ty = |u: &mut Unstructured, core_ty| match core_ty {
1806
0
        ValType::I32 => u
1807
0
            .choose(&[
1808
0
                ComponentValType::Primitive(PrimitiveValType::Char),
1809
0
                ComponentValType::Primitive(PrimitiveValType::Bool),
1810
0
                ComponentValType::Primitive(PrimitiveValType::S8),
1811
0
                ComponentValType::Primitive(PrimitiveValType::U8),
1812
0
                ComponentValType::Primitive(PrimitiveValType::S16),
1813
0
                ComponentValType::Primitive(PrimitiveValType::U16),
1814
0
                ComponentValType::Primitive(PrimitiveValType::S32),
1815
0
                ComponentValType::Primitive(PrimitiveValType::U32),
1816
0
            ])
1817
0
            .cloned(),
1818
0
        ValType::I64 => u
1819
0
            .choose(&[
1820
0
                ComponentValType::Primitive(PrimitiveValType::S64),
1821
0
                ComponentValType::Primitive(PrimitiveValType::U64),
1822
0
            ])
1823
0
            .cloned(),
1824
0
        ValType::F32 => Ok(ComponentValType::Primitive(PrimitiveValType::F32)),
1825
0
        ValType::F64 => Ok(ComponentValType::Primitive(PrimitiveValType::F64)),
1826
        ValType::V128 | ValType::Ref(_) => {
1827
0
            unreachable!("not used in canonical ABI")
1828
        }
1829
0
    };
1830
1831
0
    let mut names = HashSet::default();
1832
0
    let mut params = vec![];
1833
1834
0
    for core_ty in &core_func_ty.params {
1835
0
        params.push((
1836
0
            crate::unique_kebab_string(100, &mut names, u)?,
1837
0
            from_core_ty(u, *core_ty)?,
1838
        ));
1839
    }
1840
1841
0
    names.clear();
1842
1843
0
    let results = match core_func_ty.results.len() {
1844
0
        0 => Vec::new(),
1845
0
        1 => vec![(
1846
0
            if u.arbitrary()? {
1847
0
                Some(crate::unique_kebab_string(100, &mut names, u)?)
1848
            } else {
1849
0
                None
1850
            },
1851
0
            from_core_ty(u, core_func_ty.results[0])?,
1852
        )],
1853
0
        _ => unimplemented!("non-scalar types are not supported yet"),
1854
    };
1855
1856
0
    Ok(FuncType { params, results })
1857
0
}
1858
1859
#[derive(Debug)]
1860
enum 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)]
1876
struct CustomSection {
1877
    name: String,
1878
    data: Vec<u8>,
1879
}
1880
1881
impl<'a> Arbitrary<'a> for CustomSection {
1882
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1883
0
        let name = crate::limited_string(1_000, u)?;
1884
0
        let data = u.arbitrary()?;
1885
0
        Ok(CustomSection { name, data })
1886
0
    }
1887
}
1888
1889
#[derive(Debug)]
1890
struct TypeSection {
1891
    types: Vec<Rc<Type>>,
1892
}
1893
1894
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1895
enum CoreType {
1896
    Func(Rc<crate::core::FuncType>),
1897
    Module(Rc<ModuleType>),
1898
}
1899
1900
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
1901
struct 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)]
1909
enum 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)]
1921
enum 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)]
1929
enum CoreInstanceExportAliasKind {
1930
    Func,
1931
    Table,
1932
    Memory,
1933
    Global,
1934
    Tag,
1935
}
1936
1937
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1938
enum CoreOuterAliasKind {
1939
    Type(Rc<crate::core::FuncType>),
1940
}
1941
1942
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1943
enum 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)]
1962
enum InstanceExportAliasKind {
1963
    Module,
1964
    Component,
1965
    Instance,
1966
    Func,
1967
    Value,
1968
}
1969
1970
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1971
enum OuterAliasKind {
1972
    Module,
1973
    Component,
1974
    CoreType(Rc<CoreType>),
1975
    Type(Rc<Type>),
1976
}
1977
1978
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1979
struct ComponentType {
1980
    defs: Vec<ComponentTypeDef>,
1981
}
1982
1983
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1984
enum 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
1996
impl From<InstanceTypeDecl> for ComponentTypeDef {
1997
0
    fn from(def: InstanceTypeDecl) -> Self {
1998
0
        match def {
1999
0
            InstanceTypeDecl::CoreType(t) => Self::CoreType(t),
2000
0
            InstanceTypeDecl::Type(t) => Self::Type(t),
2001
0
            InstanceTypeDecl::Export { name, url, ty } => Self::Export { name, url, ty },
2002
0
            InstanceTypeDecl::Alias(a) => Self::Alias(a),
2003
        }
2004
0
    }
2005
}
2006
2007
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2008
struct InstanceType {
2009
    defs: Vec<InstanceTypeDecl>,
2010
}
2011
2012
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2013
enum 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)]
2025
struct FuncType {
2026
    params: Vec<(String, ComponentValType)>,
2027
    results: Vec<(Option<String>, ComponentValType)>,
2028
}
2029
2030
impl FuncType {
2031
0
    fn unnamed_result_ty(&self) -> Option<ComponentValType> {
2032
0
        if self.results.len() == 1 {
2033
0
            let (name, ty) = &self.results[0];
2034
0
            if name.is_none() {
2035
0
                return Some(*ty);
2036
0
            }
2037
0
        }
2038
0
        None
2039
0
    }
2040
2041
0
    fn is_scalar(&self) -> bool {
2042
0
        self.params.iter().all(|(_, ty)| is_scalar(ty))
2043
0
            && self.results.len() == 1
2044
0
            && is_scalar(&self.results[0].1)
2045
0
    }
2046
}
2047
2048
0
fn is_scalar(ty: &ComponentValType) -> bool {
2049
0
    match ty {
2050
0
        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
0
            | PrimitiveValType::Char => true,
2063
0
            PrimitiveValType::String | PrimitiveValType::ErrorContext => false,
2064
        },
2065
0
        ComponentValType::Type(_) => false,
2066
    }
2067
0
}
2068
2069
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2070
enum 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)]
2083
struct RecordType {
2084
    fields: Vec<(String, ComponentValType)>,
2085
}
2086
2087
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2088
struct VariantType {
2089
    cases: Vec<(String, Option<ComponentValType>)>,
2090
}
2091
2092
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2093
struct ListType {
2094
    elem_ty: ComponentValType,
2095
}
2096
2097
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2098
struct TupleType {
2099
    fields: Vec<ComponentValType>,
2100
}
2101
2102
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2103
struct FlagsType {
2104
    fields: Vec<String>,
2105
}
2106
2107
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2108
struct EnumType {
2109
    variants: Vec<String>,
2110
}
2111
2112
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2113
struct OptionType {
2114
    inner_ty: ComponentValType,
2115
}
2116
2117
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2118
struct ResultType {
2119
    ok_ty: Option<ComponentValType>,
2120
    err_ty: Option<ComponentValType>,
2121
}
2122
2123
#[derive(Debug)]
2124
struct ImportSection {
2125
    imports: Vec<Import>,
2126
}
2127
2128
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2129
struct Import {
2130
    name: String,
2131
    url: Option<String>,
2132
    ty: ComponentTypeRef,
2133
}
2134
2135
#[derive(Debug)]
2136
struct CanonicalSection {
2137
    funcs: Vec<Func>,
2138
}
2139
2140
#[derive(Debug)]
2141
enum 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)]
2154
enum CanonOpt {
2155
    StringUtf8,
2156
    StringUtf16,
2157
    StringLatin1Utf16,
2158
    Memory(u32),
2159
    Realloc(u32),
2160
    PostReturn(u32),
2161
}
2162
2163
#[derive(Debug)]
2164
struct InstanceSection {}
2165
2166
#[derive(Debug)]
2167
struct ExportSection {}
2168
2169
#[derive(Debug)]
2170
struct StartSection {}
2171
2172
#[derive(Debug)]
2173
struct AliasSection {}
2174
2175
#[derive(Debug)]
2176
struct CoreInstanceSection {}
2177
2178
#[derive(Debug)]
2179
struct CoreTypeSection {
2180
    types: Vec<Rc<CoreType>>,
2181
}
2182
2183
0
fn arbitrary_func_type(
2184
0
    u: &mut Unstructured,
2185
0
    config: &Config,
2186
0
    valtypes: &[ValType],
2187
0
    max_results: Option<usize>,
2188
0
    type_ref_limit: u32,
2189
0
) -> Result<Rc<crate::core::FuncType>> {
2190
0
    let mut params = vec![];
2191
0
    let mut results = vec![];
2192
0
    arbitrary_loop(u, 0, 20, |u| {
2193
0
        params.push(arbitrary_valtype(u, config, valtypes, type_ref_limit)?);
2194
0
        Ok(true)
2195
0
    })?;
2196
0
    arbitrary_loop(u, 0, max_results.unwrap_or(20), |u| {
2197
0
        results.push(arbitrary_valtype(u, config, valtypes, type_ref_limit)?);
2198
0
        Ok(true)
2199
0
    })?;
2200
0
    Ok(Rc::new(crate::core::FuncType { params, results }))
2201
0
}
2202
2203
0
fn arbitrary_valtype(
2204
0
    u: &mut Unstructured,
2205
0
    config: &Config,
2206
0
    valtypes: &[ValType],
2207
0
    type_ref_limit: u32,
2208
0
) -> Result<ValType> {
2209
0
    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
0
            heap_type: HeapType::Concrete(u.int_in_range(0..=type_ref_limit - 1)?),
2219
        }))
2220
    } else {
2221
0
        Ok(*u.choose(valtypes)?)
2222
    }
2223
0
}