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