Skip to main content

ExecutionEngine

Struct ExecutionEngine 

Source
pub struct ExecutionEngine(/* private fields */);
Expand description

Rust wrapper around [LLVMExecutionEngineRef]

Implementations§

Source§

impl ExecutionEngine

Source

pub fn new_for_module( module: LLVMModule, kind: EngineKind, ) -> Result<Self, String>

Creates a new ExecutionEngine for the given module.

§Example usage:
use pliron_llvm::llvm_sys::{
    core::{LLVMMemoryBuffer, LLVMContext, LLVMModule},
    execution_engine::{ExecutionEngine, EngineKind, MCJITCompilerOptions},
    target::initialize_native,
};
fn main() -> Result<(), String> {
    let llvm_ctx = LLVMContext::default();
    ExecutionEngine::link_in_mcjit();
    initialize_native()?;

    let llvm_ir = r#"
        define i32 @main() {
            ret i32 0
        }"#;
    let ir_mb = LLVMMemoryBuffer::from_str(llvm_ir, "test_buffer");
    let module = LLVMModule::from_ir_in_memory_buffer(&llvm_ctx, ir_mb)?;

    let mcjit_options = MCJITCompilerOptions::default();
    let ee = ExecutionEngine::new_for_module(module, EngineKind::MCJIT(mcjit_options))?;
    let main = ee
        .find_function("main")
        .ok_or("Function 'main' not found")?;
    let ret_gv = unsafe { ee.run_function_as_main(main, &[]) };
    assert_eq!(ret_gv, 0);
    Ok(())
}
Source

pub unsafe fn run_static_constructors(&self)

Runs static constructors.

§Safety

This function executes arbitrary code.

Source

pub unsafe fn run_static_destructors(&self)

Runs static destructors.

§Safety

This function executes arbitrary code.

Source

pub fn find_function(&self, name: &str) -> Option<LLVMValue>

Find a function by name.

Source

pub fn add_global_mapping<T>(&self, function: LLVMValue, addr: *mut T)

Map an external global into the execution engine.

§Example usage:
use pliron_llvm::llvm_sys::{
    core::{LLVMMemoryBuffer, LLVMContext, LLVMModule, llvm_get_named_function},
    execution_engine::{ExecutionEngine, EngineKind, CodeGenOptLevel},
    target::initialize_native,
};
fn main() -> Result<(), String> {
    let llvm_ctx = LLVMContext::default();
    ExecutionEngine::link_in_mcjit();
    initialize_native()?;

    let llvm_ir = r#"
        declare i32 @external_function()

        define i32 @call_external() {
            %result = call i32 @external_function()
            ret i32 %result
        }"#;
    let ir_mb = LLVMMemoryBuffer::from_str(llvm_ir, "test_buffer");
    let module = LLVMModule::from_ir_in_memory_buffer(&llvm_ctx, ir_mb)?;
    let ext_fn_value = llvm_get_named_function(&module, "external_function")
        .ok_or("Function 'external_function' not found")?;

    let ee =
        ExecutionEngine::new_for_module(module, EngineKind::JIT(CodeGenOptLevel::Default))?;
    let call_external_fn = ee
        .find_function("call_external")
        .ok_or("Function 'call_external' not found")?;

    extern "C" fn external_function() -> i32 {
        1234
    }

    ee.add_global_mapping(ext_fn_value, external_function as *mut fn() -> i32);

    let ret_gv = unsafe { ee.run_function(call_external_fn, &[]) };
    let ret_val = ret_gv.to_u64();
    assert_eq!(ret_val, 1234);
    Ok(())
}
Source

pub unsafe fn run_function( &self, function: LLVMValue, args: &[GenericValue], ) -> GenericValue

Execute the function with the given arguments.

§Safety

This function executes arbitrary code.

§Example usage:
use pliron_llvm::llvm_sys::{
    core::{LLVMMemoryBuffer, LLVMContext, LLVMModule, llvm_int_type_in_context},
    execution_engine::{ExecutionEngine, EngineKind, GenericValue},
    target::initialize_native,
};
fn main() -> Result<(), String> {
    let llvm_ctx = LLVMContext::default();
    ExecutionEngine::link_in_interpreter();
    initialize_native()?;

    let llvm_ir = r#"
        define i32 @add(i32 %a, i32 %b) {
            %sum = add i32 %a, %b
            ret i32 %sum
        }"#;
    let ir_mb = LLVMMemoryBuffer::from_str(llvm_ir, "test_buffer");
    let module = LLVMModule::from_ir_in_memory_buffer(&llvm_ctx, ir_mb)?;
    let ee = ExecutionEngine::new_for_module(module, EngineKind::Interpreter)?;
    let add_fn = ee.find_function("add").ok_or("Function 'add' not found")?;

    let i32_type = llvm_int_type_in_context(&llvm_ctx, 32);
    let arg1 = GenericValue::from_u64(i32_type, 10, false);
    let arg2 = GenericValue::from_u64(i32_type, 32, false);
    let ret_gv = unsafe { ee.run_function(add_fn, &[arg1, arg2]) };
    let ret_val = ret_gv.to_u64();
    assert_eq!(ret_val, 42);
    Ok(())
}
Source

pub unsafe fn run_function_as_main( &self, function: LLVMValue, args: &[&str], ) -> i32

Execute a function as main.

§Safety

This function executes arbitrary code.

§Example usage:
use pliron_llvm::llvm_sys::{
    core::{LLVMMemoryBuffer, LLVMContext, LLVMModule},
    execution_engine::{ExecutionEngine, EngineKind},
    target::initialize_native,
};
fn main() -> Result<(), String> {
    let llvm_ctx = LLVMContext::default();
    ExecutionEngine::link_in_interpreter();
    initialize_native()?;

    let llvm_ir = r#"
        define i32 @main() {
            ret i32 42
        }"#;
    let ir_mb = LLVMMemoryBuffer::from_str(llvm_ir, "test_buffer");
    let module = LLVMModule::from_ir_in_memory_buffer(&llvm_ctx, ir_mb)?;
    let ee = ExecutionEngine::new_for_module(module, EngineKind::Interpreter)?;
    let main = ee
        .find_function("main")
        .ok_or("Function 'main' not found")?;
    let ret_gv = unsafe { ee.run_function_as_main(main, &[]) };
    assert_eq!(ret_gv, 42);
    Ok(())
}

Link in Interpreter.

Link in MCJIT.

Trait Implementations§

Source§

impl Drop for ExecutionEngine

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.