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::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 unsafe {
100 assert!(!execution_engine.is_null());
101
102 let target_data = LLVMGetExecutionEngineTargetData(*execution_engine);
104
105 ExecutionEngine {
106 execution_engine: Some(ExecEngineInner(execution_engine, PhantomData)),
107 target_data: Some(TargetData::new(target_data)),
108 jit_mode,
109 }
110 }
111 }
112
113 pub fn as_mut_ptr(&self) -> LLVMExecutionEngineRef {
115 self.execution_engine_inner()
116 }
117
118 pub(crate) fn execution_engine_rc(&self) -> &Rc<LLVMExecutionEngineRef> {
119 &self.execution_engine.as_ref().expect(EE_INNER_PANIC).0
120 }
121
122 #[inline]
123 pub(crate) fn execution_engine_inner(&self) -> LLVMExecutionEngineRef {
124 **self.execution_engine_rc()
125 }
126
127 pub fn link_in_mc_jit() {
130 unsafe { LLVMLinkInMCJIT() }
131 }
132
133 pub fn link_in_interpreter() {
136 unsafe {
137 LLVMLinkInInterpreter();
138 }
139 }
140
141 pub fn add_global_mapping(&self, value: &dyn AnyValue<'ctx>, addr: usize) {
183 unsafe { LLVMAddGlobalMapping(self.execution_engine_inner(), value.as_value_ref(), addr as *mut _) }
184 }
185
186 pub fn add_module(&self, module: &Module<'ctx>) -> Result<(), ()> {
204 unsafe { LLVMAddModule(self.execution_engine_inner(), module.module.get()) }
205
206 if module.owned_by_ee.borrow().is_some() {
207 return Err(());
208 }
209
210 *module.owned_by_ee.borrow_mut() = Some(self.clone());
211
212 Ok(())
213 }
214
215 pub fn remove_module(&self, module: &Module<'ctx>) -> Result<(), RemoveModuleError> {
216 match *module.owned_by_ee.borrow() {
217 Some(ref ee) if ee.execution_engine_inner() != self.execution_engine_inner() => {
218 return Err(RemoveModuleError::IncorrectModuleOwner);
219 },
220 None => return Err(RemoveModuleError::ModuleNotOwned),
221 _ => (),
222 }
223
224 let mut new_module = MaybeUninit::uninit();
225 let mut err_string: *mut ::libc::c_char = ::core::ptr::null_mut();
226
227 let code = unsafe {
228 LLVMRemoveModule(
229 self.execution_engine_inner(),
230 module.module.get(),
231 new_module.as_mut_ptr(),
232 &mut err_string,
233 )
234 };
235
236 if code == 1 {
237 unsafe {
238 return Err(RemoveModuleError::LLVMError(LLVMString::new(err_string)));
239 }
240 }
241
242 let new_module = unsafe { new_module.assume_init() };
243
244 module.module.set(new_module);
245 *module.owned_by_ee.borrow_mut() = None;
246
247 Ok(())
248 }
249
250 pub unsafe fn get_function<F>(&self, fn_name: &str) -> Result<JitFunction<'ctx, F>, FunctionLookupError>
308 where
309 F: UnsafeFunctionPointer,
310 {
311 unsafe {
312 if !self.jit_mode {
313 return Err(FunctionLookupError::JITNotEnabled);
314 }
315
316 let address = self.get_function_address(fn_name)?;
317
318 assert_eq!(
319 size_of::<F>(),
320 size_of::<usize>(),
321 "The type `F` must have the same size as a function pointer"
322 );
323
324 let execution_engine = self.execution_engine.as_ref().expect(EE_INNER_PANIC);
325
326 Ok(JitFunction {
327 _execution_engine: execution_engine.clone(),
328 inner: transmute_copy(&address),
329 })
330 }
331 }
332
333 pub fn get_function_address(&self, fn_name: &str) -> Result<usize, FunctionLookupError> {
339 let c_string = to_c_str(fn_name);
340 let address = unsafe { LLVMGetFunctionAddress(self.execution_engine_inner(), c_string.as_ptr()) };
341
342 if address == 0 {
347 return Err(FunctionLookupError::FunctionNotFound);
348 }
349
350 Ok(address as usize)
351 }
352
353 pub fn get_target_data(&self) -> &TargetData {
356 self.target_data
357 .as_ref()
358 .expect("TargetData should always exist until Drop")
359 }
360
361 pub fn get_function_value(&self, fn_name: &str) -> Result<FunctionValue<'ctx>, FunctionLookupError> {
366 if !self.jit_mode {
367 return Err(FunctionLookupError::JITNotEnabled);
368 }
369
370 let c_string = to_c_str(fn_name);
371 let mut function = MaybeUninit::uninit();
372
373 let code = unsafe { LLVMFindFunction(self.execution_engine_inner(), c_string.as_ptr(), function.as_mut_ptr()) };
374
375 if code == 0 {
376 return unsafe { FunctionValue::new(function.assume_init()).ok_or(FunctionLookupError::FunctionNotFound) };
377 };
378
379 Err(FunctionLookupError::FunctionNotFound)
380 }
381
382 pub unsafe fn run_function(
385 &self,
386 function: FunctionValue<'ctx>,
387 args: &[&GenericValue<'ctx>],
388 ) -> GenericValue<'ctx> {
389 unsafe {
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
403 pub unsafe fn run_function_as_main(&self, function: FunctionValue<'ctx>, args: &[&str]) -> c_int {
407 unsafe {
408 let cstring_args: Vec<_> = args.iter().map(|&arg| to_c_str(arg)).collect();
409 let raw_args: Vec<*const _> = cstring_args.iter().map(|arg| arg.as_ptr()).collect();
410
411 let environment_variables = []; LLVMRunFunctionAsMain(
414 self.execution_engine_inner(),
415 function.as_value_ref(),
416 raw_args.len() as u32,
417 raw_args.as_ptr(),
418 environment_variables.as_ptr(),
419 ) }
421 }
422
423 pub fn free_fn_machine_code(&self, function: FunctionValue<'ctx>) {
424 unsafe { LLVMFreeMachineCodeForFunction(self.execution_engine_inner(), function.as_value_ref()) }
425 }
426
427 pub fn run_static_constructors(&self) {
429 unsafe { LLVMRunStaticConstructors(self.execution_engine_inner()) }
430 }
431
432 pub fn run_static_destructors(&self) {
434 unsafe { LLVMRunStaticDestructors(self.execution_engine_inner()) }
435 }
436}
437
438impl Drop for ExecutionEngine<'_> {
441 fn drop(&mut self) {
442 forget(
443 self.target_data
444 .take()
445 .expect("TargetData should always exist until Drop"),
446 );
447
448 drop(self.execution_engine.take().expect(EE_INNER_PANIC));
452 }
453}
454
455impl Clone for ExecutionEngine<'_> {
456 fn clone(&self) -> Self {
457 let execution_engine_rc = self.execution_engine_rc().clone();
458
459 unsafe { ExecutionEngine::new(execution_engine_rc, self.jit_mode) }
460 }
461}
462
463#[derive(Debug, Clone, PartialEq, Eq)]
465struct ExecEngineInner<'ctx>(Rc<LLVMExecutionEngineRef>, PhantomData<&'ctx Context>);
466
467impl Drop for ExecEngineInner<'_> {
468 fn drop(&mut self) {
469 if Rc::strong_count(&self.0) == 1 {
470 unsafe {
471 LLVMDisposeExecutionEngine(*self.0);
472 }
473 }
474 }
475}
476
477impl Deref for ExecEngineInner<'_> {
478 type Target = LLVMExecutionEngineRef;
479
480 fn deref(&self) -> &Self::Target {
481 &self.0
482 }
483}
484
485#[derive(Clone)]
488pub struct JitFunction<'ctx, F> {
489 _execution_engine: ExecEngineInner<'ctx>,
490 inner: F,
491}
492
493impl<F: Copy> JitFunction<'_, F> {
494 pub unsafe fn into_raw(self) -> F {
499 self.inner
500 }
501
502 pub unsafe fn as_raw(&self) -> F {
507 self.inner
508 }
509}
510
511impl<F> Debug for JitFunction<'_, F> {
512 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
513 f.debug_tuple("JitFunction").field(&"<unnamed>").finish()
514 }
515}
516
517pub trait UnsafeFunctionPointer: private::SealedUnsafeFunctionPointer {}
519
520mod private {
521 pub trait SealedUnsafeFunctionPointer: Copy {}
526}
527
528impl<F: private::SealedUnsafeFunctionPointer> UnsafeFunctionPointer for F {}
529
530macro_rules! impl_unsafe_fn {
531 (@recurse $first:ident $( , $rest:ident )*) => {
532 impl_unsafe_fn!($( $rest ),*);
533 };
534
535 (@recurse) => {};
536
537 ($( $param:ident ),*) => {
538 impl<Output, $( $param ),*> private::SealedUnsafeFunctionPointer for unsafe extern "C" fn($( $param ),*) -> Output {}
539
540 impl<Output, $( $param ),*> JitFunction<'_, unsafe extern "C" fn($( $param ),*) -> Output> {
541 #[allow(non_snake_case)]
545 #[inline(always)]
546 pub unsafe fn call(&self, $( $param: $param ),*) -> Output { unsafe {
547 (self.inner)($( $param ),*)
548 }}
549 }
550
551 impl_unsafe_fn!(@recurse $( $param ),*);
552 };
553}
554
555impl_unsafe_fn!(A, B, C, D, E, F, G, H, I, J, K, L, M);
556
557#[cfg(feature = "experimental")]
558pub mod experimental {
559 use llvm_sys::error::{LLVMConsumeError, LLVMErrorRef, LLVMErrorTypeId, LLVMGetErrorMessage, LLVMGetErrorTypeId};
560 use llvm_sys::orc::{
561 LLVMOrcAddEagerlyCompiledIR, LLVMOrcAddLazilyCompiledIR, LLVMOrcCreateInstance, LLVMOrcDisposeInstance,
562 LLVMOrcDisposeMangledSymbol, LLVMOrcGetErrorMsg, LLVMOrcGetMangledSymbol, LLVMOrcJITStackRef,
563 };
564
565 use crate::module::Module;
566 use crate::support::to_c_str;
567 use crate::targets::TargetMachine;
568
569 use std::ffi::{CStr, CString};
570 use std::mem::MaybeUninit;
571 use std::ops::Deref;
572
573 #[derive(Debug)]
574 pub struct MangledSymbol(*mut libc::c_char);
575
576 impl Deref for MangledSymbol {
577 type Target = CStr;
578
579 fn deref(&self) -> &CStr {
580 unsafe { CStr::from_ptr(self.0) }
581 }
582 }
583
584 impl Drop for MangledSymbol {
585 fn drop(&mut self) {
586 unsafe { LLVMOrcDisposeMangledSymbol(self.0) }
587 }
588 }
589
590 #[derive(Debug)]
591 pub struct LLVMError(LLVMErrorRef);
592
593 impl LLVMError {
594 pub fn get_type_id(&self) -> LLVMErrorTypeId {
596 unsafe { LLVMGetErrorTypeId(self.0) }
598 }
599 }
600
601 impl Deref for LLVMError {
602 type Target = CStr;
603
604 fn deref(&self) -> &CStr {
605 unsafe {
606 CStr::from_ptr(LLVMGetErrorMessage(self.0)) }
608 }
609 }
610
611 impl Drop for LLVMError {
612 fn drop(&mut self) {
613 unsafe { LLVMConsumeError(self.0) }
614 }
615 }
616
617 #[derive(Debug)]
619 pub struct Orc(LLVMOrcJITStackRef);
620
621 impl Orc {
622 pub fn create(target_machine: TargetMachine) -> Self {
623 let stack_ref = unsafe { LLVMOrcCreateInstance(target_machine.target_machine) };
624
625 Orc(stack_ref)
626 }
627
628 pub fn add_compiled_ir<'ctx>(&self, module: &Module<'ctx>, lazily: bool) -> Result<(), ()> {
629 Ok(())
637 }
638
639 pub fn get_error(&self) -> &CStr {
641 let err_str = unsafe { LLVMOrcGetErrorMsg(self.0) };
642
643 if err_str.is_null() {
644 panic!("Needs to be optional")
645 }
646
647 unsafe { CStr::from_ptr(err_str) }
648 }
649
650 pub fn get_mangled_symbol(&self, symbol: &str) -> MangledSymbol {
651 let mut mangled_symbol = MaybeUninit::uninit();
652 let c_symbol = to_c_str(symbol);
653
654 unsafe { LLVMOrcGetMangledSymbol(self.0, mangled_symbol.as_mut_ptr(), c_symbol.as_ptr()) };
655
656 MangledSymbol(unsafe { mangled_symbol.assume_init() })
657 }
658 }
659
660 impl Drop for Orc {
661 fn drop(&mut self) {
662 LLVMError(unsafe { LLVMOrcDisposeInstance(self.0) });
665 }
666 }
667
668 #[test]
669 fn test_mangled_str() {
670 use crate::OptimizationLevel;
671 use crate::targets::{CodeModel, InitializationConfig, RelocMode, Target};
672
673 Target::initialize_native(&InitializationConfig::default()).unwrap();
674
675 let target_triple = TargetMachine::get_default_triple();
676 let target = Target::from_triple(&target_triple).unwrap();
677 let target_machine = target
678 .create_target_machine(
679 &target_triple,
680 &"",
681 &"",
682 OptimizationLevel::None,
683 RelocMode::Default,
684 CodeModel::Default,
685 )
686 .unwrap();
687 let orc = Orc::create(target_machine);
688
689 assert_eq!(orc.get_error().to_str().unwrap(), "");
690
691 let mangled_symbol = orc.get_mangled_symbol("MyStructName");
692
693 assert_eq!(orc.get_error().to_str().unwrap(), "");
694
695 assert_eq!(mangled_symbol.to_str().unwrap(), "MyStructName");
697 }
698}