Skip to content

Commit 814225f

Browse files
committed
Bump versions, and simplify execution engine
1 parent 6c2e729 commit 814225f

File tree

4 files changed

+44
-42
lines changed

4 files changed

+44
-42
lines changed

Cargo.lock

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/fib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ fn main() {
3030
let fa = builder.build_tail_call(func, &[a]);
3131
let fb = builder.build_tail_call(func, &[b]);
3232
builder.build_ret(builder.build_add(fa, fb));
33+
println!("{:?}", module);
3334
module.verify().unwrap();
3435
let ee = JitEngine::new(&module, JitOptions {opt_level: 0}).unwrap();
3536
ee.with_function(func, |fib: extern fn(u64) -> u64| {

src/engine.rs

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use ffi::{core, target};
33
use ffi::execution_engine as engine;
44
use ffi::execution_engine::*;
55
use ffi::target_machine::LLVMCodeModel;
6-
use cbox::CBox;
6+
use cbox::{CBox, CSemiBox, DisposeRef};
77
use std::marker::PhantomData;
88
use std::{mem, ptr};
99
use std::ops::*;
@@ -17,36 +17,36 @@ use value::{Function, Value};
1717
/// An abstract interface for implementation execution of LLVM modules.
1818
///
1919
/// This is designed to support both interpreter and just-in-time (JIT) compiler implementations.
20-
pub trait ExecutionEngine<'a, 'b:'a>:Sized+'b where LLVMExecutionEngineRef:From<&'b Self> {
20+
pub trait ExecutionEngine<'a>:'a + Sized + DisposeRef where LLVMExecutionEngineRef: From<&'a Self> {
2121
/// The options given to the engine upon creation.
2222
type Options : Copy;
23-
/// Create a new execution engine with the given `Module` and options, or return a
23+
/// Create a new execution engine with the given `Module` and optiions, or return a
2424
/// description of the error.
25-
fn new(module: &'a Module, options: Self::Options) -> Result<Self, CBox<str>>;
25+
fn new(module: &'a Module, options: Self::Options) -> Result<CSemiBox<'a, Self>, CBox<str>>;
2626

2727
/// Add a module to the list of modules to interpret or compile.
28-
fn add_module(&'b self, module: &'a Module) {
28+
fn add_module(&'a self, module: &'a Module) {
2929
unsafe { engine::LLVMAddModule(self.into(), (&*module).into()) }
3030
}
3131
/// Remove a module from the list of modules to interpret or compile.
32-
fn remove_module(&'b self, module: &'a Module) -> &'a Module {
32+
fn remove_module(&'a self, module: &'a Module) -> &'a Module {
3333
unsafe {
3434
let mut out = mem::uninitialized();
3535
engine::LLVMRemoveModule(self.into(), module.into(), &mut out, ptr::null_mut());
3636
out.into()
3737
}
3838
}
3939
/// Execute all of the static constructors for this program.
40-
fn run_static_constructors(&'b self) {
40+
fn run_static_constructors(&'a self) {
4141
unsafe { engine::LLVMRunStaticConstructors(self.into()) }
4242
}
4343
/// Execute all of the static destructors for this program.
44-
fn run_static_destructors(&'b self) {
44+
fn run_static_destructors(&'a self) {
4545
unsafe { engine::LLVMRunStaticDestructors(self.into()) }
4646
}
4747
/// Attempt to find a function with the name given, or `None` if there wasn't
4848
/// a function with that name.
49-
fn find_function(&'b self, name: &str) -> Option<&'a Function> {
49+
fn find_function(&'a self, name: &str) -> Option<&'a Function> {
5050
util::with_cstr(name, |c_name| unsafe {
5151
let mut out = mem::zeroed();
5252
engine::LLVMFindFunction(self.into(), c_name, &mut out);
@@ -60,22 +60,22 @@ pub trait ExecutionEngine<'a, 'b:'a>:Sized+'b where LLVMExecutionEngineRef:From<
6060
///
6161
/// To convert the arguments to `GenericValue`s, you should use the `GenericValueCast::to_generic` method.
6262
/// To convert the return value from a `GenericValue`, you should use the `GenericValueCast::from_generic` method.
63-
fn run_function(&'b self, function: &'a Function, args: &[GenericValue<'a>]) -> GenericValue<'a> {
63+
fn run_function(&'a self, function: &'a Function, args: &[GenericValue<'a>]) -> GenericValue<'a> {
6464
let ptr = args.as_ptr() as *mut LLVMGenericValueRef;
6565
unsafe { engine::LLVMRunFunction(self.into(), function.into(), args.len() as c_uint, ptr).into() }
6666
}
6767
/// Returns a pointer to the global value given.
6868
///
6969
/// This is marked as unsafe because the type cannot be guranteed to be the same as the
7070
/// type of the global value at this point.
71-
unsafe fn get_global<T>(&'b self, global: &'a Value) -> &'b T {
71+
unsafe fn get_global<T>(&'a self, global: &'a Value) -> &'a T {
7272
mem::transmute(engine::LLVMGetPointerToGlobal(self.into(), global.into()))
7373
}
7474
/// Returns a pointer to the global value with the name given.
7575
///
7676
/// This is marked as unsafe because the type cannot be guranteed to be the same as the
7777
/// type of the global value at this point.
78-
unsafe fn find_global<T>(&'b self, name: &str) -> Option<&'b T> {
78+
unsafe fn find_global<T>(&'a self, name: &str) -> Option<&'a T> {
7979
util::with_cstr(name, |ptr|
8080
mem::transmute(engine::LLVMGetGlobalValueAddress(self.into(), ptr))
8181
)
@@ -91,17 +91,15 @@ pub struct JitOptions {
9191
pub opt_level: usize
9292
}
9393
/// The MCJIT backend, which compiles functions and values into machine code.
94-
pub struct JitEngine<'a> {
95-
engine: LLVMExecutionEngineRef,
96-
marker: PhantomData<&'a ()>
97-
}
98-
native_ref!{contra JitEngine, engine: LLVMExecutionEngineRef}
99-
impl<'a, 'b> JitEngine<'a> {
94+
pub struct JitEngine(PhantomData<[u8]>);
95+
native_ref!{&JitEngine = LLVMExecutionEngineRef}
96+
dispose!{JitEngine, LLVMOpaqueExecutionEngine, LLVMDisposeExecutionEngine}
97+
impl<'a> JitEngine {
10098
/// Run the closure `cb` with the machine code for the function `function`.
10199
///
102100
/// This will check that the types match at runtime when in debug mode, but not release mode.
103101
/// You should make sure to use debug mode if you want it to error when the types don't match.
104-
pub fn with_function<C, A, R>(&self, function: &'b Function, cb: C) where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R) {
102+
pub fn with_function<C, A, R>(&self, function: &'a Function, cb: C) where A:Compile<'a>, R:Compile<'a>, C:FnOnce(extern "C" fn (A) -> R) {
105103
if cfg!(not(ndebug)) {
106104
let ctx = function.get_context();
107105
let sig = function.get_signature();
@@ -118,21 +116,21 @@ impl<'a, 'b> JitEngine<'a> {
118116
}
119117
}
120118
/// Run the closure `cb` with the machine code for the function `function`.
121-
pub unsafe fn with_function_unchecked<C, A, R>(&self, function: &'b Function, cb: C) where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R) {
119+
pub unsafe fn with_function_unchecked<C, A, R>(&self, function: &'a Function, cb: C) where A:Compile<'a>, R:Compile<'a>, C:FnOnce(extern fn(A) -> R) {
122120
cb(self.get_function::<A, R>(function));
123121
}
124122
/// Returns a pointer to the machine code for the function `function`.
125123
///
126124
/// This is marked as unsafe because the types given as arguments and return could be different
127125
/// from their internal representation.
128-
pub unsafe fn get_function<A, R>(&self, function: &'b Function) -> extern fn(A) -> R {
126+
pub unsafe fn get_function<A, R>(&self, function: &'a Function) -> extern fn(A) -> R {
129127
let ptr:&u8 = self.get_global(function);
130128
mem::transmute(ptr)
131129
}
132130
}
133-
impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for JitEngine<'b> {
131+
impl<'a> ExecutionEngine<'a> for JitEngine {
134132
type Options = JitOptions;
135-
fn new(module: &'a Module, options: JitOptions) -> Result<JitEngine<'b>, CBox<str>> {
133+
fn new(module: &'a Module, options: JitOptions) -> Result<CSemiBox<'a, JitEngine>, CBox<str>> {
136134
unsafe {
137135
let mut ee = mem::uninitialized();
138136
let mut out = mem::zeroed();
@@ -161,12 +159,10 @@ impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for JitEngine<'b> {
161159
}
162160
}
163161
/// The interpreter backend
164-
pub struct Interpreter<'a> {
165-
engine: LLVMExecutionEngineRef,
166-
marker: PhantomData<&'a ()>
167-
}
168-
native_ref!{contra Interpreter, engine: LLVMExecutionEngineRef}
169-
impl<'a> Interpreter<'a> {
162+
pub struct Interpreter(PhantomData<[u8]>);
163+
native_ref!{&Interpreter = LLVMExecutionEngineRef}
164+
dispose!{Interpreter, LLVMOpaqueExecutionEngine, LLVMDisposeExecutionEngine}
165+
impl<'a> Interpreter {
170166
/// Run `function` with the arguments given as ``GenericValue`s, then return the result as one.
171167
///
172168
/// To convert the arguments to `GenericValue`s, you should use the `GenericValueCast::to_generic` method.
@@ -176,9 +172,9 @@ impl<'a> Interpreter<'a> {
176172
unsafe { engine::LLVMRunFunction(self.into(), function.into(), args.len() as c_uint, ptr).into() }
177173
}
178174
}
179-
impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for Interpreter<'b> {
175+
impl<'a> ExecutionEngine<'a> for Interpreter {
180176
type Options = ();
181-
fn new(module: &'a Module, _: ()) -> Result<Interpreter<'b>, CBox<str>> {
177+
fn new(module: &'a Module, _: ()) -> Result<CSemiBox<'a, Interpreter>, CBox<str>> {
182178
unsafe {
183179
let mut ee = mem::uninitialized();
184180
let mut out = mem::zeroed();

src/macros.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
#[macro_escape]
2+
macro_rules! build {
3+
($ctx:expr) => ()
4+
}
5+
16
macro_rules! native_ref(
27
(&$name:ident = $alias:ty) => (
38
impl Eq for $name {}

0 commit comments

Comments
 (0)