use std::cell::RefCell;
use super::error::CompileError;
thread_local! {
static TLS_MODULE: RefCell<Option<cranelift_jit::JITModule>> = const { RefCell::new(None) };
}
fn create_module() -> Result<cranelift_jit::JITModule, CompileError> {
use cranelift_codegen::settings;
let flags = settings::Flags::new(settings::builder());
let isa = cranelift_native::builder()
.map_err(|e| CompileError::Backend(e.to_string()))?
.finish(flags)
.map_err(|e| CompileError::Backend(e.to_string()))?;
let builder =
cranelift_jit::JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
Ok(cranelift_jit::JITModule::new(builder))
}
pub fn with_jit_module<R>(
f: impl FnOnce(&mut cranelift_jit::JITModule) -> Result<R, CompileError>,
) -> Result<R, CompileError> {
TLS_MODULE.with(|cell| {
let mut slot = cell.borrow_mut();
if slot.is_none() {
*slot = Some(create_module()?);
}
let module = slot.as_mut().ok_or_else(|| {
CompileError::Backend("thread-local JIT module failed to initialize".into())
})?;
f(module)
})
}