sonatina_ir/builder/
module_builder.rs1use 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 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}