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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
use libfirm_rs::{types::*, Entity};
use strum_macros::EnumDiscriminants;
use crate::type_checking::type_system;
#[strum_discriminants(derive(Display))]
#[derive(EnumDiscriminants)]
pub enum RuntimeFunction {
SystemOutPrintln,
SystemOutWrite,
SystemOutFlush,
SystemInRead,
New,
Dumpstack,
NullUsage,
ArrayOutOfBounds,
DivByZero,
}
pub trait RTLib {
fn ld_name(&self, builtin: RuntimeFunction) -> &'static str;
fn mj_main_name(&self) -> &'static str;
}
impl From<type_system::BuiltinMethodBody> for RuntimeFunction {
fn from(mb: type_system::BuiltinMethodBody) -> Self {
use self::type_system::BuiltinMethodBody;
match mb {
BuiltinMethodBody::SystemOutPrintln => RuntimeFunction::SystemOutPrintln,
BuiltinMethodBody::SystemOutWrite => RuntimeFunction::SystemOutWrite,
BuiltinMethodBody::SystemOutFlush => RuntimeFunction::SystemOutFlush,
BuiltinMethodBody::SystemInRead => RuntimeFunction::SystemInRead,
}
}
}
pub struct Mjrt;
impl RTLib for Mjrt {
fn ld_name(&self, rtf: RuntimeFunction) -> &'static str {
match rtf {
RuntimeFunction::SystemOutPrintln => "mjrt_system_out_println",
RuntimeFunction::SystemOutWrite => "mjrt_system_out_write",
RuntimeFunction::SystemOutFlush => "mjrt_system_out_flush",
RuntimeFunction::SystemInRead => "mjrt_system_in_read",
RuntimeFunction::Dumpstack => "mjrt_dumpstack",
RuntimeFunction::DivByZero => "mjrt_div_by_zero",
RuntimeFunction::NullUsage => "mjrt_null_usage",
RuntimeFunction::ArrayOutOfBounds => "mjrt_array_out_of_bounds",
RuntimeFunction::New => "mjrt_new",
}
}
fn mj_main_name(&self) -> &'static str {
"mj_main"
}
}
pub struct Runtime {
pub lib: Box<dyn RTLib>,
pub system_out_println: Entity,
pub system_out_write: Entity,
pub system_out_flush: Entity,
pub system_in_read: Entity,
pub new: Entity,
pub dumpstack: Entity,
pub null_usage: Entity,
pub array_out_of_bounds: Entity,
pub div_by_zero: Entity,
}
impl Runtime {
pub fn new(lib: Box<dyn RTLib>) -> Self {
let dumpstack = {
let t = MethodTyBuilder::new().build_no_this_call();
Entity::new_global(lib.ld_name(RuntimeFunction::Dumpstack), t.into())
};
let system_out_println = {
let it = PrimitiveTy::i32();
let mut t = MethodTyBuilder::new();
t.add_param(it.into());
let t = t.build_no_this_call();
Entity::new_global(lib.ld_name(RuntimeFunction::SystemOutPrintln), t.into())
};
let system_out_write = {
let it = PrimitiveTy::i32();
let mut t = MethodTyBuilder::new();
t.add_param(it.into());
let t = t.build_no_this_call();
Entity::new_global(lib.ld_name(RuntimeFunction::SystemOutWrite), t.into())
};
let system_out_flush = {
let t = MethodTyBuilder::new().build_no_this_call();
Entity::new_global(lib.ld_name(RuntimeFunction::SystemOutFlush), t.into())
};
let system_in_read = {
let it = PrimitiveTy::i32();
let mut t = MethodTyBuilder::new();
t.set_res(it.into());
let t = t.build_no_this_call();
Entity::new_global(lib.ld_name(RuntimeFunction::SystemInRead), t.into())
};
let new = {
let loc = PrimitiveTy::ptr();
let size = PrimitiveTy::i64();
let mut t = MethodTyBuilder::new();
t.add_param(size.into());
t.set_res(loc.into());
let t = t.build_no_this_call();
Entity::new_global(lib.ld_name(RuntimeFunction::New), t.into())
};
let div_by_zero = {
let t = MethodTyBuilder::new().build_no_this_call();
Entity::new_global(lib.ld_name(RuntimeFunction::DivByZero), t.into())
};
let null_usage = {
let t = MethodTyBuilder::new().build_no_this_call();
Entity::new_global(lib.ld_name(RuntimeFunction::NullUsage), t.into())
};
let array_out_of_bounds = {
let t = MethodTyBuilder::new().build_no_this_call();
Entity::new_global(lib.ld_name(RuntimeFunction::ArrayOutOfBounds), t.into())
};
Self {
lib,
system_out_println,
system_out_write,
system_out_flush,
system_in_read,
new,
dumpstack,
div_by_zero,
null_usage,
array_out_of_bounds,
}
}
}