Skip to content

Instantly share code, notes, and snippets.

@DGriffin91
Last active September 11, 2021 00:34
Show Gist options
  • Save DGriffin91/5bbbd888c53e63bbfefd04a6af1c8760 to your computer and use it in GitHub Desktop.
Save DGriffin91/5bbbd888c53e63bbfefd04a6af1c8760 to your computer and use it in GitHub Desktop.
Return a slice from a function defined in cranelift
/*
[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