Skip to content

Instantly share code, notes, and snippets.

@gwillen
Last active November 2, 2015 19:09
Show Gist options
  • Save gwillen/9ce58ed836f3a2e6e08c to your computer and use it in GitHub Desktop.
Save gwillen/9ce58ed836f3a2e6e08c to your computer and use it in GitHub Desktop.
Horrible hack to enable mutable state in rusti
use std::collections::HashMap;
std::env::set_var("RUSTI_HACK_SYMTAB",
format!("{:?}",
Box::into_raw(Box::new(HashMap::<&str, i64>::new()))));
fn hack_symtab() -> &'static mut HashMap<&'static str, i64> {
unsafe {
std::mem::transmute(
i64::from_str_radix(
&std::env::var("RUSTI_HACK_SYMTAB").unwrap()[2..],
16).unwrap())
}
}
// set!(name, value) binds name to value.
macro_rules! set {
($name:ident, $x:expr) => {{
hack_symtab().insert(stringify!($name), unsafe {
std::mem::transmute(Box::into_raw(Box::new($x)))
});
}}
}
// get!(name, ty) gets the binding of name, assuming it was originally of type "ty", returning a ref of type "&'static ty".
macro_rules! get {
($name:ident, $t:ty) => {{
unsafe {
let xaddr: i64 = *hack_symtab().get(stringify!($name)).unwrap();
let x: &'static $t = std::mem::transmute(xaddr);
x
}
}}
}
// Examples:
// set!(a, 1); get!(a, i32) => 1 // Perfect!
// set!(a, 1); get!(a, i64) => 4294967297 // Less good.
// set!(a, 1); get!(a, HashMap<i32, i32>) => An unknown error occurred // :-(
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment