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