1 use crate::error::OutOfMemory;
2 use crate::func::HostFunc;
3 use crate::instance::InstancePre;
4 use crate::store::StoreOpaque;
5 use crate::{
6     AsContext, AsContextMut, Caller, Engine, Extern, ExternType, Func, FuncType, ImportType,
7     Instance, IntoFunc, Module, Result, StoreContextMut, Val, ValRaw, prelude::*,
8 };
9 use alloc::sync::Arc;
10 use core::fmt::{self, Debug};
11 #[cfg(feature = "async")]
12 use core::future::Future;
13 use core::marker;
14 use core::mem::MaybeUninit;
15 use log::warn;
16 use wasmtime_environ::{
17     Atom, PanicOnOom as _, StringPool,
18     collections::{HashMap, TryClone},
19 };
20 
21 /// Structure used to link wasm modules/instances together.
22 ///
23 /// This structure is used to assist in instantiating a [`Module`]. A [`Linker`]
24 /// is a way of performing name resolution to make instantiating a module easier
25 /// than specifying positional imports to [`Instance::new`]. [`Linker`] is a
26 /// name-based resolver where names are dynamically defined and then used to
27 /// instantiate a [`Module`].
28 ///
29 /// An important method is [`Linker::instantiate`] which takes a module to
30 /// instantiate into the provided store. This method will automatically select
31 /// all the right imports for the [`Module`] to be instantiated, and will
32 /// otherwise return an error if an import isn't satisfied.
33 ///
34 /// ## Name Resolution
35 ///
36 /// As mentioned previously, `Linker` is a form of name resolver. It will be
37 /// using the string-based names of imports on a module to attempt to select a
38 /// matching item to hook up to it. This name resolution has two-levels of
39 /// namespaces, a module level and a name level. Each item is defined within a
40 /// module and then has its own name. This basically follows the wasm standard
41 /// for modularization.
42 ///
43 /// Names in a `Linker` cannot be defined twice, but allowing duplicates by
44 /// shadowing the previous definition can be controlled with the
45 /// [`Linker::allow_shadowing`] method.
46 ///
47 /// ## Commands and Reactors
48 ///
49 /// The [`Linker`] type provides conveniences for working with WASI Commands and
50 /// Reactors through the [`Linker::module`] method. This will automatically
51 /// handle instantiation and calling `_start` and such as appropriate
52 /// depending on the inferred type of module.
53 ///
54 /// ## Type parameter `T`
55 ///
56 /// It's worth pointing out that the type parameter `T` on [`Linker<T>`] does
57 /// not represent that `T` is stored within a [`Linker`]. Rather the `T` is used
58 /// to ensure that linker-defined functions and stores instantiated into all use
59 /// the same matching `T` as host state.
60 ///
61 /// ## Multiple `Store`s
62 ///
63 /// The [`Linker`] type is designed to be compatible, in some scenarios, with
64 /// instantiation in multiple [`Store`]s. Specifically host-defined functions
65 /// created in [`Linker`] with [`Linker::func_new`], [`Linker::func_wrap`], and
66 /// their async versions are compatible to instantiate into any [`Store`]. This
67 /// enables programs which want to instantiate lots of modules to create one
68 /// [`Linker`] value at program start up and use that continuously for each
69 /// [`Store`] created over the lifetime of the program.
70 ///
71 /// Note that once [`Store`]-owned items, such as [`Global`], are defined within
72 /// a [`Linker`] then it is no longer compatible with any [`Store`]. At that
73 /// point only the [`Store`] that owns the [`Global`] can be used to instantiate
74 /// modules.
75 ///
76 /// ## Multiple `Engine`s
77 ///
78 /// The [`Linker`] type is not compatible with usage between multiple [`Engine`]
79 /// values. An [`Engine`] is provided when a [`Linker`] is created and only
80 /// stores and items which originate from that [`Engine`] can be used with this
81 /// [`Linker`]. If more than one [`Engine`] is used with a [`Linker`] then that
82 /// may cause a panic at runtime, similar to how if a [`Func`] is used with the
83 /// wrong [`Store`] that can also panic at runtime.
84 ///
85 /// [`Store`]: crate::Store
86 /// [`Global`]: crate::Global
87 pub struct Linker<T> {
88     engine: Engine,
89     pool: StringPool,
90     map: HashMap<ImportKey, Definition>,
91     allow_shadowing: bool,
92     allow_unknown_exports: bool,
93     _marker: marker::PhantomData<fn() -> T>,
94 }
95 
96 impl<T> Debug for Linker<T> {
97     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98         f.debug_struct("Linker").finish_non_exhaustive()
99     }
100 }
101 
102 impl<T> Clone for Linker<T> {
103     fn clone(&self) -> Linker<T> {
104         Linker {
105             engine: self.engine.clone(),
106             pool: self.pool.try_clone().panic_on_oom(),
107             map: self.map.try_clone().panic_on_oom(),
108             allow_shadowing: self.allow_shadowing,
109             allow_unknown_exports: self.allow_unknown_exports,
110             _marker: self._marker,
111         }
112     }
113 }
114 
115 #[derive(Copy, Clone, Hash, PartialEq, Eq)]
116 struct ImportKey {
117     module: Atom,
118     name: Option<Atom>,
119 }
120 
121 impl TryClone for ImportKey {
122     #[inline]
123     fn try_clone(&self) -> Result<Self, OutOfMemory> {
124         Ok(*self)
125     }
126 }
127 
128 #[derive(Clone)]
129 pub(crate) enum Definition {
130     Extern(Extern, DefinitionType),
131     HostFunc(Arc<HostFunc>),
132 }
133 
134 impl TryClone for Definition {
135     fn try_clone(&self) -> core::result::Result<Self, OutOfMemory> {
136         Ok(self.clone())
137     }
138 }
139 
140 /// This is a sort of slimmed down `ExternType` which notably doesn't have a
141 /// `FuncType`, which is an allocation, and additionally retains the current
142 /// size of the table/memory.
143 #[derive(Clone, Copy, Debug)]
144 pub(crate) enum DefinitionType {
145     Func(wasmtime_environ::VMSharedTypeIndex),
146     Global(wasmtime_environ::Global),
147     // Note that tables and memories store not only the original type
148     // information but additionally the current size of the table/memory, as
149     // this is used during linking since the min size specified in the type may
150     // no longer be the current size of the table/memory.
151     Table(wasmtime_environ::Table, u64),
152     Memory(wasmtime_environ::Memory, u64),
153     Tag(wasmtime_environ::Tag),
154 }
155 
156 impl<T> Linker<T> {
157     /// Creates a new [`Linker`].
158     ///
159     /// The linker will define functions within the context of the `engine`
160     /// provided and can only instantiate modules for a [`Store`][crate::Store]
161     /// that is also defined within the same [`Engine`]. Usage of stores with
162     /// different [`Engine`]s may cause a panic when used with this [`Linker`].
163     pub fn new(engine: &Engine) -> Linker<T> {
164         Linker {
165             engine: engine.clone(),
166             map: HashMap::new(),
167             pool: StringPool::new(),
168             allow_shadowing: false,
169             allow_unknown_exports: false,
170             _marker: marker::PhantomData,
171         }
172     }
173 
174     /// Returns the [`Engine`] this is connected to.
175     pub fn engine(&self) -> &Engine {
176         &self.engine
177     }
178 
179     /// Configures whether this [`Linker`] will shadow previous duplicate
180     /// definitions of the same signature.
181     ///
182     /// By default a [`Linker`] will disallow duplicate definitions of the same
183     /// signature. This method, however, can be used to instead allow duplicates
184     /// and have the latest definition take precedence when linking modules.
185     ///
186     /// # Examples
187     ///
188     /// ```
189     /// # use wasmtime::*;
190     /// # fn main() -> Result<()> {
191     /// # let engine = Engine::default();
192     /// let mut linker = Linker::<()>::new(&engine);
193     /// linker.func_wrap("", "", || {})?;
194     ///
195     /// // by default, duplicates are disallowed
196     /// assert!(linker.func_wrap("", "", || {}).is_err());
197     ///
198     /// // but shadowing can be configured to be allowed as well
199     /// linker.allow_shadowing(true);
200     /// linker.func_wrap("", "", || {})?;
201     /// # Ok(())
202     /// # }
203     /// ```
204     pub fn allow_shadowing(&mut self, allow: bool) -> &mut Self {
205         self.allow_shadowing = allow;
206         self
207     }
208 
209     /// Configures whether this [`Linker`] will allow unknown exports from
210     /// command modules.
211     ///
212     /// By default a [`Linker`] will error when unknown exports are encountered
213     /// in a command module while using [`Linker::module`].
214     ///
215     /// This method can be used to allow unknown exports from command modules.
216     ///
217     /// # Examples
218     ///
219     /// ```
220     /// # use wasmtime::*;
221     /// # fn main() -> Result<()> {
222     /// # let engine = Engine::default();
223     /// # let module = Module::new(&engine, "(module)")?;
224     /// # let mut store = Store::new(&engine, ());
225     /// let mut linker = Linker::new(&engine);
226     /// linker.allow_unknown_exports(true);
227     /// linker.module(&mut store, "mod", &module)?;
228     /// # Ok(())
229     /// # }
230     /// ```
231     pub fn allow_unknown_exports(&mut self, allow: bool) -> &mut Self {
232         self.allow_unknown_exports = allow;
233         self
234     }
235 
236     /// Implement any imports of the given [`Module`] with a function which traps.
237     ///
238     /// By default a [`Linker`] will error when unknown imports are encountered
239     /// in a command module while using [`Linker::module`].
240     ///
241     /// This method can be used to allow unknown imports from command modules.
242     ///
243     /// # Examples
244     ///
245     /// ```
246     /// # use wasmtime::*;
247     /// # fn main() -> Result<()> {
248     /// # let engine = Engine::default();
249     /// # let module = Module::new(&engine, "(module (import \"unknown\" \"import\" (func)))")?;
250     /// # let mut store = Store::new(&engine, ());
251     /// let mut linker = Linker::new(&engine);
252     /// linker.define_unknown_imports_as_traps(&module)?;
253     /// linker.instantiate(&mut store, &module)?;
254     /// # Ok(())
255     /// # }
256     /// ```
257     pub fn define_unknown_imports_as_traps(&mut self, module: &Module) -> Result<()>
258     where
259         T: 'static,
260     {
261         for import in module.imports() {
262             if let Err(import_err) = self._get_by_import(&import) {
263                 if let ExternType::Func(func_ty) = import_err.ty() {
264                     self.func_new(import.module(), import.name(), func_ty, move |_, _, _| {
265                         bail!(import_err.clone());
266                     })?;
267                 }
268             }
269         }
270         Ok(())
271     }
272 
273     /// Implement any function imports of the [`Module`] with a function that
274     /// ignores its arguments and returns default values.
275     ///
276     /// Default values are either zero or null, depending on the value type.
277     ///
278     /// This method can be used to allow unknown imports from command modules.
279     ///
280     /// # Example
281     ///
282     /// ```
283     /// # use wasmtime::*;
284     /// # fn main() -> Result<()> {
285     /// # let engine = Engine::default();
286     /// # let module = Module::new(&engine, "(module (import \"unknown\" \"import\" (func)))")?;
287     /// # let mut store = Store::new(&engine, ());
288     /// let mut linker = Linker::new(&engine);
289     /// linker.define_unknown_imports_as_default_values(&mut store, &module)?;
290     /// linker.instantiate(&mut store, &module)?;
291     /// # Ok(())
292     /// # }
293     /// ```
294     pub fn define_unknown_imports_as_default_values(
295         &mut self,
296         mut store: impl AsContextMut<Data = T>,
297         module: &Module,
298     ) -> Result<()>
299     where
300         T: 'static,
301     {
302         let mut store = store.as_context_mut();
303         for import in module.imports() {
304             if let Err(import_err) = self._get_by_import(&import) {
305                 let default_extern =
306                     import_err.ty().default_value(&mut store).with_context(|| {
307                         format_err!(
308                             "no default value exists for `{}::{}` with type `{:?}`",
309                             import.module(),
310                             import.name(),
311                             import_err.ty(),
312                         )
313                     })?;
314                 self.define(
315                     store.as_context(),
316                     import.module(),
317                     import.name(),
318                     default_extern,
319                 )?;
320             }
321         }
322         Ok(())
323     }
324 
325     /// Defines a new item in this [`Linker`].
326     ///
327     /// This method will add a new definition, by name, to this instance of
328     /// [`Linker`]. The `module` and `name` provided are what to name the
329     /// `item`.
330     ///
331     /// # Errors
332     ///
333     /// Returns an error if the `module` and `name` already identify an item
334     /// of the same type as the `item` provided and if shadowing is disallowed.
335     /// For more information see the documentation on [`Linker`].
336     ///
337     /// # Examples
338     ///
339     /// ```
340     /// # use wasmtime::*;
341     /// # fn main() -> Result<()> {
342     /// # let engine = Engine::default();
343     /// # let mut store = Store::new(&engine, ());
344     /// let mut linker = Linker::new(&engine);
345     /// let ty = GlobalType::new(ValType::I32, Mutability::Const);
346     /// let global = Global::new(&mut store, ty, Val::I32(0x1234))?;
347     /// linker.define(&store, "host", "offset", global)?;
348     ///
349     /// let wat = r#"
350     ///     (module
351     ///         (import "host" "offset" (global i32))
352     ///         (memory 1)
353     ///         (data (global.get 0) "foo")
354     ///     )
355     /// "#;
356     /// let module = Module::new(&engine, wat)?;
357     /// linker.instantiate(&mut store, &module)?;
358     /// # Ok(())
359     /// # }
360     /// ```
361     pub fn define(
362         &mut self,
363         store: impl AsContext<Data = T>,
364         module: &str,
365         name: &str,
366         item: impl Into<Extern>,
367     ) -> Result<&mut Self>
368     where
369         T: 'static,
370     {
371         let store = store.as_context();
372         let key = self.import_key(module, Some(name))?;
373         self.insert(key, Definition::new(store.0, item.into()))?;
374         Ok(self)
375     }
376 
377     /// Same as [`Linker::define`], except only the name of the import is
378     /// provided, not a module name as well.
379     ///
380     /// This is only relevant when working with the module linking proposal
381     /// where one-level names are allowed (in addition to two-level names).
382     /// Otherwise this method need not be used.
383     pub fn define_name(
384         &mut self,
385         store: impl AsContext<Data = T>,
386         name: &str,
387         item: impl Into<Extern>,
388     ) -> Result<&mut Self>
389     where
390         T: 'static,
391     {
392         let store = store.as_context();
393         let key = self.import_key(name, None)?;
394         self.insert(key, Definition::new(store.0, item.into()))?;
395         Ok(self)
396     }
397 
398     fn func_insert(&mut self, module: &str, name: &str, func: HostFunc) -> Result<&mut Self>
399     where
400         T: 'static,
401     {
402         let key = self.import_key(module, Some(name))?;
403         self.insert(key, Definition::HostFunc(try_new(func)?))?;
404         Ok(self)
405     }
406 
407     /// Creates a [`Func::new`]-style function named in this linker.
408     ///
409     /// For more information see [`Linker::func_wrap`].
410     ///
411     /// # Panics
412     ///
413     /// Panics if the given function type is not associated with the same engine
414     /// as this linker.
415     pub fn func_new(
416         &mut self,
417         module: &str,
418         name: &str,
419         ty: FuncType,
420         func: impl Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<()> + Send + Sync + 'static,
421     ) -> Result<&mut Self>
422     where
423         T: 'static,
424     {
425         self.func_insert(module, name, HostFunc::new(&self.engine, ty, func)?)
426     }
427 
428     /// Creates a [`Func::new_unchecked`]-style function named in this linker.
429     ///
430     /// For more information see [`Linker::func_wrap`].
431     ///
432     /// # Panics
433     ///
434     /// Panics if the given function type is not associated with the same engine
435     /// as this linker.
436     ///
437     /// # Safety
438     ///
439     /// See [`Func::new_unchecked`] for more safety information.
440     pub unsafe fn func_new_unchecked(
441         &mut self,
442         module: &str,
443         name: &str,
444         ty: FuncType,
445         func: impl Fn(Caller<'_, T>, &mut [MaybeUninit<ValRaw>]) -> Result<()> + Send + Sync + 'static,
446     ) -> Result<&mut Self>
447     where
448         T: 'static,
449     {
450         // SAFETY: the contract of this function is the same as `new_unchecked`.
451         let func = unsafe { HostFunc::new_unchecked(&self.engine, ty, func)? };
452         self.func_insert(module, name, func)
453     }
454 
455     /// Creates a [`Func::new_async`]-style function named in this linker.
456     ///
457     /// For more information see [`Linker::func_wrap`].
458     ///
459     /// # Panics
460     ///
461     /// This method panics in the following situations:
462     ///
463     /// * If the given function type is not associated with the same engine as
464     ///   this linker.
465     #[cfg(feature = "async")]
466     pub fn func_new_async<F>(
467         &mut self,
468         module: &str,
469         name: &str,
470         ty: FuncType,
471         func: F,
472     ) -> Result<&mut Self>
473     where
474         F: for<'a> Fn(
475                 Caller<'a, T>,
476                 &'a [Val],
477                 &'a mut [Val],
478             ) -> Box<dyn Future<Output = Result<()>> + Send + 'a>
479             + Send
480             + Sync
481             + 'static,
482         T: Send + 'static,
483     {
484         self.func_insert(module, name, HostFunc::new_async(&self.engine, ty, func)?)
485     }
486 
487     /// Define a host function within this linker.
488     ///
489     /// For information about how the host function operates, see
490     /// [`Func::wrap`]. That includes information about translating Rust types
491     /// to WebAssembly native types.
492     ///
493     /// This method creates a host-provided function in this linker under the
494     /// provided name. This method is distinct in its capability to create a
495     /// [`Store`](crate::Store)-independent function. This means that the
496     /// function defined here can be used to instantiate instances in multiple
497     /// different stores, or in other words the function can be loaded into
498     /// different stores.
499     ///
500     /// Note that the capability mentioned here applies to all other
501     /// host-function-defining-methods on [`Linker`] as well. All of them can be
502     /// used to create instances of [`Func`] within multiple stores. In a
503     /// multithreaded program, for example, this means that the host functions
504     /// could be called concurrently if different stores are executing on
505     /// different threads.
506     ///
507     /// # Errors
508     ///
509     /// Returns an error if the `module` and `name` already identify an item
510     /// of the same type as the `item` provided and if shadowing is disallowed.
511     /// For more information see the documentation on [`Linker`].
512     ///
513     /// # Examples
514     ///
515     /// ```
516     /// # use wasmtime::*;
517     /// # fn main() -> Result<()> {
518     /// # let engine = Engine::default();
519     /// let mut linker = Linker::new(&engine);
520     /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
521     /// linker.func_wrap("host", "log_i32", |x: i32| println!("{}", x))?;
522     /// linker.func_wrap("host", "log_str", |caller: Caller<'_, ()>, ptr: i32, len: i32| {
523     ///     // ...
524     /// })?;
525     ///
526     /// let wat = r#"
527     ///     (module
528     ///         (import "host" "double" (func (param i32) (result i32)))
529     ///         (import "host" "log_i32" (func (param i32)))
530     ///         (import "host" "log_str" (func (param i32 i32)))
531     ///     )
532     /// "#;
533     /// let module = Module::new(&engine, wat)?;
534     ///
535     /// // instantiate in multiple different stores
536     /// for _ in 0..10 {
537     ///     let mut store = Store::new(&engine, ());
538     ///     linker.instantiate(&mut store, &module)?;
539     /// }
540     /// # Ok(())
541     /// # }
542     /// ```
543     pub fn func_wrap<Params, Args>(
544         &mut self,
545         module: &str,
546         name: &str,
547         func: impl IntoFunc<T, Params, Args>,
548     ) -> Result<&mut Self>
549     where
550         T: 'static,
551     {
552         self.func_insert(module, name, func.into_func(&self.engine)?)
553     }
554 
555     /// Asynchronous analog of [`Linker::func_wrap`].
556     #[cfg(feature = "async")]
557     pub fn func_wrap_async<F, Params: crate::WasmTyList, Args: crate::WasmRet>(
558         &mut self,
559         module: &str,
560         name: &str,
561         func: F,
562     ) -> Result<&mut Self>
563     where
564         F: for<'a> Fn(Caller<'a, T>, Params) -> Box<dyn Future<Output = Args> + Send + 'a>
565             + Send
566             + Sync
567             + 'static,
568         T: Send + 'static,
569     {
570         self.func_insert(module, name, HostFunc::wrap_async(&self.engine, func)?)
571     }
572 
573     /// Convenience wrapper to define an entire [`Instance`] in this linker.
574     ///
575     /// This function is a convenience wrapper around [`Linker::define`] which
576     /// will define all exports on `instance` into this linker. The module name
577     /// for each export is `module_name`, and the name for each export is the
578     /// name in the instance itself.
579     ///
580     /// Note that when this API is used the [`Linker`] is no longer compatible
581     /// with multi-[`Store`][crate::Store] instantiation because the items
582     /// defined within this store will belong to the `store` provided, and only
583     /// the `store` provided.
584     ///
585     /// # Errors
586     ///
587     /// Returns an error if the any item is redefined twice in this linker (for
588     /// example the same `module_name` was already defined) and shadowing is
589     /// disallowed, or if `instance` comes from a different
590     /// [`Store`](crate::Store) than this [`Linker`] originally was created
591     /// with.
592     ///
593     /// # Panics
594     ///
595     /// Panics if `instance` does not belong to `store`.
596     ///
597     /// # Examples
598     ///
599     /// ```
600     /// # use wasmtime::*;
601     /// # fn main() -> Result<()> {
602     /// # let engine = Engine::default();
603     /// # let mut store = Store::new(&engine, ());
604     /// let mut linker = Linker::new(&engine);
605     ///
606     /// // Instantiate a small instance...
607     /// let wat = r#"(module (func (export "run") ))"#;
608     /// let module = Module::new(&engine, wat)?;
609     /// let instance = linker.instantiate(&mut store, &module)?;
610     ///
611     /// // ... and inform the linker that the name of this instance is
612     /// // `instance1`. This defines the `instance1::run` name for our next
613     /// // module to use.
614     /// linker.instance(&mut store, "instance1", instance)?;
615     ///
616     /// let wat = r#"
617     ///     (module
618     ///         (import "instance1" "run" (func $instance1_run))
619     ///         (func (export "run")
620     ///             call $instance1_run
621     ///         )
622     ///     )
623     /// "#;
624     /// let module = Module::new(&engine, wat)?;
625     /// let instance = linker.instantiate(&mut store, &module)?;
626     /// # Ok(())
627     /// # }
628     /// ```
629     pub fn instance(
630         &mut self,
631         mut store: impl AsContextMut<Data = T>,
632         module_name: &str,
633         instance: Instance,
634     ) -> Result<&mut Self>
635     where
636         T: 'static,
637     {
638         let mut store = store.as_context_mut();
639         let exports = instance
640             .exports(&mut store)
641             .map(|e| {
642                 Ok((
643                     self.import_key(module_name, Some(e.name()))?,
644                     e.into_extern(),
645                 ))
646             })
647             .collect::<Result<Vec<_>>>()?;
648         for (key, export) in exports {
649             self.insert(key, Definition::new(store.0, export))?;
650         }
651         Ok(self)
652     }
653 
654     /// Define automatic instantiations of a [`Module`] in this linker.
655     ///
656     /// This automatically handles [Commands and Reactors] instantiation and
657     /// initialization.
658     ///
659     /// Exported functions of a Command module may be called directly, however
660     /// instead of having a single instance which is reused for each call,
661     /// each call creates a new instance, which lives for the duration of the
662     /// call. The imports of the Command are resolved once, and reused for
663     /// each instantiation, so all dependencies need to be present at the time
664     /// when `Linker::module` is called.
665     ///
666     /// For Reactors, a single instance is created, and an initialization
667     /// function is called, and then its exports may be called.
668     ///
669     /// Ordinary modules which don't declare themselves to be either Commands
670     /// or Reactors are treated as Reactors without any initialization calls.
671     ///
672     /// [Commands and Reactors]: https://github.com/WebAssembly/WASI/blob/main/legacy/application-abi.md#current-unstable-abi
673     ///
674     /// # Errors
675     ///
676     /// Returns an error if the any item is redefined twice in this linker (for
677     /// example the same `module_name` was already defined) and shadowing is
678     /// disallowed, if `instance` comes from a different
679     /// [`Store`](crate::Store) than this [`Linker`] originally was created
680     /// with, or if a Reactor initialization function traps.
681     ///
682     /// # Panics
683     ///
684     /// Panics if any item used to instantiate the provided [`Module`] is not
685     /// owned by `store`, or if the `store` provided comes from a different
686     /// [`Engine`] than this [`Linker`].
687     ///
688     /// # Examples
689     ///
690     /// ```
691     /// # use wasmtime::*;
692     /// # fn main() -> Result<()> {
693     /// # let engine = Engine::default();
694     /// # let mut store = Store::new(&engine, ());
695     /// let mut linker = Linker::new(&engine);
696     ///
697     /// // Instantiate a small instance and inform the linker that the name of
698     /// // this instance is `instance1`. This defines the `instance1::run` name
699     /// // for our next module to use.
700     /// let wat = r#"(module (func (export "run") ))"#;
701     /// let module = Module::new(&engine, wat)?;
702     /// linker.module(&mut store, "instance1", &module)?;
703     ///
704     /// let wat = r#"
705     ///     (module
706     ///         (import "instance1" "run" (func $instance1_run))
707     ///         (func (export "run")
708     ///             call $instance1_run
709     ///         )
710     ///     )
711     /// "#;
712     /// let module = Module::new(&engine, wat)?;
713     /// let instance = linker.instantiate(&mut store, &module)?;
714     /// # Ok(())
715     /// # }
716     /// ```
717     ///
718     /// For a Command, a new instance is created for each call.
719     ///
720     /// ```
721     /// # use wasmtime::*;
722     /// # fn main() -> Result<()> {
723     /// # let engine = Engine::default();
724     /// # let mut store = Store::new(&engine, ());
725     /// let mut linker = Linker::new(&engine);
726     ///
727     /// // Create a Command that attempts to count the number of times it is run, but is
728     /// // foiled by each call getting a new instance.
729     /// let wat = r#"
730     ///     (module
731     ///         (global $counter (mut i32) (i32.const 0))
732     ///         (func (export "_start")
733     ///             (global.set $counter (i32.add (global.get $counter) (i32.const 1)))
734     ///         )
735     ///         (func (export "read_counter") (result i32)
736     ///             (global.get $counter)
737     ///         )
738     ///     )
739     /// "#;
740     /// let module = Module::new(&engine, wat)?;
741     /// linker.module(&mut store, "commander", &module)?;
742     /// let run = linker.get_default(&mut store, "")?
743     ///     .typed::<(), ()>(&store)?
744     ///     .clone();
745     /// run.call(&mut store, ())?;
746     /// run.call(&mut store, ())?;
747     /// run.call(&mut store, ())?;
748     ///
749     /// let wat = r#"
750     ///     (module
751     ///         (import "commander" "_start" (func $commander_start))
752     ///         (import "commander" "read_counter" (func $commander_read_counter (result i32)))
753     ///         (func (export "run") (result i32)
754     ///             call $commander_start
755     ///             call $commander_start
756     ///             call $commander_start
757     ///             call $commander_read_counter
758     ///         )
759     ///     )
760     /// "#;
761     /// let module = Module::new(&engine, wat)?;
762     /// linker.module(&mut store, "", &module)?;
763     /// let run = linker.get(&mut store, "", "run").unwrap().into_func().unwrap();
764     /// let count = run.typed::<(), i32>(&store)?.call(&mut store, ())?;
765     /// assert_eq!(count, 0, "a Command should get a fresh instance on each invocation");
766     ///
767     /// # Ok(())
768     /// # }
769     /// ```
770     pub fn module(
771         &mut self,
772         mut store: impl AsContextMut<Data = T>,
773         module_name: &str,
774         module: &Module,
775     ) -> Result<&mut Self>
776     where
777         T: 'static,
778     {
779         // NB: this is intended to function the same as `Linker::module_async`,
780         // they should be kept in sync.
781 
782         // This assert isn't strictly necessary since it'll bottom out in the
783         // `HostFunc::to_func` method anyway. This is placed earlier for this
784         // function though to prevent the functions created here from delaying
785         // the panic until they're called.
786         assert!(
787             Engine::same(&self.engine, store.as_context().engine()),
788             "different engines for this linker and the store provided"
789         );
790         match ModuleKind::categorize(module)? {
791             ModuleKind::Command => {
792                 self.command(
793                     store,
794                     module_name,
795                     module,
796                     |store, func_ty, export_name, instance_pre| {
797                         Func::new(
798                             store,
799                             func_ty.clone(),
800                             move |mut caller, params, results| {
801                                 // Create a new instance for this command execution.
802                                 let instance = instance_pre.instantiate(&mut caller)?;
803 
804                                 // `unwrap()` everything here because we know the instance contains a
805                                 // function export with the given name and signature because we're
806                                 // iterating over the module it was instantiated from.
807                                 instance
808                                     .get_export(&mut caller, &export_name)
809                                     .unwrap()
810                                     .into_func()
811                                     .unwrap()
812                                     .call(&mut caller, params, results)?;
813 
814                                 Ok(())
815                             },
816                         )
817                     },
818                 )
819             }
820             ModuleKind::Reactor => {
821                 let instance = self.instantiate(&mut store, &module)?;
822 
823                 if let Some(export) = instance.get_export(&mut store, "_initialize") {
824                     if let Extern::Func(func) = export {
825                         func.typed::<(), ()>(&store)
826                             .and_then(|f| f.call(&mut store, ()))
827                             .context("calling the Reactor initialization function")?;
828                     }
829                 }
830 
831                 self.instance(store, module_name, instance)
832             }
833         }
834     }
835 
836     /// Define automatic instantiations of a [`Module`] in this linker.
837     ///
838     /// This is the same as [`Linker::module`], except for async `Store`s.
839     #[cfg(feature = "async")]
840     pub async fn module_async(
841         &mut self,
842         mut store: impl AsContextMut<Data = T>,
843         module_name: &str,
844         module: &Module,
845     ) -> Result<&mut Self>
846     where
847         T: Send + 'static,
848     {
849         // NB: this is intended to function the same as `Linker::module`, they
850         // should be kept in sync.
851         assert!(
852             Engine::same(&self.engine, store.as_context().engine()),
853             "different engines for this linker and the store provided"
854         );
855         match ModuleKind::categorize(module)? {
856             ModuleKind::Command => self.command(
857                 store,
858                 module_name,
859                 module,
860                 |store, func_ty, export_name, instance_pre| {
861                     let upvars = Arc::new((instance_pre, export_name));
862                     Func::new_async(
863                         store,
864                         func_ty.clone(),
865                         move |mut caller, params, results| {
866                             let upvars = upvars.clone();
867                             Box::new(async move {
868                                 let (instance_pre, export_name) = &*upvars;
869                                 let instance = instance_pre.instantiate_async(&mut caller).await?;
870 
871                                 instance
872                                     .get_export(&mut caller, &export_name)
873                                     .unwrap()
874                                     .into_func()
875                                     .unwrap()
876                                     .call_async(&mut caller, params, results)
877                                     .await?;
878                                 Ok(())
879                             })
880                         },
881                     )
882                 },
883             ),
884             ModuleKind::Reactor => {
885                 let instance = self.instantiate_async(&mut store, &module).await?;
886 
887                 if let Some(export) = instance.get_export(&mut store, "_initialize") {
888                     if let Extern::Func(func) = export {
889                         let func = func
890                             .typed::<(), ()>(&store)
891                             .context("loading the Reactor initialization function")?;
892                         func.call_async(&mut store, ())
893                             .await
894                             .context("calling the Reactor initialization function")?;
895                     }
896                 }
897 
898                 self.instance(store, module_name, instance)
899             }
900         }
901     }
902 
903     fn command(
904         &mut self,
905         mut store: impl AsContextMut<Data = T>,
906         module_name: &str,
907         module: &Module,
908         mk_func: impl Fn(&mut StoreContextMut<T>, &FuncType, String, InstancePre<T>) -> Func,
909     ) -> Result<&mut Self>
910     where
911         T: 'static,
912     {
913         let mut store = store.as_context_mut();
914         for export in module.exports() {
915             if let Some(func_ty) = export.ty().func() {
916                 let instance_pre = self.instantiate_pre(module)?;
917                 let export_name = export.name().to_owned();
918                 let func = mk_func(&mut store, func_ty, export_name, instance_pre);
919                 let key = self.import_key(module_name, Some(export.name()))?;
920                 self.insert(key, Definition::new(store.0, func.into()))?;
921             } else if export.name() == "memory" && export.ty().memory().is_some() {
922                 // Allow an exported "memory" memory for now.
923             } else if export.name() == "__indirect_function_table" && export.ty().table().is_some()
924             {
925                 // Allow an exported "__indirect_function_table" table for now.
926             } else if export.name() == "table" && export.ty().table().is_some() {
927                 // Allow an exported "table" table for now.
928             } else if export.name() == "__data_end" && export.ty().global().is_some() {
929                 // Allow an exported "__data_end" memory for compatibility with toolchains
930                 // which use --export-dynamic, which unfortunately doesn't work the way
931                 // we want it to.
932                 warn!("command module exporting '__data_end' is deprecated");
933             } else if export.name() == "__heap_base" && export.ty().global().is_some() {
934                 // Allow an exported "__data_end" memory for compatibility with toolchains
935                 // which use --export-dynamic, which unfortunately doesn't work the way
936                 // we want it to.
937                 warn!("command module exporting '__heap_base' is deprecated");
938             } else if export.name() == "__dso_handle" && export.ty().global().is_some() {
939                 // Allow an exported "__dso_handle" memory for compatibility with toolchains
940                 // which use --export-dynamic, which unfortunately doesn't work the way
941                 // we want it to.
942                 warn!("command module exporting '__dso_handle' is deprecated")
943             } else if export.name() == "__rtti_base" && export.ty().global().is_some() {
944                 // Allow an exported "__rtti_base" memory for compatibility with
945                 // AssemblyScript.
946                 warn!(
947                     "command module exporting '__rtti_base' is deprecated; pass `--runtime half` to the AssemblyScript compiler"
948                 );
949             } else if !self.allow_unknown_exports {
950                 bail!("command export '{}' is not a function", export.name());
951             }
952         }
953 
954         Ok(self)
955     }
956 
957     /// Aliases one item's name as another.
958     ///
959     /// This method will alias an item with the specified `module` and `name`
960     /// under a new name of `as_module` and `as_name`.
961     ///
962     /// # Errors
963     ///
964     /// Returns an error if any shadowing violations happen while defining new
965     /// items, or if the original item wasn't defined.
966     pub fn alias(
967         &mut self,
968         module: &str,
969         name: &str,
970         as_module: &str,
971         as_name: &str,
972     ) -> Result<&mut Self> {
973         let src = self.import_key(module, Some(name))?;
974         let dst = self.import_key(as_module, Some(as_name))?;
975         match self.map.get(&src).cloned() {
976             Some(item) => self.insert(dst, item)?,
977             None => bail!("no item named `{module}::{name}` defined"),
978         }
979         Ok(self)
980     }
981 
982     /// Aliases one module's name as another.
983     ///
984     /// This method will alias all currently defined under `module` to also be
985     /// defined under the name `as_module` too.
986     ///
987     /// # Errors
988     ///
989     /// Returns an error if any shadowing violations happen while defining new
990     /// items.
991     pub fn alias_module(&mut self, module: &str, as_module: &str) -> Result<()> {
992         let module = self.pool.insert(module)?;
993         let as_module = self.pool.insert(as_module)?;
994         let items = self
995             .map
996             .iter()
997             .filter(|(key, _def)| key.module == module)
998             .map(|(key, def)| (key.name, def.clone()))
999             .collect::<Vec<_>>();
1000         for (name, item) in items {
1001             self.insert(
1002                 ImportKey {
1003                     module: as_module,
1004                     name,
1005                 },
1006                 item,
1007             )?;
1008         }
1009         Ok(())
1010     }
1011 
1012     fn insert(&mut self, key: ImportKey, item: Definition) -> Result<()> {
1013         if !self.allow_shadowing && self.map.contains_key(&key) {
1014             let module = &self.pool[key.module];
1015             match key.name.and_then(|n| self.pool.get(n)) {
1016                 Some(name) => bail!("import of `{module}::{name}` defined twice"),
1017                 None => bail!("import of `{module}` defined twice"),
1018             }
1019         }
1020 
1021         self.map.insert(key, item)?;
1022         Ok(())
1023     }
1024 
1025     fn import_key(&mut self, module: &str, name: Option<&str>) -> Result<ImportKey, OutOfMemory> {
1026         Ok(ImportKey {
1027             module: self.pool.insert(module)?,
1028             name: name.map(|name| self.pool.insert(name)).transpose()?,
1029         })
1030     }
1031 
1032     /// Attempts to instantiate the `module` provided.
1033     ///
1034     /// This method will attempt to assemble a list of imports that correspond
1035     /// to the imports required by the [`Module`] provided. This list
1036     /// of imports is then passed to [`Instance::new`] to continue the
1037     /// instantiation process.
1038     ///
1039     /// Each import of `module` will be looked up in this [`Linker`] and must
1040     /// have previously been defined. If it was previously defined with an
1041     /// incorrect signature or if it was not previously defined then an error
1042     /// will be returned because the import can not be satisfied.
1043     ///
1044     /// Per the WebAssembly spec, instantiation includes running the module's
1045     /// start function, if it has one (not to be confused with the `_start`
1046     /// function, which is not run).
1047     ///
1048     /// # Errors
1049     ///
1050     /// This method can fail because an import may not be found, or because
1051     /// instantiation itself may fail. For information on instantiation
1052     /// failures see [`Instance::new`]. If an import is not found, the error
1053     /// may be downcast to an [`UnknownImportError`].
1054     ///
1055     ///
1056     /// # Panics
1057     ///
1058     /// Panics if any item used to instantiate `module` is not owned by
1059     /// `store`. Additionally this will panic if the [`Engine`] that the `store`
1060     /// belongs to is different than this [`Linker`].
1061     ///
1062     /// # Examples
1063     ///
1064     /// ```
1065     /// # use wasmtime::*;
1066     /// # fn main() -> Result<()> {
1067     /// # let engine = Engine::default();
1068     /// # let mut store = Store::new(&engine, ());
1069     /// let mut linker = Linker::new(&engine);
1070     /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
1071     ///
1072     /// let wat = r#"
1073     ///     (module
1074     ///         (import "host" "double" (func (param i32) (result i32)))
1075     ///     )
1076     /// "#;
1077     /// let module = Module::new(&engine, wat)?;
1078     /// linker.instantiate(&mut store, &module)?;
1079     /// # Ok(())
1080     /// # }
1081     /// ```
1082     pub fn instantiate(
1083         &self,
1084         mut store: impl AsContextMut<Data = T>,
1085         module: &Module,
1086     ) -> Result<Instance>
1087     where
1088         T: 'static,
1089     {
1090         self._instantiate_pre(module, Some(store.as_context_mut().0))?
1091             .instantiate(store)
1092     }
1093 
1094     /// Attempts to instantiate the `module` provided. This is the same as
1095     /// [`Linker::instantiate`], except for async `Store`s.
1096     #[cfg(feature = "async")]
1097     pub async fn instantiate_async(
1098         &self,
1099         mut store: impl AsContextMut<Data = T>,
1100         module: &Module,
1101     ) -> Result<Instance>
1102     where
1103         T: Send + 'static,
1104     {
1105         self._instantiate_pre(module, Some(store.as_context_mut().0))?
1106             .instantiate_async(store)
1107             .await
1108     }
1109 
1110     /// Performs all checks necessary for instantiating `module` with this
1111     /// linker, except that instantiation doesn't actually finish.
1112     ///
1113     /// This method is used for front-loading type-checking information as well
1114     /// as collecting the imports to use to instantiate a module with. The
1115     /// returned [`InstancePre`] represents a ready-to-be-instantiated module,
1116     /// which can also be instantiated multiple times if desired.
1117     ///
1118     /// # Errors
1119     ///
1120     /// Returns an error which may be downcast to an [`UnknownImportError`] if
1121     /// the module has any unresolvable imports.
1122     ///
1123     /// # Examples
1124     ///
1125     /// ```
1126     /// # use wasmtime::*;
1127     /// # fn main() -> Result<()> {
1128     /// # let engine = Engine::default();
1129     /// # let mut store = Store::new(&engine, ());
1130     /// let mut linker = Linker::new(&engine);
1131     /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
1132     ///
1133     /// let wat = r#"
1134     ///     (module
1135     ///         (import "host" "double" (func (param i32) (result i32)))
1136     ///     )
1137     /// "#;
1138     /// let module = Module::new(&engine, wat)?;
1139     /// let instance_pre = linker.instantiate_pre(&module)?;
1140     ///
1141     /// // Finish instantiation after the type-checking has all completed...
1142     /// let instance = instance_pre.instantiate(&mut store)?;
1143     ///
1144     /// // ... and we can even continue to keep instantiating if desired!
1145     /// instance_pre.instantiate(&mut store)?;
1146     /// instance_pre.instantiate(&mut store)?;
1147     ///
1148     /// // Note that functions defined in a linker with `func_wrap` and similar
1149     /// // constructors are not owned by any particular `Store`, so we can also
1150     /// // instantiate our `instance_pre` in other stores because no imports
1151     /// // belong to the original store.
1152     /// let mut new_store = Store::new(&engine, ());
1153     /// instance_pre.instantiate(&mut new_store)?;
1154     /// # Ok(())
1155     /// # }
1156     /// ```
1157     pub fn instantiate_pre(&self, module: &Module) -> Result<InstancePre<T>>
1158     where
1159         T: 'static,
1160     {
1161         self._instantiate_pre(module, None)
1162     }
1163 
1164     /// This is split out to optionally take a `store` so that when the
1165     /// `.instantiate` API is used we can get fresh up-to-date type information
1166     /// for memories and their current size, if necessary.
1167     ///
1168     /// Note that providing a `store` here is not required for correctness
1169     /// per-se. If one is not provided, such as the with the `instantiate_pre`
1170     /// API, then the type information used for memories and tables will reflect
1171     /// their size when inserted into the linker rather than their current size.
1172     /// This isn't expected to be much of a problem though since
1173     /// per-store-`Linker` types are likely using `.instantiate(..)` and
1174     /// per-`Engine` linkers don't have memories/tables in them.
1175     fn _instantiate_pre(
1176         &self,
1177         module: &Module,
1178         store: Option<&StoreOpaque>,
1179     ) -> Result<InstancePre<T>>
1180     where
1181         T: 'static,
1182     {
1183         let mut imports = module
1184             .imports()
1185             .map(|import| self._get_by_import(&import))
1186             .collect::<Result<Vec<_>, _>>()?;
1187         if let Some(store) = store {
1188             for import in imports.iter_mut() {
1189                 import.update_size(store);
1190             }
1191         }
1192         unsafe { InstancePre::new(module, imports) }
1193     }
1194 
1195     /// Returns an iterator over all items defined in this `Linker`, in
1196     /// arbitrary order.
1197     ///
1198     /// The iterator returned will yield 3-tuples where the first two elements
1199     /// are the module name and item name for the external item, and the third
1200     /// item is the item itself that is defined.
1201     ///
1202     /// Note that multiple `Extern` items may be defined for the same
1203     /// module/name pair.
1204     ///
1205     /// # Panics
1206     ///
1207     /// This function will panic if the `store` provided does not come from the
1208     /// same [`Engine`] that this linker was created with.
1209     pub fn iter<'a: 'p, 'p>(
1210         &'a self,
1211         mut store: impl AsContextMut<Data = T> + 'p,
1212     ) -> impl Iterator<Item = (&'a str, &'a str, Extern)> + 'p
1213     where
1214         T: 'static,
1215     {
1216         self.map.iter().map(move |(key, item)| {
1217             let store = store.as_context_mut();
1218             (
1219                 &self.pool[key.module],
1220                 &self.pool[key.name.unwrap()],
1221                 // Should be safe since `T` is connecting the linker and store
1222                 unsafe { item.to_extern(store.0) },
1223             )
1224         })
1225     }
1226 
1227     /// Looks up a previously defined value in this [`Linker`], identified by
1228     /// the names provided.
1229     ///
1230     /// Returns `None` if this name was not previously defined in this
1231     /// [`Linker`].
1232     ///
1233     /// # Panics
1234     ///
1235     /// This function will panic if the `store` provided does not come from the
1236     /// same [`Engine`] that this linker was created with.
1237     pub fn get(
1238         &self,
1239         mut store: impl AsContextMut<Data = T>,
1240         module: &str,
1241         name: &str,
1242     ) -> Option<Extern>
1243     where
1244         T: 'static,
1245     {
1246         let store = store.as_context_mut().0;
1247         // Should be safe since `T` is connecting the linker and store
1248         Some(unsafe { self._get(module, name)?.to_extern(store) })
1249     }
1250 
1251     fn _get(&self, module: &str, name: &str) -> Option<&Definition> {
1252         let key = ImportKey {
1253             module: self.pool.get_atom(module)?,
1254             name: Some(self.pool.get_atom(name)?),
1255         };
1256         self.map.get(&key)
1257     }
1258 
1259     /// Looks up a value in this `Linker` which matches the `import` type
1260     /// provided.
1261     ///
1262     /// Returns `None` if no match was found.
1263     ///
1264     /// # Panics
1265     ///
1266     /// This function will panic if the `store` provided does not come from the
1267     /// same [`Engine`] that this linker was created with.
1268     pub fn get_by_import(
1269         &self,
1270         mut store: impl AsContextMut<Data = T>,
1271         import: &ImportType,
1272     ) -> Option<Extern>
1273     where
1274         T: 'static,
1275     {
1276         let store = store.as_context_mut().0;
1277         // Should be safe since `T` is connecting the linker and store
1278         Some(unsafe { self._get_by_import(import).ok()?.to_extern(store) })
1279     }
1280 
1281     fn _get_by_import(&self, import: &ImportType) -> Result<Definition, UnknownImportError> {
1282         match self._get(import.module(), import.name()) {
1283             Some(item) => Ok(item.clone()),
1284             None => Err(UnknownImportError::new(import)),
1285         }
1286     }
1287 
1288     /// Returns the "default export" of a module.
1289     ///
1290     /// An export with an empty string is considered to be a "default export".
1291     /// "_start" is also recognized for compatibility.
1292     ///
1293     /// # Panics
1294     ///
1295     /// Panics if the default function found is not owned by `store`. This
1296     /// function will also panic if the `store` provided does not come from the
1297     /// same [`Engine`] that this linker was created with.
1298     pub fn get_default(&self, mut store: impl AsContextMut<Data = T>, module: &str) -> Result<Func>
1299     where
1300         T: 'static,
1301     {
1302         if let Some(external) = self.get(&mut store, module, "") {
1303             if let Extern::Func(func) = external {
1304                 return Ok(func);
1305             }
1306             bail!("default export in '{module}' is not a function");
1307         }
1308 
1309         // For compatibility, also recognize "_start".
1310         if let Some(external) = self.get(&mut store, module, "_start") {
1311             if let Extern::Func(func) = external {
1312                 return Ok(func);
1313             }
1314             bail!("`_start` in '{module}' is not a function");
1315         }
1316 
1317         // Otherwise return a no-op function.
1318         Ok(Func::wrap(store, || {}))
1319     }
1320 }
1321 
1322 impl<T: 'static> Default for Linker<T> {
1323     fn default() -> Linker<T> {
1324         Linker::new(&Engine::default())
1325     }
1326 }
1327 
1328 impl Definition {
1329     fn new(store: &StoreOpaque, item: Extern) -> Definition {
1330         let ty = DefinitionType::from(store, &item);
1331         Definition::Extern(item, ty)
1332     }
1333 
1334     pub(crate) fn ty(&self) -> DefinitionType {
1335         match self {
1336             Definition::Extern(_, ty) => *ty,
1337             Definition::HostFunc(func) => DefinitionType::Func(func.sig_index()),
1338         }
1339     }
1340 
1341     /// Inserts this definition into the `store` provided.
1342     ///
1343     /// # Safety
1344     ///
1345     /// Note the unsafety here is due to calling `HostFunc::to_func`. The
1346     /// requirement here is that the `T` that was originally used to create the
1347     /// `HostFunc` matches the `T` on the store.
1348     pub(crate) unsafe fn to_extern(&self, store: &mut StoreOpaque) -> Extern {
1349         match self {
1350             Definition::Extern(e, _) => e.clone(),
1351             // SAFETY: the contract of this function is the same as what's
1352             // required of `to_func`, that `T` of the store matches the `T` of
1353             // this original definition.
1354             Definition::HostFunc(func) => unsafe { func.to_func(store).into() },
1355         }
1356     }
1357 
1358     pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque) -> bool {
1359         match self {
1360             Definition::Extern(e, _) => e.comes_from_same_store(store),
1361             Definition::HostFunc(_func) => true,
1362         }
1363     }
1364 
1365     fn update_size(&mut self, store: &StoreOpaque) {
1366         match self {
1367             Definition::Extern(Extern::Memory(m), DefinitionType::Memory(_, size)) => {
1368                 *size = m.internal_size(store);
1369             }
1370             Definition::Extern(Extern::SharedMemory(m), DefinitionType::Memory(_, size)) => {
1371                 *size = m.size();
1372             }
1373             Definition::Extern(Extern::Table(m), DefinitionType::Table(_, size)) => {
1374                 *size = m._size(store);
1375             }
1376             _ => {}
1377         }
1378     }
1379 }
1380 
1381 impl DefinitionType {
1382     pub(crate) fn from(store: &StoreOpaque, item: &Extern) -> DefinitionType {
1383         match item {
1384             Extern::Func(f) => DefinitionType::Func(f.type_index(store)),
1385             Extern::Table(t) => DefinitionType::Table(*t.wasmtime_ty(store), t._size(store)),
1386             Extern::Global(t) => DefinitionType::Global(*t.wasmtime_ty(store)),
1387             Extern::Memory(t) => {
1388                 DefinitionType::Memory(*t.wasmtime_ty(store), t.internal_size(store))
1389             }
1390             Extern::SharedMemory(t) => DefinitionType::Memory(*t.ty().wasmtime_memory(), t.size()),
1391             Extern::Tag(t) => DefinitionType::Tag(*t.wasmtime_ty(store)),
1392         }
1393     }
1394 
1395     pub(crate) fn desc(&self) -> &'static str {
1396         match self {
1397             DefinitionType::Func(_) => "function",
1398             DefinitionType::Table(..) => "table",
1399             DefinitionType::Memory(..) => "memory",
1400             DefinitionType::Global(_) => "global",
1401             DefinitionType::Tag(_) => "tag",
1402         }
1403     }
1404 }
1405 
1406 /// Modules can be interpreted either as Commands or Reactors.
1407 enum ModuleKind {
1408     /// The instance is a Command, meaning an instance is created for each
1409     /// exported function and lives for the duration of the function call.
1410     Command,
1411 
1412     /// The instance is a Reactor, meaning one instance is created which
1413     /// may live across multiple calls.
1414     Reactor,
1415 }
1416 
1417 impl ModuleKind {
1418     /// Determine whether the given module is a Command or a Reactor.
1419     fn categorize(module: &Module) -> Result<ModuleKind> {
1420         let command_start = module.get_export("_start");
1421         let reactor_start = module.get_export("_initialize");
1422         match (command_start, reactor_start) {
1423             (Some(command_start), None) => {
1424                 if let Some(_) = command_start.func() {
1425                     Ok(ModuleKind::Command)
1426                 } else {
1427                     bail!("`_start` must be a function")
1428                 }
1429             }
1430             (None, Some(reactor_start)) => {
1431                 if let Some(_) = reactor_start.func() {
1432                     Ok(ModuleKind::Reactor)
1433                 } else {
1434                     bail!("`_initialize` must be a function")
1435                 }
1436             }
1437             (None, None) => {
1438                 // Module declares neither of the recognized functions, so treat
1439                 // it as a reactor with no initialization function.
1440                 Ok(ModuleKind::Reactor)
1441             }
1442             (Some(_), Some(_)) => {
1443                 // Module declares itself to be both a Command and a Reactor.
1444                 bail!("Program cannot be both a Command and a Reactor")
1445             }
1446         }
1447     }
1448 }
1449 
1450 /// Error for an unresolvable import.
1451 ///
1452 /// Returned - wrapped in an [`Error`][crate::Error] - by
1453 /// [`Linker::instantiate`] and related methods for modules with unresolvable
1454 /// imports.
1455 #[derive(Clone, Debug)]
1456 pub struct UnknownImportError {
1457     module: String,
1458     name: String,
1459     ty: ExternType,
1460 }
1461 
1462 impl UnknownImportError {
1463     fn new(import: &ImportType) -> Self {
1464         Self {
1465             module: import.module().to_string(),
1466             name: import.name().to_string(),
1467             ty: import.ty(),
1468         }
1469     }
1470 
1471     /// Returns the module name that the unknown import was expected to come from.
1472     pub fn module(&self) -> &str {
1473         &self.module
1474     }
1475 
1476     /// Returns the field name of the module that the unknown import was expected to come from.
1477     pub fn name(&self) -> &str {
1478         &self.name
1479     }
1480 
1481     /// Returns the type of the unknown import.
1482     pub fn ty(&self) -> ExternType {
1483         self.ty.clone()
1484     }
1485 }
1486 
1487 impl fmt::Display for UnknownImportError {
1488     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1489         write!(
1490             f,
1491             "unknown import: `{}::{}` has not been defined",
1492             self.module, self.name,
1493         )
1494     }
1495 }
1496 
1497 impl core::error::Error for UnknownImportError {}
1498