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
11pub(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 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}