Crate mir

Source
Expand description

§MIR project bindings for Rust

§Quick start

You can also check tests/smoke.rs for more examples.

§Construct a function and execute it via MIR interpreter

use mir::{InsnBuilder, MirContext, Ty, Val};

// Initialize a context.
let ctx = MirContext::new();

// Create a module, a function, append instructions, and finally sealing them.
let m = ctx.enter_new_module(c"module_add");
// Note that MIR requires all argument types to be I64.
// extern "C" fn add(a: i64, b: i64) -> i64
let f = m.enter_new_function(c"add", &[Ty::I64], &[(c"a", Ty::I64), (c"b", Ty::I64)]);
let a = f.get_reg(c"a");
let b = f.get_reg(c"b");
let ret = f.new_local_reg(c"ret", Ty::I64);
f.ins().add(ret, a, b);
f.ins().ret(ret);
let func = f.finish();
let module = m.finish();

// Load and link modules.
ctx.load_module(module);
ctx.link_modules_for_interpret();

// Execute our functions.
let mut ret = [Val::default()];
unsafe { ctx.interpret_unchecked(func, &mut ret, &[Val::from(40i64), Val::from(2i64)]) };
assert_eq!(ret[0].as_i64(), 42);

§Codegen a function to native code and execute it natively

use mir::{InsnBuilder, MirContext, MirGenContext, Ty};

// Initialize a context and codegen context.
let ctx = MirGenContext::new(MirContext::new());

// Same creation code.
let m = ctx.enter_new_module(c"module_add");
// ...
let module = m.finish();

// Set optimization level and/or other configurables.
ctx.set_opt_level(3);
// Load and link modules, for codegen.
ctx.load_module(module);
ctx.link_modules_for_codegen();

// Codegen and get a pointer to generated function.
let func_ptr = ctx.codegen_func(func);
type AddFunc = extern "C" fn(a: i64, b: i64) -> i64;
let func_ptr = unsafe { std::mem::transmute::<*mut _, AddFunc>(func_ptr) };

// Call it!
assert_eq!(func_ptr(40, 2), 42);

§Panics and errors

Unfortunately MIR treats all errors as fatal errors and is likely to continue be like this. In mir-rs, we did a best-effort recovery to unwind in error callback inside C code via “C-unwind” ABI. This is always safe because all intermediate C frames are Plain Old Frames. But it may leave the C states inconsistent, thus it is strongly recommended to drop the MirContext if any modification method panics.

§Features

  • default: Implies io, interp, gen.

  • io: De/serialization of MIR memory representation into/from bytes.

  • interp: Enables MIR interpreter.

  • gen: MIR native code generator.

  • gen-debug: Debug logging in MIR native code generator. It implies gen.

Re-exports§

pub use mir_sys as ffi;

Structs§

BssItemRef
Reference to a writable memory segment item.
DataItemRef
Reference to a data item.
ExportItemRef
Reference to a export item.
ExprDataItemRef
Reference to a computed data item.
ForwardItemRef
Reference to a forward declaration item.
FuncItemRef
Reference to a function item.
ImportItemRef
Reference to a import item.
ItemRef
Reference to an item.
ItemType
Type of items.
Label
Label identifier.
LabelRefDataItemRef
Reference to a label data item.
MemOp
Memory operand.
MirContext
The context for code generation, linking and interpreter.
MirFuncBuilder
The currently building MIR function.
MirGenContextgen
The MIR context for native code generation.
MirModuleBuilder
The currently building MIR module.
MirModuleRef
A module reference.
Operand
Operand of instructions.
ProtoItemRef
Reference to a prototype item.
RefDataItemRef
Reference to a referential data item.
Reg
Virtual register identifier.
Ty
Type of virtual registers.
Valinterp
Untagged value for MIR interpreter.

Traits§

InsnBuilder
The instruction builder.
IntoOperand
Convertible to Operand.
IntoOutOperand
Convertible to Operand, but can only be used in destination place.