Last active
September 29, 2024 12:19
-
-
Save juanbono/9ad4d22e99ea73579691bcf60c765d42 to your computer and use it in GitHub Desktop.
cranelift binary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use cranelift::prelude::*; | |
use cranelift_module::{Linkage, Module}; | |
use cranelift_object::{ObjectBuilder, ObjectModule}; | |
fn main() { | |
// create a settings builder to configure the opt level | |
let mut settings_builder = settings::builder(); | |
// disable optimizations | |
// TODO: take the opt level in the CLI. | |
settings_builder.set("opt_level", "none").unwrap(); | |
let flags = settings::Flags::new(settings_builder); | |
// create the ISA builder using the native configuration. | |
let isa_builder = cranelift_native::builder().unwrap(); | |
let isa = isa_builder.finish(flags).unwrap(); | |
// to create a function first we need to create its signature | |
let mut signature = Signature::new(isa::CallConv::SystemV); | |
// add the return type | |
signature.returns.push(AbiParam::new(types::I64)); | |
let object_builder = | |
ObjectBuilder::new(isa, "main", cranelift_module::default_libcall_names()).unwrap(); | |
let mut module = ObjectModule::new(object_builder); | |
let function_id = module | |
.declare_function("main", Linkage::Export, &signature) | |
.unwrap(); | |
// now we can create our function | |
let mut function = codegen::ir::Function::with_name_signature( | |
codegen::ir::UserFuncName::user(0, 0), | |
signature, | |
); | |
// we also need a function builder context | |
let mut func_ctx = FunctionBuilderContext::new(); | |
// and with both we can create our function builder, where we are going to store the generated instructions | |
let mut function_builder = FunctionBuilder::new(&mut function, &mut func_ctx); | |
// code generation | |
// create an empty block and switch to it. | |
let block = function_builder.create_block(); | |
function_builder.seal_block(block); | |
function_builder.append_block_params_for_function_params(block); | |
function_builder.switch_to_block(block); | |
// insert the "return 2" instruction | |
let return_value = function_builder.ins().iconst(types::I64, 42); | |
function_builder.ins().return_(&[return_value]); | |
// finalize the code generation of the function | |
function_builder.finalize(); | |
let mut ctx = codegen::Context::for_function(function); | |
module.define_function(function_id, &mut ctx).unwrap(); | |
let object_product = module.finish(); | |
// emit the code into a vec of bytes | |
let bytes = object_product.emit().unwrap(); | |
// save it to link it later | |
std::fs::write("main.o", bytes).unwrap(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment