1#![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#[derive(Debug)]
34pub struct Component {
35 sections: Vec<Section>,
36}
37
38#[derive(Debug)]
48struct ComponentBuilder {
49 config: Config,
50
51 core_valtypes: Vec<ValType>,
53
54 types: Vec<TypesScope>,
67
68 components: Vec<ComponentContext>,
71
72 fill_minimums: bool,
77
78 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#[derive(Debug)]
117struct ComponentContext {
118 component: Component,
120
121 num_imports: usize,
123
124 import_names: HashSet<String>,
126
127 import_urls: HashSet<String>,
129
130 funcs: Vec<ComponentOrCoreFuncType>,
132
133 component_funcs: Vec<u32>,
135
136 scalar_component_funcs: Vec<u32>,
139
140 core_funcs: Vec<u32>,
145
146 components: Vec<(usize, usize)>,
161
162 modules: Vec<(usize, usize)>,
177
178 instances: Vec<ComponentOrCoreInstanceType>,
180
181 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 core_types: Vec<Rc<CoreType>>,
228
229 core_func_types: Vec<u32>,
231
232 module_types: Vec<u32>,
234
235 types: Vec<Rc<Type>>,
237
238 defined_types: Vec<u32>,
240
241 func_types: Vec<u32>,
243
244 func_type_to_indices: HashMap<Rc<FuncType>, Vec<u32>>,
246
247 component_types: Vec<u32>,
249
250 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 !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 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 if !u.is_empty() {
381 choices.push(Self::arbitrary_custom_section);
382
383 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 }
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 return Ok(component);
416 } else {
417 self.push_section(Section::Component(component));
419 }
420 }
421 }
422 }
423 }
424
425 fn finish_component(&mut self, u: &mut Unstructured) -> Result<Step> {
426 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 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 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 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 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, ),
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 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, ),
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 if !types.is_empty()
776 || (!self.types.is_empty()
777 && !self.types.last().unwrap().core_func_types.is_empty())
778 {
779 3
781 } else {
782 2
784 }
785 } else {
786 1
788 };
789
790 match u.int_in_range::<u8>(0..=max_choice)? {
791 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 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 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 )); }
845
846 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 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 }
1031
1032 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 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 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 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 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 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 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 let name = if results.is_empty() {
1267 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 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 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 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 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 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 debug_assert!(!indices.is_empty());
1695 *u.choose(indices)?
1696 } else if c.current_type_scope().types.len() < c.config.max_types {
1697 let ty = Rc::new(Type::Func(Rc::new(comp_func_ty)));
1701 c.push_type(ty)
1702 } else {
1703 return Ok(None);
1705 };
1706
1707 Ok(Some(Func::CanonLift {
1708 func_ty,
1709 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 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}