use cranelift::prelude::*;
use cranelift_jit::{JITBuilder, JITModule};
use std::collections::HashMap;
use crate::context::JITConfig;
use crate::error::JitError;
use crate::ffi_symbols::{declare_ffi_functions, register_ffi_symbols};
pub struct JITCompiler {
pub(super) module: JITModule,
pub(super) builder_context: FunctionBuilderContext,
#[allow(dead_code)]
pub(super) config: JITConfig,
pub(super) compiled_functions: HashMap<String, *const u8>,
pub(super) ffi_funcs: HashMap<String, cranelift_module::FuncId>,
pub(super) function_table: Vec<*const u8>,
pub(super) compiled_dc_funcs: HashMap<u16, (cranelift_module::FuncId, u16)>,
}
impl JITCompiler {
pub fn module_mut(&mut self) -> &mut JITModule {
&mut self.module
}
pub fn builder_context_mut(&mut self) -> &mut FunctionBuilderContext {
&mut self.builder_context
}
}
impl JITCompiler {
#[inline(always)]
pub fn new(config: JITConfig) -> Result<Self, JitError> {
let mut flag_builder = settings::builder();
let opt_level_str = if config.opt_level >= 2 {
"speed"
} else {
"speed_and_size"
};
flag_builder
.set("opt_level", opt_level_str)
.map_err(|e| JitError::Setup(format!("Failed to set opt_level: {}", e)))?;
flag_builder
.set("is_pic", "false")
.map_err(|e| JitError::Setup(format!("Failed to set is_pic: {}", e)))?;
let isa_builder = cranelift_native::builder()
.map_err(|e| JitError::Setup(format!("Failed to create ISA builder: {}", e)))?;
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.map_err(|e| JitError::Setup(format!("Failed to create ISA: {}", e)))?;
let mut builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
register_ffi_symbols(&mut builder);
let mut module = JITModule::new(builder);
let ffi_funcs = declare_ffi_functions(&mut module);
Ok(Self {
module,
builder_context: FunctionBuilderContext::new(),
config,
compiled_functions: HashMap::new(),
ffi_funcs,
function_table: Vec::new(),
compiled_dc_funcs: HashMap::new(),
})
}
}