Skip to main content

dada_codegen/
cx.rs

1use dada_ir_sym::{ir::functions::SymFunction, ir::types::SymGenericTerm};
2use dada_util::{FromImpls, Map};
3use salsa::Update;
4use wasm_encoder::{CodeSection, FunctionSection, TypeSection};
5
6mod generate_expr;
7mod generate_fn;
8mod wasm_fn_type;
9mod wasm_repr;
10
11/// Core codegen context.
12pub(crate) struct Cx<'db> {
13    db: &'db dyn crate::Db,
14    function_section: FunctionSection,
15    type_section: TypeSection,
16    code_section: CodeSection,
17    functions: Map<FnKey<'db>, FnIndex>,
18    codegen_queue: Vec<CodegenQueueItem<'db>>,
19}
20
21impl<'db> Cx<'db> {
22    pub fn new(db: &'db dyn crate::Db) -> Self {
23        Self {
24            db,
25            function_section: Default::default(),
26            type_section: Default::default(),
27            code_section: Default::default(),
28            functions: Default::default(),
29            codegen_queue: Default::default(),
30        }
31    }
32
33    /// Generates all code reachable from the given fn instantiated with the given arguments.
34    pub fn generate_from_fn(
35        mut self,
36        function: SymFunction<'db>,
37        generics: Vec<SymGenericTerm<'db>>,
38    ) -> wasm_encoder::Module {
39        self.declare_fn(function, generics);
40        while let Some(item) = self.codegen_queue.pop() {
41            match item {
42                CodegenQueueItem::Function(fn_key) => self.codegen_fn(fn_key),
43            }
44        }
45
46        let mut module = wasm_encoder::Module::new();
47        module.section(&self.type_section);
48        module.section(&self.function_section);
49        module.section(&self.code_section);
50
51        module
52    }
53}
54
55#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Update)]
56pub(crate) struct FnKey<'db>(SymFunction<'db>, Vec<SymGenericTerm<'db>>);
57
58#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Update)]
59pub(crate) struct FnIndex(u32);
60
61#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Update, FromImpls)]
62enum CodegenQueueItem<'db> {
63    Function(FnKey<'db>),
64}