qanglang_core/backend/
module_resolver.rs1use std::collections::VecDeque;
2
3use rustc_hash::{FxBuildHasher, FxHashMap};
4
5use crate::{
6 FunctionHandle, HashMapHandle, QangRuntimeError, SourceLocation, StringHandle, Value,
7 backend::vm::RuntimeResult,
8};
9
10#[derive(Debug, Clone, Copy, PartialEq, Hash)]
11pub struct RuntimeModule {
12 function: FunctionHandle,
13 instance: Option<HashMapHandle>,
14}
15
16impl RuntimeModule {
17 pub fn new(function: FunctionHandle) -> Self {
18 Self {
19 function,
20 instance: None,
21 }
22 }
23}
24
25#[derive(Debug, Clone, PartialEq, Default)]
26pub struct ModuleResolver {
27 modules: FxHashMap<StringHandle, RuntimeModule>,
28 module_names: FxHashMap<HashMapHandle, StringHandle>,
29 count: usize,
30}
31
32impl ModuleResolver {
33 pub fn gather_roots(&self, roots: &mut VecDeque<Value>) {
34 for (_, module) in self.modules.iter() {
35 if let Some(handle) = module.instance {
36 roots.push_front(Value::module(handle));
37 }
38 }
39 }
40
41 pub fn get_instance_handle(&self, module_id: StringHandle) -> Option<HashMapHandle> {
42 self.modules.get(&module_id).and_then(|m| m.instance)
43 }
44
45 pub fn remove_instance(&mut self, module_id: StringHandle) {
46 if let Some(module) = self.modules.get_mut(&module_id) {
47 module.instance = None;
48 self.count -= 1;
49 }
50 }
51
52 pub fn get_module_handle(
53 &self,
54 module_id: StringHandle,
55 loc: SourceLocation,
56 ) -> RuntimeResult<FunctionHandle> {
57 self.modules
58 .get(&module_id)
59 .map(|m| m.function)
60 .ok_or(QangRuntimeError::new(
61 "Failed to resolve module.".to_string(),
62 loc,
63 ))
64 }
65
66 pub fn add_instance(&mut self, module_id: StringHandle, handle: HashMapHandle) {
67 if let Some(module) = self.modules.get_mut(&module_id) {
68 module.instance = Some(handle);
69 self.count += 1;
70 self.module_names.insert(handle, module_id);
71 }
72 }
73
74 pub fn get_module_id(&self, handle: HashMapHandle) -> StringHandle {
75 self.module_names[&handle]
76 }
77
78 pub fn count(&self) -> usize {
79 self.count
80 }
81}
82
83impl From<FxHashMap<StringHandle, RuntimeModule>> for ModuleResolver {
84 fn from(val: FxHashMap<StringHandle, RuntimeModule>) -> Self {
85 let capacity = val.capacity();
86 ModuleResolver {
87 modules: val,
88 count: 0,
89 module_names: FxHashMap::with_capacity_and_hasher(capacity, FxBuildHasher),
90 }
91 }
92}