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
|
fn transmute(p: &u8) -> Result<&u64, String> {
let u8_p = p as *const u8;
let u64_p = u8_p as *const u64;
if u64_p as usize % 8 != 0 {
return Err(String::from("not aligned"));
}
unsafe {
return Ok(&*u64_p);
}
}
fn transmute_mut(p: &mut u8) -> Result<&mut u64, String> {
let u8_p = p as *mut u8;
let u64_p = u8_p as *mut u64;
if u64_p as usize % 8 != 0 {
return Err(String::from("not aligned"));
}
unsafe {
return Ok(&mut *u64_p);
}
}
pub struct Heap {
heap: Vec<u8>,
}
pub struct Pointer(usize);
impl Heap {
pub fn new() -> Self {
Heap {
heap: vec![0; 128], // 1 kB
}
}
pub fn alloc(&mut self, n: usize) -> Pointer {
let p = Pointer(self.heap.len());
self.heap.append(&mut vec![0; n]);
p
}
pub fn peek(&self, p: Pointer) -> Result<u64, String> {
let Pointer(x) = p;
let u8_p = &self.heap[x];
let u64_p = transmute(u8_p)?;
Ok(*u64_p)
}
pub fn poke(&mut self, u: u64, p: Pointer) -> Result<(), String> {
let Pointer(x) = p;
let u8_p = &mut self.heap[x];
let u64_p = transmute_mut(u8_p)?;
*u64_p = u;
Ok(())
}
pub fn peek_byte(&self, p: Pointer) -> u8 {
let Pointer(x) = p;
self.heap[x]
}
pub fn poke_byte(&mut self, u: u8, p: Pointer) {
let Pointer(x) = p;
self.heap[x] = u;
}
}
impl Pointer {
pub fn from_bytes(p: u64) -> Self {
Pointer(usize::try_from(p).unwrap() >> 1)
}
pub fn bytes(&self) -> u64 {
let Pointer(x) = self;
u64::try_from(*x).unwrap() << 1
}
pub fn offset(&self, off: u8) -> Pointer {
let Pointer(x) = self;
Pointer(*x + usize::from(off))
}
}
|