From 3ff7aac2d2eb2cbf2f854793fc0d7bc6f1f7d927 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Sun, 9 Jan 2022 08:40:09 -0800 Subject: 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. --- bytecode/src/heap.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 bytecode/src/heap.rs (limited to 'bytecode/src/heap.rs') 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, +} + +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 { + 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)) + } +} -- cgit v1.3.1