Add a minimal SimpleJIT example program.

This minimally demonstrates usage of the API, and serves as a very small
testcase to test that the basic JIT mechanisms are working.
This commit is contained in:
Dan Gohman
2018-08-28 16:10:39 -07:00
parent bdd1949b34
commit d2943ec32d
7 changed files with 114 additions and 5 deletions

View File

@@ -21,6 +21,9 @@ target-lexicon = { version = "0.0.3", default-features = false }
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3", features = ["winbase", "memoryapi"] }
[dev-dependencies]
cranelift = { path = "../umbrella", version = "0.19.0", default-features = false }
[features]
default = ["std"]
std = ["libc/use_std", "cranelift-codegen/std", "cranelift-module/std", "cranelift-native/std", "target-lexicon/std"]

View File

@@ -2,3 +2,7 @@ This crate provides a simple JIT library that uses
[Cranelift](https://crates.io/crates/cranelift).
This crate is extremely experimental.
See the [example program] for a brief overview of how to use this.
[example program]: https://github.com/CraneStation/cranelift/tree/master/lib/simplejit/examples/simplejit-minimal.rs

View File

@@ -0,0 +1,58 @@
extern crate cranelift;
extern crate cranelift_module;
extern crate cranelift_simplejit;
use cranelift::prelude::*;
use cranelift_module::{Linkage, Module};
use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder};
use std::mem;
fn main() {
let mut module: Module<SimpleJITBackend> = Module::new(SimpleJITBuilder::new());
let mut ctx = module.make_context();
let mut func_ctx = FunctionBuilderContext::new();
let sig = module.make_signature();
let func_a = module.declare_function("a", Linkage::Local, &sig).unwrap();
let func_b = module.declare_function("b", Linkage::Local, &sig).unwrap();
ctx.func.name = ExternalName::user(0, func_a.index() as u32);
{
let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let ebb = bcx.create_ebb();
bcx.switch_to_block(ebb);
bcx.ins().return_(&[]);
bcx.seal_all_blocks();
bcx.finalize();
}
module.define_function(func_a, &mut ctx).unwrap();
module.clear_context(&mut ctx);
ctx.func.name = ExternalName::user(0, func_b.index() as u32);
{
let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let ebb = bcx.create_ebb();
bcx.switch_to_block(ebb);
let local_func = module.declare_func_in_func(func_a, &mut bcx.func);
bcx.ins().call(local_func, &[]);
bcx.ins().return_(&[]);
bcx.seal_all_blocks();
bcx.finalize();
}
module.define_function(func_b, &mut ctx).unwrap();
module.clear_context(&mut ctx);
// Perform linking.
module.finalize_all();
// Get a raw pointer to the generated code.
let code_b = module.get_finalized_function(func_b);
// Cast it to a rust function pointer type.
let ptr_b = unsafe { mem::transmute::<_, fn()>(code_b) };
// Call it!
ptr_b();
}

View File

@@ -334,7 +334,10 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
_ => unimplemented!(),
}
}
func.code
}
fn get_finalized_function(&self, func: &Self::CompiledFunction) -> Self::FinalizedFunction {
func.code
}
@@ -394,7 +397,10 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
}
}
}
(data.storage, data.size)
}
fn get_finalized_data(&self, data: &Self::CompiledData) -> Self::FinalizedData {
(data.storage, data.size)
}