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 let c_string = to_c_str(fn_name);
336 let address = unsafe { LLVMGetFunctionAddress(self.execution_engine_inner(), c_string.as_ptr()) };
337
338 if address == 0 {
343 return Err(FunctionLookupError::FunctionNotFound);
344 }
345
346 Ok(address as usize)
347 }
348
349 pub fn get_target_data(&self) -> &TargetData {
352 self.target_data
353 .as_ref()
354 .expect("TargetData should always exist until Drop")
355 }
356
357 pub fn get_function_value(&self, fn_name: &str) -> Result<FunctionValue<'ctx>, FunctionLookupError> {
362 if !self.jit_mode {
363 return Err(FunctionLookupError::JITNotEnabled);
364 }
365
366 let c_string = to_c_str(fn_name);
367 let mut function = MaybeUninit::uninit();
368
369 let code = unsafe { LLVMFindFunction(self.execution_engine_inner(), c_string.as_ptr(), function.as_mut_ptr()) };
370
371 if code == 0 {
372 return unsafe { FunctionValue::new(function.assume_init()).ok_or(FunctionLookupError::FunctionNotFound) };
373 };
374
375 Err(FunctionLookupError::FunctionNotFound)
376 }
377
378 pub unsafe fn run_function(
381 &self,
382 function: FunctionValue<'ctx>,
383 args: &[&GenericValue<'ctx>],
384 ) -> GenericValue<'ctx> {
385 let mut args: Vec<LLVMGenericValueRef> = args.iter().map(|val| val.generic_value).collect();
386
387 let value = LLVMRunFunction(
388 self.execution_engine_inner(),
389 function.as_value_ref(),
390 args.len() as u32,
391 args.as_mut_ptr(),
392 ); GenericValue::new(value)
395 }
396
397 pub unsafe fn run_function_as_main(&self, function: FunctionValue<'ctx>, args: &[&str]) -> c_int {
401 let cstring_args: Vec<_> = args.iter().map(|&arg| to_c_str(arg)).collect();
402 let raw_args: Vec<*const _> = cstring_args.iter().map(|arg| arg.as_ptr()).collect();
403
404 let environment_variables = []; LLVMRunFunctionAsMain(
407 self.execution_engine_inner(),
408 function.as_value_ref(),
409 raw_args.len() as u32,
410 raw_args.as_ptr(),
411 environment_variables.as_ptr(),
412 ) }
414
415 pub fn free_fn_machine_code(&self, function: FunctionValue<'ctx>) {
416 unsafe { LLVMFreeMachineCodeForFunction(self.execution_engine_inner(), function.as_value_ref()) }
417 }
418
419 pub fn run_static_constructors(&self) {
421 unsafe { LLVMRunStaticConstructors(self.execution_engine_inner()) }
422 }
423
424 pub fn run_static_destructors(&self) {
426 unsafe { LLVMRunStaticDestructors(self.execution_engine_inner()) }
427 }
428}
429
430impl Drop for ExecutionEngine<'_> {
433 fn drop(&mut self) {
434 forget(
435 self.target_data
436 .take()
437 .expect("TargetData should always exist until Drop"),
438 );
439
440 drop(self.execution_engine.take().expect(EE_INNER_PANIC));
444 }
445}
446
447impl Clone for ExecutionEngine<'_> {
448 fn clone(&self) -> Self {
449 let execution_engine_rc = self.execution_engine_rc().clone();
450
451 unsafe { ExecutionEngine::new(execution_engine_rc, self.jit_mode) }
452 }
453}
454
455#[derive(Debug, Clone, PartialEq, Eq)]
457struct ExecEngineInner<'ctx>(Rc<LLVMExecutionEngineRef>, PhantomData<&'ctx Context>);
458
459impl Drop for ExecEngineInner<'_> {
460 fn drop(&mut self) {
461 if Rc::strong_count(&self.0) == 1 {
462 unsafe {
463 LLVMDisposeExecutionEngine(*self.0);
464 }
465 }
466 }
467}
468
469impl Deref for ExecEngineInner<'_> {
470 type Target = LLVMExecutionEngineRef;
471
472 fn deref(&self) -> &Self::Target {
473 &self.0
474 }
475}
476
477#[derive(Clone)]
480pub struct JitFunction<'ctx, F> {
481 _execution_engine: ExecEngineInner<'ctx>,
482 inner: F,
483}
484
485impl<F: Copy> JitFunction<'_, F> {
486 pub unsafe fn into_raw(self) -> F {
491 self.inner
492 }
493
494 pub unsafe fn as_raw(&self) -> F {
499 self.inner
500 }
501}
502
503impl<F> Debug for JitFunction<'_, F> {
504 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
505 f.debug_tuple("JitFunction").field(&"<unnamed>").finish()
506 }
507}
508
509pub trait UnsafeFunctionPointer: private::SealedUnsafeFunctionPointer {}
511
512mod private {
513 pub trait SealedUnsafeFunctionPointer: Copy {}
518}
519
520impl<F: private::SealedUnsafeFunctionPointer> UnsafeFunctionPointer for F {}
521
522macro_rules! impl_unsafe_fn {
523 (@recurse $first:ident $( , $rest:ident )*) => {
524 impl_unsafe_fn!($( $rest ),*);
525 };
526
527 (@recurse) => {};
528
529 ($( $param:ident ),*) => {
530 impl<Output, $( $param ),*> private::SealedUnsafeFunctionPointer for unsafe extern "C" fn($( $param ),*) -> Output {}
531
532 impl<Output, $( $param ),*> JitFunction<'_, unsafe extern "C" fn($( $param ),*) -> Output> {
533 #[allow(non_snake_case)]
537 #[inline(always)]
538 pub unsafe fn call(&self, $( $param: $param ),*) -> Output {
539 (self.inner)($( $param ),*)
540 }
541 }
542
543 impl_unsafe_fn!(@recurse $( $param ),*);
544 };
545}
546
547impl_unsafe_fn!(A, B, C, D, E, F, G, H, I, J, K, L, M);
548
549#[cfg(feature = "experimental")]
550pub mod experimental {
551 use llvm_sys::error::{LLVMConsumeError, LLVMErrorRef, LLVMErrorTypeId, LLVMGetErrorMessage, LLVMGetErrorTypeId};
552 use llvm_sys::orc::{
553 LLVMOrcAddEagerlyCompiledIR, LLVMOrcAddLazilyCompiledIR, LLVMOrcCreateInstance, LLVMOrcDisposeInstance,
554 LLVMOrcDisposeMangledSymbol, LLVMOrcGetErrorMsg, LLVMOrcGetMangledSymbol, LLVMOrcJITStackRef,
555 };
556
557 use crate::module::Module;
558 use crate::support::to_c_str;
559 use crate::targets::TargetMachine;
560
561 use std::ffi::{CStr, CString};
562 use std::mem::MaybeUninit;
563 use std::ops::Deref;
564
565 #[derive(Debug)]
566 pub struct MangledSymbol(*mut libc::c_char);
567
568 impl Deref for MangledSymbol {
569 type Target = CStr;
570
571 fn deref(&self) -> &CStr {
572 unsafe { CStr::from_ptr(self.0) }
573 }
574 }
575
576 impl Drop for MangledSymbol {
577 fn drop(&mut self) {
578 unsafe { LLVMOrcDisposeMangledSymbol(self.0) }
579 }
580 }
581
582 #[derive(Debug)]
583 pub struct LLVMError(LLVMErrorRef);
584
585 impl LLVMError {
586 pub fn get_type_id(&self) -> LLVMErrorTypeId {
588 unsafe { LLVMGetErrorTypeId(self.0) }
590 }
591 }
592
593 impl Deref for LLVMError {
594 type Target = CStr;
595
596 fn deref(&self) -> &CStr {
597 unsafe {
598 CStr::from_ptr(LLVMGetErrorMessage(self.0)) }
600 }
601 }
602
603 impl Drop for LLVMError {
604 fn drop(&mut self) {
605 unsafe { LLVMConsumeError(self.0) }
606 }
607 }
608
609 #[derive(Debug)]
611 pub struct Orc(LLVMOrcJITStackRef);
612
613 impl Orc {
614 pub fn create(target_machine: TargetMachine) -> Self {
615 let stack_ref = unsafe { LLVMOrcCreateInstance(target_machine.target_machine) };
616
617 Orc(stack_ref)
618 }
619
620 pub fn add_compiled_ir<'ctx>(&self, module: &Module<'ctx>, lazily: bool) -> Result<(), ()> {
621 Ok(())
629 }
630
631 pub fn get_error(&self) -> &CStr {
633 let err_str = unsafe { LLVMOrcGetErrorMsg(self.0) };
634
635 if err_str.is_null() {
636 panic!("Needs to be optional")
637 }
638
639 unsafe { CStr::from_ptr(err_str) }
640 }
641
642 pub fn get_mangled_symbol(&self, symbol: &str) -> MangledSymbol {
643 let mut mangled_symbol = MaybeUninit::uninit();
644 let c_symbol = to_c_str(symbol);
645
646 unsafe { LLVMOrcGetMangledSymbol(self.0, mangled_symbol.as_mut_ptr(), c_symbol.as_ptr()) };
647
648 MangledSymbol(unsafe { mangled_symbol.assume_init() })
649 }
650 }
651
652 impl Drop for Orc {
653 fn drop(&mut self) {
654 LLVMError(unsafe { LLVMOrcDisposeInstance(self.0) });
657 }
658 }
659
660 #[test]
661 fn test_mangled_str() {
662 use crate::targets::{CodeModel, InitializationConfig, RelocMode, Target};
663 use crate::OptimizationLevel;
664
665 Target::initialize_native(&InitializationConfig::default()).unwrap();
666
667 let target_triple = TargetMachine::get_default_triple();
668 let target = Target::from_triple(&target_triple).unwrap();
669 let target_machine = target
670 .create_target_machine(
671 &target_triple,
672 &"",
673 &"",
674 OptimizationLevel::None,
675 RelocMode::Default,
676 CodeModel::Default,
677 )
678 .unwrap();
679 let orc = Orc::create(target_machine);
680
681 assert_eq!(orc.get_error().to_str().unwrap(), "");
682
683 let mangled_symbol = orc.get_mangled_symbol("MyStructName");
684
685 assert_eq!(orc.get_error().to_str().unwrap(), "");
686
687 assert_eq!(mangled_symbol.to_str().unwrap(), "MyStructName");
689 }
690}