1use std::{collections::BTreeMap, fmt::Debug, ops::AddAssign};
2
3use dependent_sort::{DependentSort, TopologicalError};
4
5use crate::{
6 wasi_types::functions::WasiFunctionBody, CanonicalImport, Identifier, WasiInstance, WasiModule, WasiType, WasiTypeReference,
7};
8
9mod arithmetic;
10
11pub(crate) trait DependenciesTrace {
12 fn define_language_types(&self, dict: &mut DependentGraph);
13 fn collect_wasi_types<'a, 'i>(&'a self, dict: &'i DependentGraph, collected: &mut Vec<&'i WasiType>)
14 where
15 'a: 'i;
16}
17
18#[derive(Default, Debug)]
19pub struct DependentGraph {
20 pub(crate) types: BTreeMap<Identifier, WasiType>,
21}
22
23impl DependentGraph {
24 pub fn get(&self, type_id: &WasiTypeReference) -> &WasiType {
25 match self.types.get(&type_id.symbol) {
26 Some(s) => s,
27 None => panic!("Missing Type `{}` in DependentGraph", type_id.symbol),
28 }
29 }
30
31 fn build_dag(&self) -> DependentSort<WasiType, WasiModule> {
32 let mut sorter = DependentSort::default();
33 for ty in self.types.values() {
34 let mut dependents: Vec<&WasiType> = vec![];
35 match ty {
36 WasiType::Integer8 { .. } => {}
37 WasiType::Integer16 { .. } => {}
38 WasiType::Integer32 { .. } => {}
39 WasiType::Integer64 { .. } => {}
40 WasiType::Option { .. } => {}
41 WasiType::Result { .. } => {}
42 WasiType::Resource(v) => {
43 sorter += dependent_sort::Task::new(ty).with_group(&v.wasi_module);
44 }
45 WasiType::Record(v) => {
46 v.collect_wasi_types(self, &mut dependents);
47 sorter += dependent_sort::Task::new_with_dependent(&ty, dependents);
48 }
49 WasiType::Variant(v) => {
50 v.collect_wasi_types(self, &mut dependents);
51 sorter += dependent_sort::Task::new_with_dependent(&ty, dependents);
52 }
53 WasiType::TypeHandler { .. } => {}
54 WasiType::External(v) => match &v.body {
55 WasiFunctionBody::External { wasi_module, .. } => {
56 v.collect_wasi_types(self, &mut dependents);
57 sorter += dependent_sort::Task { id: ty, group: Some(wasi_module), dependent_tasks: dependents };
58 }
59 WasiFunctionBody::Normal { .. } => {}
60 },
61 WasiType::Array { .. } => {}
62 WasiType::Float32 => {}
63 WasiType::Float64 => {}
64 WasiType::Boolean => {}
65 WasiType::Function(_) => {}
66 }
67 }
68 sorter
69 }
70 pub fn resolve_imports(&self) -> Result<Vec<CanonicalImport>, TopologicalError<WasiType, WasiModule>> {
71 let mut imports = vec![];
72 for group in self.build_dag().sort_grouped_hash_specialization()? {
73 match group.id {
74 Some(s) => {
75 let mut instance = WasiInstance::new(s.clone());
76 for task in group.tasks {
77 instance.insert(task);
78 }
79 imports.push(CanonicalImport::Instance(instance));
80 }
81 None => {
82 for task in group.tasks {
83 imports.push(CanonicalImport::Type(task.clone()))
85 }
86 }
87 }
88 }
89 Ok(imports)
90 }
91}