diff options
| author | Rose Hogenson <rhogenson@posteo.net> | 2022-01-09 08:40:09 -0800 |
|---|---|---|
| committer | Rose Hogenson <rhogenson@posteo.net> | 2022-01-09 08:40:09 -0800 |
| commit | 3ff7aac2d2eb2cbf2f854793fc0d7bc6f1f7d927 (patch) | |
| tree | cef8ca0e77c40a70daaca40af25572437d563105 /bytecode/src/heap.rs | |
| download | chromatopelma-3ff7aac2d2eb2cbf2f854793fc0d7bc6f1f7d927.tar.zst | |
Initial commit.
Not sure if everything here will be needed eventually, but we have a
working bytecode interpreter. Next I will write the linker, then the
core compiler, and finish with the macro expander.
Diffstat (limited to 'bytecode/src/heap.rs')
| -rw-r--r-- | bytecode/src/heap.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/bytecode/src/heap.rs b/bytecode/src/heap.rs new file mode 100644 index 0000000..d76456a --- /dev/null +++ b/bytecode/src/heap.rs @@ -0,0 +1,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)) + } +} |
