Screen Labs


use cranelift::codegen;
use cranelift::codegen::settings::{self, Configurable};
use cranelift::prelude::*;
use cranelift_jit::{JITBuilder, JITModule};
use cranelift_module::{DataContext, Linkage, Module};

pub struct Codegen {
    pub builder_context: FunctionBuilderContext,
    pub data_context: DataContext,
    pub context: codegen::Context,
    pub module: JITModule,
}

impl Default for Codegen {
    fn default() -> Self {
        let mut flag_builder = settings::builder();
        flag_builder.set("use_colocated_libcalls", "false").unwrap();
        flag_builder.set("is_pic", "false").unwrap();
        let isa = cranelift_native::builder()
            .unwrap_or_else(|message| panic!("Host machine target is not supported: {message}"))
            .finish(settings::Flags::new(flag_builder))
            .unwrap();
        let builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
        let module = JITModule::new(builder);

        Self {
            builder_context: FunctionBuilderContext::new(),
            data_context: DataContext::new(),
            context: module.make_context(),
            module,
        }
    }
}

impl Codegen {
    pub fn codegen(&mut self) -> Result<*const u8, String> {
        let sym = self
            .module
            .declare_function("main", Linkage::Export, &self.context.func.signature)
            .map_err(|error| error.to_string())?;

        self.module.clear_context(&mut self.context);

        self.module.finalize_definitions().unwrap();

        let code = self.module.get_finalized_function(sym);

        Ok(code)
    }

    pub fn build_main_func(&mut self) -> Result<(), String> {
        let int = self.module.target_config().pointer_type();

        self.context.func.signature.returns.push(AbiParam::new(int));

        let mut builder = FunctionBuilder::new(&mut self.context.func, &mut self.builder_context);

        let entry_block = builder.create_block();

        builder.append_block_params_for_function_params(entry_block);
        builder.switch_to_block(entry_block);
        builder.seal_block(entry_block);
        let v = builder.ins().iconst(int, i64::from(0));
        builder.ins().return_(&[v]);
        builder.finalize();

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_claudio() {
        let mut codegen = Codegen::default();
        let bc = unsafe { codegen.codegen().unwrap().as_ref().unwrap() };

        println!("hello! {bc}");
    }
}
    
Created at 1/19/2026
Expires at 1/19/2026