inkpad_executor/wasmi/
builder.rs

1//! WASMI env builder
2use super::{
3    func::{DefinedHostFunctions, HostFuncIndex},
4    memory::Memory,
5};
6use crate::derive;
7use ::wasmi::{
8    Error, FuncInstance, FuncRef, GlobalDescriptor, GlobalRef, ImportResolver, MemoryDescriptor,
9    MemoryRef, Signature, TableDescriptor, TableRef,
10};
11use inkpad_std::{format, BTreeMap, String, ToOwned, Vec};
12
13enum ExternVal {
14    HostFunc(HostFuncIndex),
15    Memory(super::memory::Memory),
16}
17
18/// WASMI env builder
19pub struct Builder<T> {
20    map: BTreeMap<(Vec<u8>, Vec<u8>), ExternVal>,
21    /// Defined hos functions
22    pub defined_host_functions: DefinedHostFunctions<T>,
23}
24
25impl<T> derive::Builder<T> for Builder<T> {
26    type Memory = Memory;
27
28    fn new() -> Self {
29        Builder {
30            map: BTreeMap::new(),
31            defined_host_functions: DefinedHostFunctions::new(),
32        }
33    }
34
35    fn add_host_func<M, F>(&mut self, module: M, field: F, f: derive::HostFuncType<T>)
36    where
37        F: Into<Vec<u8>>,
38        M: Into<Vec<u8>>,
39    {
40        let idx = self.defined_host_functions.define(f);
41        self.map
42            .insert((module.into(), field.into()), ExternVal::HostFunc(idx));
43    }
44
45    fn add_memory<M, F>(&mut self, module: M, field: F, mem: Memory)
46    where
47        M: Into<Vec<u8>>,
48        F: Into<Vec<u8>>,
49    {
50        self.map
51            .insert((module.into(), field.into()), ExternVal::Memory(mem));
52    }
53}
54
55impl<T> ImportResolver for Builder<T> {
56    fn resolve_func(
57        &self,
58        module_name: &str,
59        field_name: &str,
60        signature: &Signature,
61    ) -> Result<FuncRef, Error> {
62        let key = (
63            module_name.as_bytes().to_owned(),
64            field_name.as_bytes().to_owned(),
65        );
66        let externval = self.map.get(&key).ok_or_else(|| {
67            Error::Instantiation(format!("Export {}:{} not found", module_name, field_name))
68        })?;
69        let host_func_idx = match *externval {
70            ExternVal::HostFunc(ref idx) => idx,
71            _ => {
72                return Err(Error::Instantiation(format!(
73                    "Export {}:{} is not a host func",
74                    module_name, field_name
75                )))
76            }
77        };
78        Ok(FuncInstance::alloc_host(signature.clone(), host_func_idx.0))
79    }
80
81    fn resolve_global(
82        &self,
83        _module_name: &str,
84        _field_name: &str,
85        _global_type: &GlobalDescriptor,
86    ) -> Result<GlobalRef, Error> {
87        Err(Error::Instantiation(String::from(
88            "Importing globals is not supported yet",
89        )))
90    }
91
92    fn resolve_memory(
93        &self,
94        module_name: &str,
95        field_name: &str,
96        _memory_type: &MemoryDescriptor,
97    ) -> Result<MemoryRef, Error> {
98        let key = (
99            module_name.as_bytes().to_owned(),
100            field_name.as_bytes().to_owned(),
101        );
102        let externval = self.map.get(&key).ok_or_else(|| {
103            Error::Instantiation(format!("Export {}:{} not found", module_name, field_name))
104        })?;
105
106        let memory = match *externval {
107            ExternVal::Memory(ref m) => m,
108            _ => {
109                return Err(Error::Instantiation(format!(
110                    "Export {}:{} is not a memory",
111                    module_name, field_name
112                )))
113            }
114        };
115        Ok(memory.0.clone())
116    }
117
118    fn resolve_table(
119        &self,
120        _module_name: &str,
121        _field_name: &str,
122        _table_type: &TableDescriptor,
123    ) -> Result<TableRef, Error> {
124        Err(Error::Instantiation(String::from(
125            "Importing tables is not supported yet",
126        )))
127    }
128}