1use libc::c_int;
2use llvm_sys::execution_engine::{
3 LLVMAddGlobalMapping, LLVMAddModule, LLVMDisposeExecutionEngine, LLVMExecutionEngineRef, LLVMFindFunction,
4 LLVMFreeMachineCodeForFunction, LLVMGenericValueRef, LLVMGetExecutionEngineTargetData, LLVMGetFunctionAddress,
5 LLVMLinkInInterpreter, LLVMLinkInMCJIT, LLVMRemoveModule, LLVMRunFunction, LLVMRunFunctionAsMain,
6 LLVMRunStaticConstructors, LLVMRunStaticDestructors,
7};
8
9use crate::context::Context;
10use crate::module::Module;
11use crate::support::{to_c_str, LLVMString};
12use crate::targets::TargetData;
13use crate::values::{AnyValue, AsValueRef, FunctionValue, GenericValue};
14
15use std::error::Error;
16use std::fmt::{self, Debug, Display, Formatter};
17use std::marker::PhantomData;
18use std::mem::{forget, size_of, transmute_copy, MaybeUninit};
19use std::ops::Deref;
20use std::rc::Rc;
21
22static EE_INNER_PANIC: &str = "ExecutionEngineInner should exist until Drop";
23
24#[derive(Debug, PartialEq, Eq)]
25pub enum FunctionLookupError {
26 JITNotEnabled,
27 FunctionNotFound, }
29
30impl Error for FunctionLookupError {}
31
32impl FunctionLookupError {
33 fn as_str(&self) -> &str {
34 match self {
35 FunctionLookupError::JITNotEnabled => "ExecutionEngine does not have JIT functionality enabled",
36 FunctionLookupError::FunctionNotFound => "Function not found in ExecutionEngine",
37 }
38 }
39}
40
41impl Display for FunctionLookupError {
42 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
43 write!(f, "FunctionLookupError({})", self.as_str())
44 }
45}
46
47#[derive(Debug, PartialEq, Eq)]
48pub enum RemoveModuleError {
49 ModuleNotOwned,
50 IncorrectModuleOwner,
51 LLVMError(LLVMString),
52}
53
54impl Error for RemoveModuleError {
55 fn description(&self) -> &str {
58 self.as_str()
59 }
60
61 fn cause(&self) -> Option<&dyn Error> {
62 None
63 }
64}
65
66impl RemoveModuleError {
67 fn as_str(&self) -> &str {
68 match self {
69 RemoveModuleError::ModuleNotOwned => "Module is not owned by an Execution Engine",
70 RemoveModuleError::IncorrectModuleOwner => "Module is not owned by this Execution Engine",
71 RemoveModuleError::LLVMError(string) => string.to_str().unwrap_or("LLVMError with invalid unicode"),
72 }
73 }
74}
75
76impl Display for RemoveModuleError {
77 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
78 write!(f, "RemoveModuleError({})", self.as_str())
79 }
80}
81
82#[derive(PartialEq, Eq, Debug)]
91pub struct ExecutionEngine<'ctx> {
92 execution_engine: Option<ExecEngineInner<'ctx>>,
93 target_data: Option<TargetData>,
94 jit_mode: bool,
95}
96
97impl<'ctx> ExecutionEngine<'ctx> {
98 pub unsafe fn new(execution_engine: Rc<LLVMExecutionEngineRef>, jit_mode: bool) -> Self {
99 assert!(!execution_engine.is_null());
100
101 let target_data = LLVMGetExecutionEngineTargetData(*execution_engine);
103
104 ExecutionEngine {
105 execution_engine: Some(ExecEngineInner(execution_engine, PhantomData)),
106 target_data: Some(TargetData::new(target_data)),
107 jit_mode,
108 }
109 }
110
111 pub fn as_mut_ptr(&self) -> LLVMExecutionEngineRef {
113 self.execution_engine_inner()
114 }
115
116 pub(crate) fn execution_engine_rc(&self) -> &Rc<LLVMExecutionEngineRef> {
117 &self.execution_engine.as_ref().expect(EE_INNER_PANIC).0
118 }
119
120 #[inline]
121 pub(crate) fn execution_engine_inner(&self) -> LLVMExecutionEngineRef {
122 **self.execution_engine_rc()
123 }
124
125 pub fn link_in_mc_jit() {
128 unsafe { LLVMLinkInMCJIT() }
129 }
130
131 pub fn link_in_interpreter() {
134 unsafe {
135 LLVMLinkInInterpreter();
136 }
137 }
138
139 pub fn add_global_mapping(&self, value: &dyn AnyValue<'ctx>, addr: usize) {
181 unsafe { LLVMAddGlobalMapping(self.execution_engine_inner(), value.as_value_ref(), addr as *mut _) }
182 }
183
184 pub fn add_module(&self, module: &Module<'ctx>) -> Result<(), ()> {
202 unsafe { LLVMAddModule(self.execution_engine_inner(), module.module.get()) }
203
204 if module.owned_by_ee.borrow().is_some() {
205 return Err(());
206 }
207
208 *module.owned_by_ee.borrow_mut() = Some(self.clone());
209
210 Ok(())
211 }
212
213 pub fn remove_module(&self, module: &Module<'ctx>) -> Result<(), RemoveModuleError> {
214 match *module.owned_by_ee.borrow() {
215 Some(ref ee) if ee.execution_engine_inner() != self.execution_engine_inner() => {
216 return Err(RemoveModuleError::IncorrectModuleOwner)
217 },
218 None => return Err(RemoveModuleError::ModuleNotOwned),
219 _ => (),
220 }
221
222 let mut new_module = MaybeUninit::uninit();
223 let mut err_string = MaybeUninit::uninit();
224
225 let code = unsafe {
226 LLVMRemoveModule(
227 self.execution_engine_inner(),
228 module.module.get(),
229 new_module.as_mut_ptr(),
230 err_string.as_mut_ptr(),
231 )
232 };
233
234 if code == 1 {
235 unsafe {
236 return Err(RemoveModuleError::LLVMError(LLVMString::new(err_string.assume_init())));
237 }
238 }
239
240 let new_module = unsafe { new_module.assume_init() };
241
242 module.module.set(new_module);
243 *module.owned_by_ee.borrow_mut() = None;
244
245 Ok(())
246 }
247
248 pub unsafe fn get_function<F>(&self, fn_name: &str) -> Result<JitFunction<'ctx, F>, FunctionLookupError>
306 where
307 F: UnsafeFunctionPointer,
308 {
309 if !self.jit_mode {
310 return Err(FunctionLookupError::JITNotEnabled);
311 }
312
313 let address = self.get_function_address(fn_name)?;
314
315 assert_eq!(
316 size_of::<F>(),
317 size_of::<usize>(),
318 "The type `F` must have the same size as a function pointer"
319 );
320
321 let execution_engine = self.execution_engine.as_ref().expect(EE_INNER_PANIC);
322
323 Ok(JitFunction {
324 _execution_engine: execution_engine.clone(),
325 inner: transmute_copy(&address),
326 })
327 }
328
329 pub fn get_function_address(&self, fn_name: &str) -> Result<usize, FunctionLookupError> {
335 #[cfg(any(feature = "llvm5-0", feature = "llvm6-0", feature = "llvm7-0", feature = "llvm8-0"))]
338 self.get_function_value(fn_name)?;
339
340 let c_string = to_c_str(fn_name);
341 let address = unsafe { LLVMGetFunctionAddress(self.execution_engine_inner(), c_string.as_ptr()) };
342
343 if address == 0 {
348 return Err(FunctionLookupError::FunctionNotFound);
349 }
350
351 Ok(address as usize)
352 }
353
354 pub fn get_target_data(&self) -> &TargetData {
357 self.target_data
358 .as_ref()
359 .expect("TargetData should always exist until Drop")
360 }
361
362 pub fn get_function_value(&self, fn_name: &str) -> Result<FunctionValue<'ctx>, FunctionLookupError> {
367 if !self.jit_mode {
368 return Err(FunctionLookupError::JITNotEnabled);
369 }
370
371 let c_string = to_c_str(fn_name);
372 let mut function = MaybeUninit::uninit();
373
374 let code = unsafe { LLVMFindFunction(self.execution_engine_inner(), c_string.as_ptr(), function.as_mut_ptr()) };
375
376 if code == 0 {
377 return unsafe { FunctionValue::new(function.assume_init()).ok_or(FunctionLookupError::FunctionNotFound) };
378 };
379
380 Err(FunctionLookupError::FunctionNotFound)
381 }
382
383 pub unsafe fn run_function(
386 &self,
387 function: FunctionValue<'ctx>,
388 args: &[&GenericValue<'ctx>],
389 ) -> GenericValue<'ctx> {
390 let mut args: Vec<LLVMGenericValueRef> = args.iter().map(|val| val.generic_value).collect();
391
392 let value = LLVMRunFunction(
393 self.execution_engine_inner(),
394 function.as_value_ref(),
395 args.len() as u32,
396 args.as_mut_ptr(),
397 ); GenericValue::new(value)
400 }
401
402 pub unsafe fn run_function_as_main(&self, function: FunctionValue<'ctx>, args: &[&str]) -> c_int {
406 let cstring_args: Vec<_> = args.iter().map(|&arg| to_c_str(arg)).collect();
407 let raw_args: Vec<*const _> = cstring_args.iter().map(|arg| arg.as_ptr()).collect();
408
409 let environment_variables = []; LLVMRunFunctionAsMain(
412 self.execution_engine_inner(),
413 function.as_value_ref(),
414 raw_args.len() as u32,
415 raw_args.as_ptr(),
416 environment_variables.as_ptr(),
417 ) }
419
420 pub fn free_fn_machine_code(&self, function: FunctionValue<'ctx>) {
421 unsafe { LLVMFreeMachineCodeForFunction(self.execution_engine_inner(), function.as_value_ref()) }
422 }
423
424 pub fn run_static_constructors(&self) {
426 unsafe { LLVMRunStaticConstructors(self.execution_engine_inner()) }
427 }
428
429 pub fn run_static_destructors(&self) {
431 unsafe { LLVMRunStaticDestructors(self.execution_engine_inner()) }
432 }
433}
434
435impl Drop for ExecutionEngine<'_> {
438 fn drop(&mut self) {
439 forget(
440 self.target_data
441 .take()
442 .expect("TargetData should always exist until Drop"),
443 );
444
445 drop(self.execution_engine.take().expect(EE_INNER_PANIC));
449 }
450}
451
452impl Clone for ExecutionEngine<'_> {
453 fn clone(&self) -> Self {
454 let execution_engine_rc = self.execution_engine_rc().clone();
455
456 unsafe { ExecutionEngine::new(execution_engine_rc, self.jit_mode) }
457 }
458}
459
460#[derive(Debug, Clone, PartialEq, Eq)]
462struct ExecEngineInner<'ctx>(Rc<LLVMExecutionEngineRef>, PhantomData<&'ctx Context>);
463
464impl Drop for ExecEngineInner<'_> {
465 fn drop(&mut self) {
466 if Rc::strong_count(&self.0) == 1 {
467 unsafe {
468 LLVMDisposeExecutionEngine(*self.0);
469 }
470 }
471 }
472}
473
474impl Deref for ExecEngineInner<'_> {
475 type Target = LLVMExecutionEngineRef;
476
477 fn deref(&self) -> &Self::Target {
478 &self.0
479 }
480}
481
482#[derive(Clone)]
485pub struct JitFunction<'ctx, F> {
486 _execution_engine: ExecEngineInner<'ctx>,
487 inner: F,
488}
489
490impl<'ctx, F: Copy> JitFunction<'ctx, F> {
491 pub unsafe fn into_raw(self) -> F {
496 self.inner
497 }
498
499 pub unsafe fn as_raw(&self) -> F {
504 self.inner
505 }
506}
507
508impl<F> Debug for JitFunction<'_, F> {
509 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
510 f.debug_tuple("JitFunction").field(&"<unnamed>").finish()
511 }
512}
513
514pub trait UnsafeFunctionPointer: private::SealedUnsafeFunctionPointer {}
516
517mod private {
518 pub trait SealedUnsafeFunctionPointer: Copy {}
523}
524
525impl<F: private::SealedUnsafeFunctionPointer> UnsafeFunctionPointer for F {}
526
527macro_rules! impl_unsafe_fn {
528 (@recurse $first:ident $( , $rest:ident )*) => {
529 impl_unsafe_fn!($( $rest ),*);
530 };
531
532 (@recurse) => {};
533
534 ($( $param:ident ),*) => {
535 impl<Output, $( $param ),*> private::SealedUnsafeFunctionPointer for unsafe extern "C" fn($( $param ),*) -> Output {}
536
537 impl<Output, $( $param ),*> JitFunction<'_, unsafe extern "C" fn($( $param ),*) -> Output> {
538 #[allow(non_snake_case)]
542 #[inline(always)]
543 pub unsafe fn call(&self, $( $param: $param ),*) -> Output {
544 (self.inner)($( $param ),*)
545 }
546 }
547
548 impl_unsafe_fn!(@recurse $( $param ),*);
549 };
550}
551
552impl_unsafe_fn!(A, B, C, D, E, F, G, H, I, J, K, L, M);
553
554#[cfg(feature = "experimental")]
555pub mod experimental {
556 use llvm_sys::error::{LLVMConsumeError, LLVMErrorRef, LLVMErrorTypeId, LLVMGetErrorMessage, LLVMGetErrorTypeId};
557 use llvm_sys::orc::{
558 LLVMOrcAddEagerlyCompiledIR, LLVMOrcAddLazilyCompiledIR, LLVMOrcCreateInstance, LLVMOrcDisposeInstance,
559 LLVMOrcDisposeMangledSymbol, LLVMOrcGetErrorMsg, LLVMOrcGetMangledSymbol, LLVMOrcJITStackRef,
560 };
561
562 use crate::module::Module;
563 use crate::support::to_c_str;
564 use crate::targets::TargetMachine;
565
566 use std::ffi::{CStr, CString};
567 use std::mem::MaybeUninit;
568 use std::ops::Deref;
569
570 #[derive(Debug)]
571 pub struct MangledSymbol(*mut libc::c_char);
572
573 impl Deref for MangledSymbol {
574 type Target = CStr;
575
576 fn deref(&self) -> &CStr {
577 unsafe { CStr::from_ptr(self.0) }
578 }
579 }
580
581 impl Drop for MangledSymbol {
582 fn drop(&mut self) {
583 unsafe { LLVMOrcDisposeMangledSymbol(self.0) }
584 }
585 }
586
587 #[derive(Debug)]
588 pub struct LLVMError(LLVMErrorRef);
589
590 impl LLVMError {
591 pub fn get_type_id(&self) -> LLVMErrorTypeId {
593 unsafe { LLVMGetErrorTypeId(self.0) }
595 }
596 }
597
598 impl Deref for LLVMError {
599 type Target = CStr;
600
601 fn deref(&self) -> &CStr {
602 unsafe {
603 CStr::from_ptr(LLVMGetErrorMessage(self.0)) }
605 }
606 }
607
608 impl Drop for LLVMError {
609 fn drop(&mut self) {
610 unsafe { LLVMConsumeError(self.0) }
611 }
612 }
613
614 #[derive(Debug)]
616 pub struct Orc(LLVMOrcJITStackRef);
617
618 impl Orc {
619 pub fn create(target_machine: TargetMachine) -> Self {
620 let stack_ref = unsafe { LLVMOrcCreateInstance(target_machine.target_machine) };
621
622 Orc(stack_ref)
623 }
624
625 pub fn add_compiled_ir<'ctx>(&self, module: &Module<'ctx>, lazily: bool) -> Result<(), ()> {
626 Ok(())
634 }
635
636 pub fn get_error(&self) -> &CStr {
638 let err_str = unsafe { LLVMOrcGetErrorMsg(self.0) };
639
640 if err_str.is_null() {
641 panic!("Needs to be optional")
642 }
643
644 unsafe { CStr::from_ptr(err_str) }
645 }
646
647 pub fn get_mangled_symbol(&self, symbol: &str) -> MangledSymbol {
648 let mut mangled_symbol = MaybeUninit::uninit();
649 let c_symbol = to_c_str(symbol);
650
651 unsafe { LLVMOrcGetMangledSymbol(self.0, mangled_symbol.as_mut_ptr(), c_symbol.as_ptr()) };
652
653 MangledSymbol(unsafe { mangled_symbol.assume_init() })
654 }
655 }
656
657 impl Drop for Orc {
658 fn drop(&mut self) {
659 LLVMError(unsafe { LLVMOrcDisposeInstance(self.0) });
662 }
663 }
664
665 #[test]
666 fn test_mangled_str() {
667 use crate::targets::{CodeModel, InitializationConfig, RelocMode, Target};
668 use crate::OptimizationLevel;
669
670 Target::initialize_native(&InitializationConfig::default()).unwrap();
671
672 let target_triple = TargetMachine::get_default_triple();
673 let target = Target::from_triple(&target_triple).unwrap();
674 let target_machine = target
675 .create_target_machine(
676 &target_triple,
677 &"",
678 &"",
679 OptimizationLevel::None,
680 RelocMode::Default,
681 CodeModel::Default,
682 )
683 .unwrap();
684 let orc = Orc::create(target_machine);
685
686 assert_eq!(orc.get_error().to_str().unwrap(), "");
687
688 let mangled_symbol = orc.get_mangled_symbol("MyStructName");
689
690 assert_eq!(orc.get_error().to_str().unwrap(), "");
691
692 assert_eq!(mangled_symbol.to_str().unwrap(), "MyStructName");
694 }
695}