Skip to content

Commit

Permalink
Merge pull request rust-lang#21 from 6A/master
Browse files Browse the repository at this point in the history
Adding ExecutionEngine::add_global_mapping
  • Loading branch information
TheDan64 authored Oct 12, 2017
2 parents 5f9b59b + 630647e commit 8c928de
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 36 deletions.
37 changes: 8 additions & 29 deletions examples/kaleidoscope/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1193,16 +1193,15 @@ macro_rules! print_flush {
// However, extern functions such as cos(x) and sin(x) can be imported without any problem.
// Other lines related to this program can be found further down.

// pub extern "C" fn putchard(x: f64) -> f64 {
// print_flush!("{}", x as u8 as char);
// x
// }
pub extern fn putchard(x: f64) -> f64 {
print_flush!("{}", x as u8 as char);
x
}

// pub extern "C" fn printd(x: f64) -> f64 {
// println!("Fn called");
// println!("{}", x);
// x
// }
pub extern fn printd(x: f64) -> f64 {
println!("{}", x);
x
}

/// Entry point of the program; acts as a REPL.
pub fn main() {
Expand All @@ -1222,9 +1221,6 @@ pub fn main() {

Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target.");

// add_symbol("printd", &printd, printd as *const ());
// add_symbol("putchard", &putchard, putchard as *const ());

let context = Context::create();
let module = context.create_module("repl");
let builder = context.create_builder();
Expand Down Expand Up @@ -1277,26 +1273,9 @@ pub fn main() {
// make module
let module = context.create_module("tmp");

//let mut printd_fn = None;
//let mut putchard_fn = None;

// recompile every previously parsed function into the new module
for prev in previous_exprs.iter() {
Compiler::compile(&context, &builder, &fpm, &module, prev).expect("Cannot re-add previously compiled function.");

// Not working; see comment above.
//
// match fun.get_name().to_str().unwrap() {
// "printd" => {
// printd_fn = Some(fun);
// },

// "putchard" => {
// putchard_fn = Some(fun);
// },

// _ => ()
// }
}

let (name, is_anonymous) = match Parser::new(input, &mut prec).parse() {
Expand Down
53 changes: 46 additions & 7 deletions src/execution_engine.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use llvm_sys::core::LLVMDisposeMessage;
use llvm_sys::execution_engine::{LLVMGetExecutionEngineTargetData, LLVMExecutionEngineRef, LLVMRunFunction, LLVMRunFunctionAsMain, LLVMDisposeExecutionEngine, LLVMGetFunctionAddress, LLVMAddModule, LLVMFindFunction, LLVMLinkInMCJIT, LLVMLinkInInterpreter, LLVMRemoveModule, LLVMGenericValueRef, LLVMFreeMachineCodeForFunction, LLVMGetPointerToGlobal};
use llvm_sys::execution_engine::{LLVMGetExecutionEngineTargetData, LLVMExecutionEngineRef, LLVMRunFunction, LLVMRunFunctionAsMain, LLVMDisposeExecutionEngine, LLVMGetFunctionAddress, LLVMAddModule, LLVMFindFunction, LLVMLinkInMCJIT, LLVMLinkInInterpreter, LLVMRemoveModule, LLVMGenericValueRef, LLVMFreeMachineCodeForFunction, LLVMGetPointerToGlobal, LLVMAddGlobalMapping};

use module::Module;
use targets::TargetData;
use values::{AsValueRef, FunctionValue, GenericValue, GlobalValue};
use values::{AnyValue, AsValueRef, FunctionValue, GenericValue, GlobalValue};

use std::ffi::{CStr, CString};
use std::mem::{forget, uninitialized, zeroed};
Expand Down Expand Up @@ -51,11 +51,50 @@ impl ExecutionEngine {
}
}

// pub fn add_global_mapping(&mut self, global: &AnyValue, addr: *const ()) {
// unsafe {
// LLVMAddGlobalMapping(self.execution_engine, global.as_value_ref(), addr as *mut ::libc::c_void)
// }
// }
/// Maps the specified value to an address.
///
/// # Example
/// ```no_run
/// use inkwell::targets::{InitializationConfig, Target};
/// use inkwell::context::Context;
/// use inkwell::OptimizationLevel;
///
/// Target::initialize_native(&InitializationConfig::default()).unwrap();
///
/// extern fn sumf(a: f64, b: f64) -> f64 {
/// a + b
/// }
///
/// let context = Context::create();
/// let module = context.create_module("test");
/// let builder = context.create_builder();
///
/// let ft = context.f64_type();
/// let fnt = ft.fn_type(&[], false);
///
/// let f = module.add_function("test_fn", &fnt, None);
/// let b = context.append_basic_block(&f, "entry");
/// builder.position_at_end(&b);
///
/// let extf = module.add_function("sumf", &ft.fn_type(&[ &ft, &ft ], false), None);
///
/// let argf = ft.const_float(64.);
/// let retv = builder.build_call(&extf, &[ &argf, &argf ], "retv", false).left().unwrap().into_float_value();
///
/// builder.build_return(Some(&retv));
///
/// let mut ee = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
/// ee.add_global_mapping(&extf, sumf as usize);
///
/// let result = unsafe { ee.run_function(&f, &[]) }.as_float(&ft);
///
/// assert_eq!(result, 128.);
/// ```
pub fn add_global_mapping(&mut self, value: &AnyValue, addr: usize) {
unsafe {
LLVMAddGlobalMapping(self.execution_engine, value.as_value_ref(), addr as *mut _)
}
}

// TODOC: EE must *own* modules and deal out references
pub fn add_module(&mut self, module: Module) -> &Module {
Expand Down

0 comments on commit 8c928de

Please # to comment.