2 unstable releases
new 0.3.0 | Mar 9, 2025 |
---|---|
0.2.0 | Mar 7, 2025 |
0.1.0 |
|
#457 in Programming languages
90 downloads per month
1.5MB
35K
SLoC
mir-rs: MIR project bindings for Rust
See documentation for more details.
License
MIT Licensed.
lib.rs
:
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
: Impliesio
,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 impliesgen
.