114 lines
2.5 KiB
Rust
114 lines
2.5 KiB
Rust
//! 虚拟机内存管理
|
|
|
|
use thiserror::Error;
|
|
use std::collections::HashMap;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum MemoryError {
|
|
#[error("内存地址无效: {0}")]
|
|
InvalidAddress(u64),
|
|
#[error("内存不足")]
|
|
OutOfMemory,
|
|
}
|
|
|
|
/// 虚拟机内存
|
|
#[derive(Debug, Clone)]
|
|
pub struct Memory {
|
|
data: HashMap<u64, u64>,
|
|
max_size: usize,
|
|
}
|
|
|
|
impl Memory {
|
|
pub fn new() -> Self {
|
|
Memory {
|
|
data: HashMap::new(),
|
|
max_size: 1024 * 1024, // 1M slots
|
|
}
|
|
}
|
|
|
|
pub fn with_capacity(capacity: usize) -> Self {
|
|
Memory {
|
|
data: HashMap::with_capacity(capacity),
|
|
max_size: capacity,
|
|
}
|
|
}
|
|
|
|
/// 加载数据
|
|
pub fn load(&self, address: u64) -> Result<u64, MemoryError> {
|
|
self.data.get(&address)
|
|
.copied()
|
|
.ok_or(MemoryError::InvalidAddress(address))
|
|
}
|
|
|
|
/// 存储数据
|
|
pub fn store(&mut self, address: u64, value: u64) -> Result<(), MemoryError> {
|
|
if self.data.len() >= self.max_size && !self.data.contains_key(&address) {
|
|
return Err(MemoryError::OutOfMemory);
|
|
}
|
|
self.data.insert(address, value);
|
|
Ok(())
|
|
}
|
|
|
|
/// 检查地址是否存在
|
|
pub fn contains(&self, address: u64) -> bool {
|
|
self.data.contains_key(&address)
|
|
}
|
|
|
|
/// 获取已使用的内存大小
|
|
pub fn size(&self) -> usize {
|
|
self.data.len()
|
|
}
|
|
|
|
/// 清空内存
|
|
pub fn clear(&mut self) {
|
|
self.data.clear();
|
|
}
|
|
}
|
|
|
|
impl Default for Memory {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_memory_store_load() {
|
|
let mut memory = Memory::new();
|
|
|
|
memory.store(0x100, 42).unwrap();
|
|
memory.store(0x200, 100).unwrap();
|
|
|
|
assert_eq!(memory.load(0x100).unwrap(), 42);
|
|
assert_eq!(memory.load(0x200).unwrap(), 100);
|
|
}
|
|
|
|
#[test]
|
|
fn test_memory_invalid_address() {
|
|
let memory = Memory::new();
|
|
assert!(memory.load(0x999).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn test_memory_overwrite() {
|
|
let mut memory = Memory::new();
|
|
|
|
memory.store(0x100, 42).unwrap();
|
|
memory.store(0x100, 100).unwrap();
|
|
|
|
assert_eq!(memory.load(0x100).unwrap(), 100);
|
|
}
|
|
|
|
#[test]
|
|
fn test_memory_contains() {
|
|
let mut memory = Memory::new();
|
|
memory.store(0x100, 42).unwrap();
|
|
|
|
assert!(memory.contains(0x100));
|
|
assert!(!memory.contains(0x200));
|
|
}
|
|
}
|