Last active
September 11, 2021 00:34
-
-
Save DGriffin91/5bbbd888c53e63bbfefd04a6af1c8760 to your computer and use it in GitHub Desktop.
Return a slice from a function defined in cranelift
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
/* | |
[dependencies] | |
cranelift = "0.76.0" | |
cranelift-jit = "0.76.0" | |
cranelift-module = "0.76.0" | |
*/ | |
use cranelift::{ | |
codegen::{ | |
self, | |
ir::{immediates::Offset32, ArgumentPurpose}, | |
}, | |
frontend::{FunctionBuilder, FunctionBuilderContext}, | |
prelude::{types, AbiParam, InstBuilder, MemFlags}, | |
}; | |
use cranelift_jit::{JITBuilder, JITModule}; | |
use cranelift_module::{Linkage, Module}; | |
fn main() { | |
let builder = JITBuilder::new(cranelift_module::default_libcall_names()); | |
let mut builder_context = FunctionBuilderContext::new(); | |
let mut module = JITModule::new(builder); | |
let mut ctx = module.make_context(); | |
let ptr_ty = module.target_config().pointer_type(); | |
let mut fn_sig = module.make_signature(); | |
fn_sig | |
.params | |
.push(AbiParam::special(ptr_ty, ArgumentPurpose::StructReturn)); | |
fn_sig.params.push(AbiParam::new(types::F64)); | |
ctx.func.signature = fn_sig; | |
let mut builder = FunctionBuilder::new(&mut ctx.func, &mut 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 return_ptr = builder.block_params(entry_block)[0]; | |
let mult_val_ptr = builder.block_params(entry_block)[1]; | |
for i in 0..4 { | |
let mval = builder.ins().f64const((i + 1) as f64); | |
let new_val = builder.ins().fmul(mval, mult_val_ptr); | |
builder.ins().store( | |
MemFlags::trusted(), | |
new_val, | |
return_ptr, | |
Offset32::new((i * types::F64.bytes()) as i32), | |
); | |
} | |
builder.ins().return_(&[]); | |
println!("{}", builder.func.display(None)); | |
builder.finalize(); | |
let test_fn_id = module | |
.declare_function("test_fn", Linkage::Export, &ctx.func.signature) | |
.unwrap(); | |
module | |
.define_function( | |
test_fn_id, | |
&mut ctx, | |
&mut codegen::binemit::NullTrapSink {}, | |
&mut codegen::binemit::NullStackMapSink {}, | |
) | |
.unwrap(); | |
module.finalize_definitions(); | |
let func: *const u8 = module.get_finalized_function(test_fn_id); | |
let array = unsafe { | |
let func = std::mem::transmute::<_, unsafe extern "C" fn(f64) -> [f64; 4]>(func); | |
func(5.0) | |
}; | |
println!("after {:?}", array); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment