Skip to main content

sonatina_ir/builder/
module_builder.rs

1use cranelift_entity::PrimaryMap;
2use fxhash::FxHashMap;
3
4use crate::{
5    module::{FuncRef, ModuleCtx},
6    Function, GlobalVariable, GlobalVariableData, Module, Signature, Type,
7};
8
9use super::FunctionBuilder;
10
11#[derive(Debug)]
12pub struct ModuleBuilder {
13    pub funcs: PrimaryMap<FuncRef, Function>,
14
15    pub ctx: ModuleCtx,
16
17    /// Map function name -> FuncRef to avoid duplicated declaration.
18    declared_funcs: FxHashMap<String, FuncRef>,
19}
20
21impl ModuleBuilder {
22    pub fn new(ctx: ModuleCtx) -> Self {
23        Self {
24            funcs: PrimaryMap::default(),
25            ctx,
26            declared_funcs: FxHashMap::default(),
27        }
28    }
29
30    pub fn declare_function(&mut self, sig: Signature) -> FuncRef {
31        if self.declared_funcs.contains_key(sig.name()) {
32            panic!("{} is already declared.", sig.name())
33        } else {
34            let name = sig.name().to_string();
35            let func = Function::new(&self.ctx, sig);
36            let func_ref = self.funcs.push(func);
37            self.declared_funcs.insert(name, func_ref);
38            func_ref
39        }
40    }
41
42    pub fn make_global(&self, global: GlobalVariableData) -> GlobalVariable {
43        self.ctx.with_gv_store_mut(|s| s.make_gv(global))
44    }
45
46    pub fn global_by_name(&self, name: &str) -> Option<GlobalVariable> {
47        self.ctx.with_gv_store(|s| s.gv_by_symbol(name))
48    }
49
50    pub fn declare_struct_type(&mut self, name: &str, fields: &[Type], packed: bool) -> Type {
51        self.ctx
52            .with_ty_store_mut(|s| s.make_struct(name, fields, packed))
53    }
54
55    pub fn get_func_ref(&self, name: &str) -> Option<FuncRef> {
56        self.declared_funcs.get(name).copied()
57    }
58
59    pub fn get_sig(&self, func: FuncRef) -> &Signature {
60        &self.funcs[func].sig
61    }
62
63    pub fn func_builder(&mut self, func: FuncRef) -> FunctionBuilder {
64        FunctionBuilder::new(self, func)
65    }
66
67    pub fn build(self) -> Module {
68        Module {
69            funcs: self.funcs,
70            ctx: self.ctx,
71        }
72    }
73}