1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#![recursion_limit="256"]
extern crate gluon;
#[macro_use]
extern crate gluon_vm;
extern crate falcon;
#[macro_use]
macro_rules! falcon_type_wrapper {
($p: path, $n: ident) => {
#[derive(Clone, Debug)] pub struct $n { pub x: $p }
impl VmType for $n { type Type = $n; }
impl Traverseable for $n {}
impl Userdata for $n {}
}
}
pub mod analysis;
pub mod architecture;
pub mod il;
pub mod loader;
pub mod memory;
fn hex(v: u64) -> String {
format!("{:x}", v)
}
fn println(string: String) {
println!("{}", string);
}
fn env (name: String) -> Option<String> {
match std::env::var(&name) {
Ok(v) => Some(v),
Err(_) => None
}
}
fn eval(expression: &il::IlExpression) -> Option<il::IlConstant> {
falcon::executor::eval(&expression.x)
.ok()
.map(|constant| il::IlConstant {x: constant})
}
fn int_to_string(i: usize) -> Option<String> {
String::from_utf8(vec![i as u8]).ok()
}
pub fn bindings (vm: gluon::RootedThread) -> gluon::RootedThread {
fn falcon_prim_loader(vm: &gluon::Thread)
-> gluon::vm::Result<gluon::vm::ExternModule> {
gluon::vm::ExternModule::new(vm, record! {
env => primitive!(1 env),
eval => primitive!(1 eval),
hex => primitive!(1 hex),
int_to_string => primitive!(1 int_to_string),
println => primitive!(1 println)
})
}
gluon::import::add_extern_module(&vm, "falcon_prim", falcon_prim_loader);
vm
}
pub fn attach_bindings(vm: gluon::RootedThread) -> gluon::RootedThread {
let vm = bindings(vm);
let vm = analysis::bindings(vm);
let vm = architecture::bindings(vm);
let vm = il::bindings(vm);
let vm = memory::bindings(vm);
let vm = loader::bindings(vm);
vm
}
pub fn run_code(code: &str) -> gluon::RootedThread {
let vm = gluon::new_vm();
let vm = attach_bindings(vm);
let mut compiler = gluon::Compiler::new();
match compiler.run_expr::<()>(&vm, "code", code) {
Ok(r) => r,
Err(e) => {
println!("{}", e);
panic!("Compile error");
}
};
vm
}