Skip to content

Commit 8c928de

Browse files
authored
Merge pull request rust-lang#21 from 6A/master
Adding ExecutionEngine::add_global_mapping
2 parents 5f9b59b + 630647e commit 8c928de

File tree

2 files changed

+54
-36
lines changed

2 files changed

+54
-36
lines changed

examples/kaleidoscope/main.rs

+8-29
Original file line numberDiff line numberDiff line change
@@ -1193,16 +1193,15 @@ macro_rules! print_flush {
11931193
// However, extern functions such as cos(x) and sin(x) can be imported without any problem.
11941194
// Other lines related to this program can be found further down.
11951195

1196-
// pub extern "C" fn putchard(x: f64) -> f64 {
1197-
// print_flush!("{}", x as u8 as char);
1198-
// x
1199-
// }
1196+
pub extern fn putchard(x: f64) -> f64 {
1197+
print_flush!("{}", x as u8 as char);
1198+
x
1199+
}
12001200

1201-
// pub extern "C" fn printd(x: f64) -> f64 {
1202-
// println!("Fn called");
1203-
// println!("{}", x);
1204-
// x
1205-
// }
1201+
pub extern fn printd(x: f64) -> f64 {
1202+
println!("{}", x);
1203+
x
1204+
}
12061205

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

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

1225-
// add_symbol("printd", &printd, printd as *const ());
1226-
// add_symbol("putchard", &putchard, putchard as *const ());
1227-
12281224
let context = Context::create();
12291225
let module = context.create_module("repl");
12301226
let builder = context.create_builder();
@@ -1277,26 +1273,9 @@ pub fn main() {
12771273
// make module
12781274
let module = context.create_module("tmp");
12791275

1280-
//let mut printd_fn = None;
1281-
//let mut putchard_fn = None;
1282-
12831276
// recompile every previously parsed function into the new module
12841277
for prev in previous_exprs.iter() {
12851278
Compiler::compile(&context, &builder, &fpm, &module, prev).expect("Cannot re-add previously compiled function.");
1286-
1287-
// Not working; see comment above.
1288-
//
1289-
// match fun.get_name().to_str().unwrap() {
1290-
// "printd" => {
1291-
// printd_fn = Some(fun);
1292-
// },
1293-
1294-
// "putchard" => {
1295-
// putchard_fn = Some(fun);
1296-
// },
1297-
1298-
// _ => ()
1299-
// }
13001279
}
13011280

13021281
let (name, is_anonymous) = match Parser::new(input, &mut prec).parse() {

src/execution_engine.rs

+46-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use llvm_sys::core::LLVMDisposeMessage;
2-
use llvm_sys::execution_engine::{LLVMGetExecutionEngineTargetData, LLVMExecutionEngineRef, LLVMRunFunction, LLVMRunFunctionAsMain, LLVMDisposeExecutionEngine, LLVMGetFunctionAddress, LLVMAddModule, LLVMFindFunction, LLVMLinkInMCJIT, LLVMLinkInInterpreter, LLVMRemoveModule, LLVMGenericValueRef, LLVMFreeMachineCodeForFunction, LLVMGetPointerToGlobal};
2+
use llvm_sys::execution_engine::{LLVMGetExecutionEngineTargetData, LLVMExecutionEngineRef, LLVMRunFunction, LLVMRunFunctionAsMain, LLVMDisposeExecutionEngine, LLVMGetFunctionAddress, LLVMAddModule, LLVMFindFunction, LLVMLinkInMCJIT, LLVMLinkInInterpreter, LLVMRemoveModule, LLVMGenericValueRef, LLVMFreeMachineCodeForFunction, LLVMGetPointerToGlobal, LLVMAddGlobalMapping};
33

44
use module::Module;
55
use targets::TargetData;
6-
use values::{AsValueRef, FunctionValue, GenericValue, GlobalValue};
6+
use values::{AnyValue, AsValueRef, FunctionValue, GenericValue, GlobalValue};
77

88
use std::ffi::{CStr, CString};
99
use std::mem::{forget, uninitialized, zeroed};
@@ -51,11 +51,50 @@ impl ExecutionEngine {
5151
}
5252
}
5353

54-
// pub fn add_global_mapping(&mut self, global: &AnyValue, addr: *const ()) {
55-
// unsafe {
56-
// LLVMAddGlobalMapping(self.execution_engine, global.as_value_ref(), addr as *mut ::libc::c_void)
57-
// }
58-
// }
54+
/// Maps the specified value to an address.
55+
///
56+
/// # Example
57+
/// ```no_run
58+
/// use inkwell::targets::{InitializationConfig, Target};
59+
/// use inkwell::context::Context;
60+
/// use inkwell::OptimizationLevel;
61+
///
62+
/// Target::initialize_native(&InitializationConfig::default()).unwrap();
63+
///
64+
/// extern fn sumf(a: f64, b: f64) -> f64 {
65+
/// a + b
66+
/// }
67+
///
68+
/// let context = Context::create();
69+
/// let module = context.create_module("test");
70+
/// let builder = context.create_builder();
71+
///
72+
/// let ft = context.f64_type();
73+
/// let fnt = ft.fn_type(&[], false);
74+
///
75+
/// let f = module.add_function("test_fn", &fnt, None);
76+
/// let b = context.append_basic_block(&f, "entry");
77+
/// builder.position_at_end(&b);
78+
///
79+
/// let extf = module.add_function("sumf", &ft.fn_type(&[ &ft, &ft ], false), None);
80+
///
81+
/// let argf = ft.const_float(64.);
82+
/// let retv = builder.build_call(&extf, &[ &argf, &argf ], "retv", false).left().unwrap().into_float_value();
83+
///
84+
/// builder.build_return(Some(&retv));
85+
///
86+
/// let mut ee = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
87+
/// ee.add_global_mapping(&extf, sumf as usize);
88+
///
89+
/// let result = unsafe { ee.run_function(&f, &[]) }.as_float(&ft);
90+
///
91+
/// assert_eq!(result, 128.);
92+
/// ```
93+
pub fn add_global_mapping(&mut self, value: &AnyValue, addr: usize) {
94+
unsafe {
95+
LLVMAddGlobalMapping(self.execution_engine, value.as_value_ref(), addr as *mut _)
96+
}
97+
}
5998

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

0 commit comments

Comments
 (0)