quickscript/codegen/
backend.rs

1use anyhow::Result;
2use cranelift_codegen::{ir::Function, write_function, CompiledCode, Context};
3use cranelift_frontend::FunctionBuilderContext;
4use cranelift_module::{DataDescription, Module};
5
6pub struct CraneliftBackend<T>
7where
8    T: Module,
9{
10    pub builder_ctx: FunctionBuilderContext,
11    pub ctx: Context,
12    pub data_desc: DataDescription,
13    pub module: T,
14    pub fns: Vec<Function>,
15    pub code: Vec<CompiledCode>,
16    pub disasm: bool,
17    pub is_jit: bool,
18    pub watch_mode: bool,
19    pub bytecode: Vec<(String, *const u8, usize)>,
20}
21
22impl<T> CraneliftBackend<T>
23where
24    T: Module,
25{
26    pub fn output_clif(&self) -> Result<String> {
27        let mut buf = String::new();
28        let isa = self.module.isa();
29
30        for func in self.fns.clone() {
31            write_function(&mut buf, &func)?;
32        }
33
34        write_function(&mut buf, &self.ctx.func)?;
35
36        for flag in isa.flags().iter() {
37            buf.push_str(format!("set {}\n", flag).as_str());
38        }
39
40        buf.push_str(format!("target {}", isa.triple().architecture).as_str());
41
42        for isa_flag in isa.isa_flags().iter() {
43            buf.push_str(format!(" {}", isa_flag).as_str());
44        }
45
46        buf.push('\n');
47        buf.push('\n');
48        buf.push('\n');
49
50        Ok(buf)
51    }
52
53    pub fn vcode(&self) -> String {
54        self.code
55            .iter()
56            .map(|v| v.vcode.clone())
57            .filter(|v| v.is_some())
58            .map(|v| v.unwrap())
59            .collect::<Vec<String>>()
60            .join("\n")
61    }
62}