Implementation of the UM-32 "Universal Machine" as described by the Cult of the Bound Variable

add support for `smallvec`

tjh dcf39087 9a425502

Changed files
+38 -5
src
+9
Cargo.lock
··· 3 version = 3 4 5 [[package]] 6 name = "um" 7 version = "0.1.0"
··· 3 version = 3 4 5 [[package]] 6 + name = "smallvec" 7 + version = "1.13.2" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 10 + 11 + [[package]] 12 name = "um" 13 version = "0.1.0" 14 + dependencies = [ 15 + "smallvec", 16 + ]
+4
Cargo.toml
··· 3 version = "0.1.0" 4 edition = "2021" 5 6 [features] 7 default = ["reclaim-memory"] 8 reclaim-memory = []
··· 3 version = "0.1.0" 4 edition = "2021" 5 6 + [dependencies] 7 + smallvec = { version = "1.13.2", optional = true } 8 + 9 [features] 10 default = ["reclaim-memory"] 11 reclaim-memory = [] 12 + smallvec = ["dep:smallvec"]
+25 -5
src/main.rs
··· 1 fn main() { 2 let mut program = Vec::new(); 3 for arg in std::env::args().skip(1) { ··· 114 pub struct Um { 115 program_counter: Platter, 116 registers: [Platter; 8], 117 memory: Vec<Vec<Platter>>, 118 #[cfg(feature = "reclaim-memory")] 119 free_blocks: Vec<Platter>, ··· 127 pub fn new(program: Vec<Platter>) -> Self { 128 let ops = decode_ops(&program); 129 Self { 130 - memory: vec![program], 131 ops, 132 ..Default::default() 133 } ··· 381 382 #[cfg(not(feature = "reclaim-memory"))] 383 fn allocate_memory(&mut self, length: Platter) -> Platter { 384 - self.memory.push(vec![0; length as usize]); 385 (self.memory.len() - 1) as Platter 386 } 387 388 #[cfg(feature = "reclaim-memory")] 389 fn allocate_memory(&mut self, length: Platter) -> Platter { 390 if let Some(index) = self.free_blocks.pop() { 391 - self.memory[index as usize] = vec![0; length as usize]; 392 index as Platter 393 } else { 394 - self.memory.push(vec![0; length as usize]); 395 (self.memory.len() - 1) as Platter 396 } 397 } ··· 401 #[cfg(feature = "reclaim-memory")] 402 { 403 self.free_blocks.push(block); 404 - self.memory[block as usize] = vec![]; 405 } 406 } 407 ··· 411 "universal machine failure: instruction: {:08x}, program_counter: {:08x}, registers: {:08x?}", 412 self.memory[0][self.program_counter as usize], self.program_counter, self.registers 413 ) 414 } 415 }
··· 1 + #[cfg(feature = "smallvec")] 2 + use smallvec::SmallVec; 3 + use std::time::Instant; 4 + 5 + #[cfg(feature = "smallvec")] 6 + const SMALLVEC_SIZE: usize = 24; 7 + 8 fn main() { 9 let mut program = Vec::new(); 10 for arg in std::env::args().skip(1) { ··· 121 pub struct Um { 122 program_counter: Platter, 123 registers: [Platter; 8], 124 + #[cfg(feature = "smallvec")] 125 + memory: Vec<SmallVec<[Platter; SMALLVEC_SIZE]>>, 126 + #[cfg(not(feature = "smallvec"))] 127 memory: Vec<Vec<Platter>>, 128 #[cfg(feature = "reclaim-memory")] 129 free_blocks: Vec<Platter>, ··· 137 pub fn new(program: Vec<Platter>) -> Self { 138 let ops = decode_ops(&program); 139 Self { 140 + memory: vec![program.into()], 141 ops, 142 ..Default::default() 143 } ··· 391 392 #[cfg(not(feature = "reclaim-memory"))] 393 fn allocate_memory(&mut self, length: Platter) -> Platter { 394 + self.memory.push(Self::new_block(length as usize)); 395 (self.memory.len() - 1) as Platter 396 } 397 398 #[cfg(feature = "reclaim-memory")] 399 fn allocate_memory(&mut self, length: Platter) -> Platter { 400 if let Some(index) = self.free_blocks.pop() { 401 + self.memory[index as usize] = Self::new_block(length as usize); 402 index as Platter 403 } else { 404 + self.memory.push(Self::new_block(length as usize)); 405 (self.memory.len() - 1) as Platter 406 } 407 } ··· 411 #[cfg(feature = "reclaim-memory")] 412 { 413 self.free_blocks.push(block); 414 + self.memory[block as usize] = Self::new_block(0); 415 } 416 } 417 ··· 421 "universal machine failure: instruction: {:08x}, program_counter: {:08x}, registers: {:08x?}", 422 self.memory[0][self.program_counter as usize], self.program_counter, self.registers 423 ) 424 + } 425 + 426 + #[cfg(feature = "smallvec")] 427 + fn new_block(len: usize) -> SmallVec<[Platter; SMALLVEC_SIZE]> { 428 + smallvec::smallvec![0; len] 429 + } 430 + 431 + #[cfg(not(feature = "smallvec"))] 432 + fn new_block(len: usize) -> Vec<Platter> { 433 + vec![0; len] 434 } 435 }