wasm/execution/
registry.rs

1use crate::instances::ModuleInst;
2use crate::RuntimeError;
3
4use alloc::borrow::Cow;
5use alloc::collections::BTreeMap;
6
7use crate::ExternVal;
8
9#[derive(Debug, PartialEq, PartialOrd, Eq, Ord)]
10struct ImportKey {
11    module_name: Cow<'static, str>,
12    name: Cow<'static, str>,
13}
14#[derive(Default, Debug)]
15pub struct Registry(BTreeMap<ImportKey, ExternVal>);
16
17impl Registry {
18    pub fn register(
19        &mut self,
20        module_name: Cow<'static, str>,
21        name: Cow<'static, str>,
22        extern_val: ExternVal,
23    ) -> Result<(), RuntimeError> {
24        if self
25            .0
26            .insert(ImportKey { module_name, name }, extern_val)
27            .is_some()
28        {
29            return Err(RuntimeError::InvalidImportType);
30        }
31
32        Ok(())
33    }
34
35    pub fn lookup(
36        &self,
37        module_name: Cow<'static, str>,
38        name: Cow<'static, str>,
39    ) -> Result<&ExternVal, RuntimeError> {
40        // Note: We cannot do a `&str` lookup on a [`String`] map key.
41        // Thus we have to use `Cow<'static, str>` as a key
42        // (at least this prevents allocations with static names).
43        self.0
44            .get(&ImportKey { module_name, name })
45            .ok_or(RuntimeError::UnknownImport)
46    }
47
48    pub fn register_module(
49        &mut self,
50        module_name: Cow<'static, str>,
51        module_inst: &ModuleInst,
52    ) -> Result<(), RuntimeError> {
53        for (entity_name, extern_val) in &module_inst.exports {
54            // FIXME this clones module_name. Maybe prevent by using `Cow<'static, Arc<str>>`.
55            self.register(
56                module_name.clone(),
57                Cow::Owned(entity_name.clone()),
58                *extern_val,
59            )?;
60        }
61        Ok(())
62    }
63}