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::{LLVMString, to_c_str};
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::{MaybeUninit, forget, size_of, transmute_copy};
19use std::ops::Deref;
20use std::ptr::NonNull;
21use std::rc::Rc;
22
23static EE_INNER_PANIC: &str = "ExecutionEngineInner should exist until Drop";
24
25#[derive(Debug, PartialEq, Eq)]
26pub enum FunctionLookupError {
27 JITNotEnabled,
28 FunctionNotFound, }
30
31impl Error for FunctionLookupError {}
32
33impl FunctionLookupError {
34 fn as_str(&self) -> &str {
35 match self {
36 FunctionLookupError::JITNotEnabled => "ExecutionEngine does not have JIT functionality enabled",
37 FunctionLookupError::FunctionNotFound => "Function not found in ExecutionEngine",
38 }
39 }
40}
41
42impl Display for FunctionLookupError {
43 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
44 write!(f, "FunctionLookupError({})", self.as_str())
45 }
46}
47
48#[derive(Debug, PartialEq, Eq)]
49pub enum RemoveModuleError {
50 ModuleNotOwned,
51 IncorrectModuleOwner,
52 LLVMError(LLVMString),
53}
54
55impl Error for RemoveModuleError {
56 fn description(&self) -> &str {
59 self.as_str()
60 }
61
62 fn cause(&self) -> Option<&dyn Error> {
63 None
64 }
65}
66
67impl RemoveModuleError {
68 fn as_str(&self) -> &str {
69 match self {
70 RemoveModuleError::ModuleNotOwned => "Module is not owned by an Execution Engine",
71 RemoveModuleError::IncorrectModuleOwner => "Module is not owned by this Execution Engine",
72 RemoveModuleError::LLVMError(string) => string.to_str().unwrap_or("LLVMError with invalid unicode"),
73 }
74 }
75}
76
77impl Display for RemoveModuleError {
78 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
79 write!(f, "RemoveModuleError({})", self.as_str())
80 }
81}
82
83#[derive(PartialEq, Eq, Debug)]
92pub struct ExecutionEngine<'ctx> {
93 execution_engine: Option<ExecEngineInner<'ctx>>,
94 target_data: Option<TargetData>,
95 jit_mode: bool,
96}
97
98impl<'ctx> ExecutionEngine<'ctx> {
99 pub unsafe fn new(execution_engine: Rc<LLVMExecutionEngineRef>, jit_mode: bool) -> Self {
100 unsafe {
101 assert!(!execution_engine.is_null());
102
103 let target_data = LLVMGetExecutionEngineTargetData(*execution_engine);
105
106 ExecutionEngine {
107 execution_engine: Some(ExecEngineInner(execution_engine, PhantomData)),
108 target_data: Some(TargetData::new(target_data)),
109 jit_mode,
110 }
111 }
112 }
113
114 pub fn as_mut_ptr(&self) -> LLVMExecutionEngineRef {
116 self.execution_engine_inner()
117 }
118
119 pub(crate) fn execution_engine_rc(&self) -> &Rc<LLVMExecutionEngineRef> {
120 &self.execution_engine.as_ref().expect(EE_INNER_PANIC).0
121 }
122
123 #[inline]
124 pub(crate) fn execution_engine_inner(&self) -> LLVMExecutionEngineRef {
125 **self.execution_engine_rc()
126 }
127
128 pub(crate) fn link_in_mc_jit() {
131 unsafe { LLVMLinkInMCJIT() }
132 }
133
134 pub(crate) fn link_in_interpreter() {
137 unsafe {
138 LLVMLinkInInterpreter();
139 }
140 }
141
142 pub fn add_global_mapping(&self, value: &dyn AnyValue<'ctx>, addr: usize) {
184 unsafe { LLVMAddGlobalMapping(self.execution_engine_inner(), value.as_value_ref(), addr as *mut _) }
185 }
186
187 pub fn add_module(&self, module: &Module<'ctx>) -> Result<(), ()> {
205 unsafe { LLVMAddModule(self.execution_engine_inner(), module.as_mut_ptr()) }
206
207 if module.owned_by_ee.borrow().is_some() {
208 return Err(());
209 }
210
211 *module.owned_by_ee.borrow_mut() = Some(self.clone());
212
213 Ok(())
214 }
215
216 pub fn remove_module(&self, module: &Module<'ctx>) -> Result<(), RemoveModuleError> {
217 match *module.owned_by_ee.borrow() {
218 Some(ref ee) if ee.execution_engine_inner() != self.execution_engine_inner() => {
219 return Err(RemoveModuleError::IncorrectModuleOwner);
220 },
221 None => return Err(RemoveModuleError::ModuleNotOwned),
222 _ => (),
223 }
224
225 let mut new_module = MaybeUninit::uninit();
226 let mut err_string: *mut ::libc::c_char = ::core::ptr::null_mut();
227
228 let code = unsafe {
229 LLVMRemoveModule(
230 self.execution_engine_inner(),
231 module.as_mut_ptr(),
232 new_module.as_mut_ptr(),
233 &mut err_string,
234 )
235 };
236
237 if code == 1 {
238 unsafe {
239 return Err(RemoveModuleError::LLVMError(LLVMString::new(err_string)));
240 }
241 }
242
243 let new_module = unsafe { new_module.assume_init() };
244
245 module.module.set(unsafe { NonNull::new_unchecked(new_module) });
246 *module.owned_by_ee.borrow_mut() = None;
247
248 Ok(())
249 }
250
251 pub unsafe fn get_function<F>(&self, fn_name: &str) -> Result<JitFunction<'ctx, F>, FunctionLookupError>
309 where
310 F: UnsafeFunctionPointer,
311 {
312 unsafe {
313 if !self.jit_mode {
314 return Err(FunctionLookupError::JITNotEnabled);
315 }
316
317 let address = self.get_function_address(fn_name)?;
318
319 assert_eq!(
320 size_of::<F>(),
321 size_of::<usize>(),
322 "The type `F` must have the same size as a function pointer"
323 );
324
325 let execution_engine = self.execution_engine.as_ref().expect(EE_INNER_PANIC);
326
327 Ok(JitFunction {
328 _execution_engine: execution_engine.clone(),
329 inner: transmute_copy(&address),
330 })
331 }
332 }
333
334 pub fn get_function_address(&self, fn_name: &str) -> Result<usize, FunctionLookupError> {
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 unsafe {
391 let mut args: Vec<LLVMGenericValueRef> = args.iter().map(|val| val.generic_value.as_ptr()).collect();
392
393 let value = LLVMRunFunction(
394 self.execution_engine_inner(),
395 function.as_value_ref(),
396 args.len() as u32,
397 args.as_mut_ptr(),
398 ); GenericValue::new(value)
401 }
402 }
403
404 pub unsafe fn run_function_as_main(&self, function: FunctionValue<'ctx>, args: &[&str]) -> c_int {
408 unsafe {
409 let cstring_args: Vec<_> = args.iter().map(|&arg| to_c_str(arg)).collect();
410 let raw_args: Vec<*const _> = cstring_args.iter().map(|arg| arg.as_ptr()).collect();
411
412 let environment_variables = []; LLVMRunFunctionAsMain(
415 self.execution_engine_inner(),
416 function.as_value_ref(),
417 raw_args.len() as u32,
418 raw_args.as_ptr(),
419 environment_variables.as_ptr(),
420 ) }
422 }
423
424 pub fn free_fn_machine_code(&self, function: FunctionValue<'ctx>) {
425 unsafe { LLVMFreeMachineCodeForFunction(self.execution_engine_inner(), function.as_value_ref()) }
426 }
427
428 pub fn run_static_constructors(&self) {
430 unsafe { LLVMRunStaticConstructors(self.execution_engine_inner()) }
431 }
432
433 pub fn run_static_destructors(&self) {
435 unsafe { LLVMRunStaticDestructors(self.execution_engine_inner()) }
436 }
437}
438
439impl Drop for ExecutionEngine<'_> {
442 fn drop(&mut self) {
443 forget(
444 self.target_data
445 .take()
446 .expect("TargetData should always exist until Drop"),
447 );
448
449 drop(self.execution_engine.take().expect(EE_INNER_PANIC));
453 }
454}
455
456impl Clone for ExecutionEngine<'_> {
457 fn clone(&self) -> Self {
458 let execution_engine_rc = self.execution_engine_rc().clone();
459
460 unsafe { ExecutionEngine::new(execution_engine_rc, self.jit_mode) }
461 }
462}
463
464#[repr(transparent)]
466#[derive(Debug, Clone, PartialEq, Eq)]
467struct ExecEngineInner<'ctx>(Rc<LLVMExecutionEngineRef>, PhantomData<&'ctx Context>);
468
469impl Drop for ExecEngineInner<'_> {
470 fn drop(&mut self) {
471 if Rc::strong_count(&self.0) == 1 {
472 unsafe {
473 LLVMDisposeExecutionEngine(*self.0);
474 }
475 }
476 }
477}
478
479impl Deref for ExecEngineInner<'_> {
480 type Target = LLVMExecutionEngineRef;
481
482 fn deref(&self) -> &Self::Target {
483 &self.0
484 }
485}
486
487#[derive(Clone)]
490pub struct JitFunction<'ctx, F> {
491 _execution_engine: ExecEngineInner<'ctx>,
492 inner: F,
493}
494
495impl<F: Copy> JitFunction<'_, F> {
496 pub unsafe fn into_raw(self) -> F {
501 self.inner
502 }
503
504 pub unsafe fn as_raw(&self) -> F {
509 self.inner
510 }
511}
512
513impl<F> Debug for JitFunction<'_, F> {
514 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
515 f.debug_tuple("JitFunction").field(&"<unnamed>").finish()
516 }
517}
518
519pub trait UnsafeFunctionPointer: private::SealedUnsafeFunctionPointer {}
521
522mod private {
523 pub trait SealedUnsafeFunctionPointer: Copy {}
528}
529
530impl<F: private::SealedUnsafeFunctionPointer> UnsafeFunctionPointer for F {}
531
532macro_rules! impl_unsafe_fn {
533 (@recurse $first:ident $( , $rest:ident )*) => {
534 impl_unsafe_fn!($( $rest ),*);
535 };
536
537 (@recurse) => {};
538
539 ($( $param:ident ),*) => {
540 impl<Output, $( $param ),*> private::SealedUnsafeFunctionPointer for unsafe extern "C" fn($( $param ),*) -> Output {}
541
542 impl<Output, $( $param ),*> JitFunction<'_, unsafe extern "C" fn($( $param ),*) -> Output> {
543 #[allow(non_snake_case)]
547 #[inline(always)]
548 pub unsafe fn call(&self, $( $param: $param ),*) -> Output { unsafe {
549 (self.inner)($( $param ),*)
550 }}
551 }
552
553 impl_unsafe_fn!(@recurse $( $param ),*);
554 };
555}
556
557impl_unsafe_fn!(A, B, C, D, E, F, G, H, I, J, K, L, M);
558
559#[cfg(feature = "experimental")]
560pub mod experimental {
561 use llvm_sys::error::{LLVMConsumeError, LLVMErrorRef, LLVMErrorTypeId, LLVMGetErrorMessage, LLVMGetErrorTypeId};
562 use llvm_sys::orc::{
563 LLVMOrcAddEagerlyCompiledIR, LLVMOrcAddLazilyCompiledIR, LLVMOrcCreateInstance, LLVMOrcDisposeInstance,
564 LLVMOrcDisposeMangledSymbol, LLVMOrcGetErrorMsg, LLVMOrcGetMangledSymbol, LLVMOrcJITStackRef,
565 };
566
567 use crate::module::Module;
568 use crate::support::to_c_str;
569 use crate::targets::TargetMachine;
570
571 use std::ffi::{CStr, CString};
572 use std::mem::MaybeUninit;
573 use std::ops::Deref;
574
575 #[derive(Debug)]
576 pub struct MangledSymbol(*mut libc::c_char);
577
578 impl Deref for MangledSymbol {
579 type Target = CStr;
580
581 fn deref(&self) -> &CStr {
582 unsafe { CStr::from_ptr(self.0) }
583 }
584 }
585
586 impl Drop for MangledSymbol {
587 fn drop(&mut self) {
588 unsafe { LLVMOrcDisposeMangledSymbol(self.0) }
589 }
590 }
591
592 #[derive(Debug)]
593 pub struct LLVMError(LLVMErrorRef);
594
595 impl LLVMError {
596 pub fn get_type_id(&self) -> LLVMErrorTypeId {
598 unsafe { LLVMGetErrorTypeId(self.0) }
600 }
601 }
602
603 impl Deref for LLVMError {
604 type Target = CStr;
605
606 fn deref(&self) -> &CStr {
607 unsafe {
608 CStr::from_ptr(LLVMGetErrorMessage(self.0)) }
610 }
611 }
612
613 impl Drop for LLVMError {
614 fn drop(&mut self) {
615 unsafe { LLVMConsumeError(self.0) }
616 }
617 }
618
619 #[derive(Debug)]
621 pub struct Orc(LLVMOrcJITStackRef);
622
623 impl Orc {
624 pub fn create(target_machine: TargetMachine) -> Self {
625 let stack_ref = unsafe { LLVMOrcCreateInstance(target_machine.target_machine.as_ptr()) };
626
627 Orc(stack_ref)
628 }
629
630 pub fn add_compiled_ir<'ctx>(&self, module: &Module<'ctx>, lazily: bool) -> Result<(), ()> {
631 Ok(())
639 }
640
641 pub fn get_error(&self) -> &CStr {
643 let err_str = unsafe { LLVMOrcGetErrorMsg(self.0) };
644
645 if err_str.is_null() {
646 panic!("Needs to be optional")
647 }
648
649 unsafe { CStr::from_ptr(err_str) }
650 }
651
652 pub fn get_mangled_symbol(&self, symbol: &str) -> MangledSymbol {
653 let mut mangled_symbol = MaybeUninit::uninit();
654 let c_symbol = to_c_str(symbol);
655
656 unsafe { LLVMOrcGetMangledSymbol(self.0, mangled_symbol.as_mut_ptr(), c_symbol.as_ptr()) };
657
658 MangledSymbol(unsafe { mangled_symbol.assume_init() })
659 }
660 }
661
662 impl Drop for Orc {
663 fn drop(&mut self) {
664 LLVMError(unsafe { LLVMOrcDisposeInstance(self.0) });
667 }
668 }
669
670 #[test]
671 fn test_mangled_str() {
672 use crate::OptimizationLevel;
673 use crate::targets::{CodeModel, InitializationConfig, RelocMode, Target};
674
675 Target::initialize_native(&InitializationConfig::default()).unwrap();
676
677 let target_triple = TargetMachine::get_default_triple();
678 let target = Target::from_triple(&target_triple).unwrap();
679 let target_machine = target
680 .create_target_machine(
681 &target_triple,
682 &"",
683 &"",
684 OptimizationLevel::None,
685 RelocMode::Default,
686 CodeModel::Default,
687 )
688 .unwrap();
689 let orc = Orc::create(target_machine);
690
691 assert_eq!(orc.get_error().to_str().unwrap(), "");
692
693 let mangled_symbol = orc.get_mangled_symbol("MyStructName");
694
695 assert_eq!(orc.get_error().to_str().unwrap(), "");
696
697 assert_eq!(mangled_symbol.to_str().unwrap(), "MyStructName");
699 }
700}