wasm/execution/
registry.rs

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