use std::mem;
use melior::{ExecutionEngine, ir::Module};
use crate::{
MathicResult, codegen::compiler_helper::debugging, compiler::OptLvl, diagnostics::CodegenError,
};
pub struct MathicExecutor {
engine: ExecutionEngine,
}
impl MathicExecutor {
pub fn new(module: &Module, opt_lvl: OptLvl) -> MathicResult<Self> {
let engine = ExecutionEngine::new(module, opt_lvl.into(), &[], false);
let executor = Self { engine };
debugging::debug_utils_runtime::setup(|sym| executor.lookup_symbol(sym));
Ok(executor)
}
pub fn call_function(&self, symbol_name: &str) -> Result<i64, CodegenError> {
let func: fn() -> i64 = unsafe {
mem::transmute(
self.lookup_symbol(&format!("mathic__{}", symbol_name))
.unwrap(),
)
};
Ok(func())
}
pub fn lookup_symbol(&self, symbol_name: &str) -> Option<*mut ()> {
let ptr = self.engine.lookup(symbol_name);
if ptr.is_null() { None } else { Some(ptr) }
}
}