alduin 0.0.1

WIP: A toy compiler backend
Documentation
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>> {
        // FIXME: Performance
        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);