inkpad_executor/wasmi/
builder.rs1use 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
18pub struct Builder<T> {
20 map: BTreeMap<(Vec<u8>, Vec<u8>), ExternVal>,
21 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}