wast_encoder/dag/
mod.rs

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                        // only one task in fact
84                        imports.push(CanonicalImport::Type(task.clone()))
85                    }
86                }
87            }
88        }
89        Ok(imports)
90    }
91}