+45
-20
src/main.rs
+45
-20
src/main.rs
···
21
21
.run();
22
22
}
23
23
24
+
/// Lossless conversion to `usize`.
25
+
///
26
+
/// This should only be implemented on types which can be losslessly
27
+
/// cast to a `usize`.
28
+
trait IntoIndex: Sized + Copy {
29
+
fn into_index(self) -> usize;
30
+
}
31
+
32
+
macro_rules! impl_into_index {
33
+
($t:ty) => {
34
+
impl IntoIndex for $t {
35
+
fn into_index(self) -> usize {
36
+
self as usize
37
+
}
38
+
}
39
+
};
40
+
}
41
+
42
+
#[cfg(target_pointer_width = "16")]
43
+
compile_error!("16 bit architectures are unsupported");
44
+
45
+
// usize *may* be 16 bits, so only implement if it is 32 or 64 bits.
46
+
#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
47
+
impl_into_index!(Platter);
48
+
impl_into_index!(Parameter);
49
+
24
50
#[derive(Default)]
25
51
pub struct Um<'a> {
26
52
program_counter: Platter,
···
275
301
/// Loads the value from the specified register.
276
302
fn load_register(&self, index: Parameter) -> Platter {
277
303
assert!(index < 8, "register index out of bounds");
278
-
self.registers[index as usize]
304
+
self.registers[index.into_index()]
279
305
}
280
306
281
307
/// Saves a value to the specified register.
282
308
fn save_register(&mut self, index: Parameter, value: Platter) {
283
309
assert!(index < 8, "register index out of bounds");
284
-
self.registers[index as usize] = value;
310
+
self.registers[index.into_index()] = value;
285
311
}
286
312
287
313
fn load_memory(&self, block: Platter, offset: Platter) -> Platter {
288
-
assert!(
289
-
(block as usize) < self.memory.len()
290
-
&& (offset as usize) < self.memory[block as usize].len()
291
-
);
292
-
self.memory[block as usize][offset as usize]
314
+
let block = block.into_index();
315
+
let offset = offset.into_index();
316
+
assert!(block < self.memory.len() && offset < self.memory[block].len());
317
+
self.memory[block][offset]
293
318
}
294
319
295
320
fn store_memory(&mut self, block: Platter, offset: Platter, value: Platter) {
296
-
assert!(
297
-
(block as usize) < self.memory.len()
298
-
&& (offset as usize) < self.memory[block as usize].len()
299
-
);
300
-
self.memory[block as usize][offset as usize] = value;
321
+
let block = block.into_index();
322
+
let offset = offset.into_index();
323
+
assert!(block < self.memory.len() && offset < self.memory[block].len());
324
+
self.memory[block][offset] = value
301
325
}
302
326
303
327
fn duplicate_memory(&mut self, block: Platter) -> &[Platter] {
304
-
assert!((block as usize) < self.memory.len());
305
-
self.memory[0] = self.memory[block as usize].clone();
328
+
let block = block.into_index();
329
+
assert!(block < self.memory.len());
330
+
self.memory[0] = self.memory[block].clone();
306
331
&self.memory[0]
307
332
}
308
333
309
334
#[cfg(not(feature = "reclaim-memory"))]
310
335
fn allocate_memory(&mut self, length: Platter) -> Platter {
311
-
self.memory.push(Self::new_block(length as usize));
336
+
self.memory.push(Self::new_block(length.into_index()));
312
337
(self.memory.len() - 1) as Platter
313
338
}
314
339
315
340
#[cfg(feature = "reclaim-memory")]
316
341
fn allocate_memory(&mut self, length: Platter) -> Platter {
317
342
if let Some(index) = self.free_blocks.pop() {
318
-
self.memory[index as usize] = Self::new_block(length as usize);
343
+
self.memory[index.into_index()] = Self::new_block(length.into_index());
319
344
index as Platter
320
345
} else {
321
-
self.memory.push(Self::new_block(length as usize));
346
+
self.memory.push(Self::new_block(length.into_index()));
322
347
(self.memory.len() - 1) as Platter
323
348
}
324
349
}
325
350
326
351
fn free_memory(&mut self, block: Platter) {
327
-
assert!((block as usize) < self.memory.len());
352
+
assert!(block.into_index() < self.memory.len());
328
353
#[cfg(feature = "reclaim-memory")]
329
354
{
330
355
self.free_blocks.push(block);
331
-
self.memory[block as usize] = Self::new_block(0);
356
+
self.memory[block.into_index()] = Self::new_block(0);
332
357
}
333
358
}
334
359
···
337
362
fn panic(&self) -> ! {
338
363
panic!(
339
364
"universal machine failure: instruction: {:08x}, program_counter: {:08x}, registers: {:08x?}",
340
-
self.memory[0][self.program_counter as usize], self.program_counter, self.registers
365
+
self.memory[0][self.program_counter.into_index()], self.program_counter, self.registers
341
366
)
342
367
}
343
368