1use crate::{
2 func::FuncRef,
3 global::GlobalRef,
4 memory::MemoryRef,
5 module::ModuleRef,
6 table::TableRef,
7 types::{GlobalDescriptor, MemoryDescriptor, TableDescriptor},
8 Error,
9 Signature,
10};
11use alloc::{collections::BTreeMap, string::String};
12
13pub trait ImportResolver {
25 fn resolve_func(
30 &self,
31 _module_name: &str,
32 field_name: &str,
33 _signature: &Signature,
34 ) -> Result<FuncRef, Error>;
35
36 fn resolve_global(
41 &self,
42 module_name: &str,
43 field_name: &str,
44 descriptor: &GlobalDescriptor,
45 ) -> Result<GlobalRef, Error>;
46
47 fn resolve_memory(
55 &self,
56 module_name: &str,
57 field_name: &str,
58 descriptor: &MemoryDescriptor,
59 ) -> Result<MemoryRef, Error>;
60
61 fn resolve_table(
69 &self,
70 module_name: &str,
71 field_name: &str,
72 descriptor: &TableDescriptor,
73 ) -> Result<TableRef, Error>;
74}
75
76pub struct ImportsBuilder<'a> {
105 modules: BTreeMap<String, &'a dyn ModuleImportResolver>,
106}
107
108impl Default for ImportsBuilder<'_> {
109 fn default() -> Self {
110 Self::new()
111 }
112}
113
114impl<'a> ImportsBuilder<'a> {
115 pub fn new() -> ImportsBuilder<'a> {
117 ImportsBuilder {
118 modules: BTreeMap::new(),
119 }
120 }
121
122 #[must_use]
124 pub fn with_resolver<N: Into<String>>(
125 mut self,
126 name: N,
127 resolver: &'a dyn ModuleImportResolver,
128 ) -> Self {
129 self.modules.insert(name.into(), resolver);
130 self
131 }
132
133 pub fn push_resolver<N: Into<String>>(
137 &mut self,
138 name: N,
139 resolver: &'a dyn ModuleImportResolver,
140 ) {
141 self.modules.insert(name.into(), resolver);
142 }
143
144 fn resolver(&self, name: &str) -> Option<&dyn ModuleImportResolver> {
145 self.modules.get(name).cloned()
146 }
147}
148
149impl ImportResolver for ImportsBuilder<'_> {
150 fn resolve_func(
151 &self,
152 module_name: &str,
153 field_name: &str,
154 signature: &Signature,
155 ) -> Result<FuncRef, Error> {
156 self.resolver(module_name)
157 .ok_or_else(|| Error::Instantiation(format!("Module {} not found", module_name)))?
158 .resolve_func(field_name, signature)
159 }
160
161 fn resolve_global(
162 &self,
163 module_name: &str,
164 field_name: &str,
165 global_type: &GlobalDescriptor,
166 ) -> Result<GlobalRef, Error> {
167 self.resolver(module_name)
168 .ok_or_else(|| Error::Instantiation(format!("Module {} not found", module_name)))?
169 .resolve_global(field_name, global_type)
170 }
171
172 fn resolve_memory(
173 &self,
174 module_name: &str,
175 field_name: &str,
176 memory_type: &MemoryDescriptor,
177 ) -> Result<MemoryRef, Error> {
178 self.resolver(module_name)
179 .ok_or_else(|| Error::Instantiation(format!("Module {} not found", module_name)))?
180 .resolve_memory(field_name, memory_type)
181 }
182
183 fn resolve_table(
184 &self,
185 module_name: &str,
186 field_name: &str,
187 table_type: &TableDescriptor,
188 ) -> Result<TableRef, Error> {
189 self.resolver(module_name)
190 .ok_or_else(|| Error::Instantiation(format!("Module {} not found", module_name)))?
191 .resolve_table(field_name, table_type)
192 }
193}
194
195pub trait ModuleImportResolver {
199 fn resolve_func(&self, field_name: &str, _signature: &Signature) -> Result<FuncRef, Error> {
205 Err(Error::Instantiation(format!(
206 "Export {} not found",
207 field_name
208 )))
209 }
210
211 fn resolve_global(
217 &self,
218 field_name: &str,
219 _global_type: &GlobalDescriptor,
220 ) -> Result<GlobalRef, Error> {
221 Err(Error::Instantiation(format!(
222 "Export {} not found",
223 field_name
224 )))
225 }
226
227 fn resolve_memory(
233 &self,
234 field_name: &str,
235 _memory_type: &MemoryDescriptor,
236 ) -> Result<MemoryRef, Error> {
237 Err(Error::Instantiation(format!(
238 "Export {} not found",
239 field_name
240 )))
241 }
242
243 fn resolve_table(
249 &self,
250 field_name: &str,
251 _table_type: &TableDescriptor,
252 ) -> Result<TableRef, Error> {
253 Err(Error::Instantiation(format!(
254 "Export {} not found",
255 field_name
256 )))
257 }
258}
259
260impl ModuleImportResolver for ModuleRef {
261 fn resolve_func(&self, field_name: &str, _signature: &Signature) -> Result<FuncRef, Error> {
262 self.export_by_name(field_name)
263 .ok_or_else(|| Error::Instantiation(format!("Export {} not found", field_name)))?
264 .as_func()
265 .cloned()
266 .ok_or_else(|| Error::Instantiation(format!("Export {} is not a function", field_name)))
267 }
268
269 fn resolve_global(
270 &self,
271 field_name: &str,
272 _global_type: &GlobalDescriptor,
273 ) -> Result<GlobalRef, Error> {
274 self.export_by_name(field_name)
275 .ok_or_else(|| Error::Instantiation(format!("Export {} not found", field_name)))?
276 .as_global()
277 .cloned()
278 .ok_or_else(|| Error::Instantiation(format!("Export {} is not a global", field_name)))
279 }
280
281 fn resolve_memory(
282 &self,
283 field_name: &str,
284 _memory_type: &MemoryDescriptor,
285 ) -> Result<MemoryRef, Error> {
286 self.export_by_name(field_name)
287 .ok_or_else(|| Error::Instantiation(format!("Export {} not found", field_name)))?
288 .as_memory()
289 .cloned()
290 .ok_or_else(|| Error::Instantiation(format!("Export {} is not a memory", field_name)))
291 }
292
293 fn resolve_table(
294 &self,
295 field_name: &str,
296 _table_type: &TableDescriptor,
297 ) -> Result<TableRef, Error> {
298 self.export_by_name(field_name)
299 .ok_or_else(|| Error::Instantiation(format!("Export {} not found", field_name)))?
300 .as_table()
301 .cloned()
302 .ok_or_else(|| Error::Instantiation(format!("Export {} is not a table", field_name)))
303 }
304}