use std::sync::{Arc, RwLock, Weak};
use once_cell::sync::Lazy;
use super::VirtualMachine;
pub(crate) struct VMRegistry {
instances: RwLock<Vec<Weak<VirtualMachine>>>,
}
impl VMRegistry {
fn new() -> Self {
Self {
instances: Default::default(),
}
}
pub fn add(&self, mut vm: VirtualMachine) -> Arc<VirtualMachine> {
let mut instances = self.instances.write().unwrap();
vm.registry_index = instances.len();
let arc_vm = Arc::new(vm);
instances.push(Arc::downgrade(&arc_vm));
arc_vm
}
pub fn get_vm_by_code_interior_pointer(&self, ptr: *const u8) -> Option<Arc<VirtualMachine>> {
let instances = self.instances.read().unwrap();
for vm in &*instances {
if let Some(vm) = vm.upgrade() {
let code_range = vm.compiler.code.range();
if ptr >= code_range.start && ptr < code_range.end {
return Some(vm.clone());
}
}
}
None
}
}
pub(crate) static VM_REGISTRY: Lazy<VMRegistry> = Lazy::new(VMRegistry::new);