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     ///
420     /// # Safety
421     ///
422     /// See [`Func::new_unchecked`] for more safety information.
423     pub unsafe fn func_new_unchecked(
424         &mut self,
425         module: &str,
426         name: &str,
427         ty: FuncType,
428         func: impl Fn(Caller<'_, T>, &mut [ValRaw]) -> Result<()> + Send + Sync + 'static,
429     ) -> Result<&mut Self>
430     where
431         T: 'static,
432     {
433         assert!(ty.comes_from_same_engine(self.engine()));
434         // SAFETY: the contract of this function is the same as `new_unchecked`.
435         let func = unsafe { HostFunc::new_unchecked(&self.engine, ty, func) };
436         let key = self.import_key(module, Some(name));
437         self.insert(key, Definition::HostFunc(Arc::new(func)))?;
438         Ok(self)
439     }
440 
441     /// Creates a [`Func::new_async`]-style function named in this linker.
442     ///
443     /// For more information see [`Linker::func_wrap`].
444     ///
445     /// # Panics
446     ///
447     /// This method panics in the following situations:
448     ///
449     /// * This linker is not associated with an [async
450     ///   config](crate::Config::async_support).
451     ///
452     /// * If the given function type is not associated with the same engine as
453     ///   this linker.
454     #[cfg(all(feature = "async", feature = "cranelift"))]
455     pub fn func_new_async<F>(
456         &mut self,
457         module: &str,
458         name: &str,
459         ty: FuncType,
460         func: F,
461     ) -> Result<&mut Self>
462     where
463         F: for<'a> Fn(
464                 Caller<'a, T>,
465                 &'a [Val],
466                 &'a mut [Val],
467             ) -> Box<dyn Future<Output = Result<()>> + Send + 'a>
468             + Send
469             + Sync
470             + 'static,
471         T: 'static,
472     {
473         assert!(
474             self.engine.config().async_support,
475             "cannot use `func_new_async` without enabling async support in the config"
476         );
477         assert!(ty.comes_from_same_engine(self.engine()));
478         self.func_new(module, name, ty, move |caller, params, results| {
479             let instance = caller.caller();
480             caller.store.with_blocking(|store, cx| {
481                 let caller = Caller::new(store, instance);
482                 cx.block_on(core::pin::Pin::from(func(caller, params, results)))
483             })?
484         })
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() -> anyhow::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         let func = HostFunc::wrap(&self.engine, func);
553         let key = self.import_key(module, Some(name));
554         self.insert(key, Definition::HostFunc(Arc::new(func)))?;
555         Ok(self)
556     }
557 
558     /// Asynchronous analog of [`Linker::func_wrap`].
559     #[cfg(feature = "async")]
560     pub fn func_wrap_async<F, Params: crate::WasmTyList, Args: crate::WasmRet>(
561         &mut self,
562         module: &str,
563         name: &str,
564         func: F,
565     ) -> Result<&mut Self>
566     where
567         F: for<'a> Fn(Caller<'a, T>, Params) -> Box<dyn Future<Output = Args> + Send + 'a>
568             + Send
569             + Sync
570             + 'static,
571         T: 'static,
572     {
573         assert!(
574             self.engine.config().async_support,
575             "cannot use `func_wrap_async` without enabling async support on the config",
576         );
577         let func =
578             HostFunc::wrap_inner(&self.engine, move |caller: Caller<'_, T>, args: Params| {
579                 let instance = caller.caller();
580                 let result = caller.store.block_on(|store| {
581                     let caller = Caller::new(store, instance);
582                     func(caller, args).into()
583                 });
584                 match result {
585                     Ok(ret) => ret.into_fallible(),
586                     Err(e) => Args::fallible_from_error(e),
587                 }
588             });
589         let key = self.import_key(module, Some(name));
590         self.insert(key, Definition::HostFunc(Arc::new(func)))?;
591         Ok(self)
592     }
593 
594     /// Convenience wrapper to define an entire [`Instance`] in this linker.
595     ///
596     /// This function is a convenience wrapper around [`Linker::define`] which
597     /// will define all exports on `instance` into this linker. The module name
598     /// for each export is `module_name`, and the name for each export is the
599     /// name in the instance itself.
600     ///
601     /// Note that when this API is used the [`Linker`] is no longer compatible
602     /// with multi-[`Store`][crate::Store] instantiation because the items
603     /// defined within this store will belong to the `store` provided, and only
604     /// the `store` provided.
605     ///
606     /// # Errors
607     ///
608     /// Returns an error if the any item is redefined twice in this linker (for
609     /// example the same `module_name` was already defined) and shadowing is
610     /// disallowed, or if `instance` comes from a different
611     /// [`Store`](crate::Store) than this [`Linker`] originally was created
612     /// with.
613     ///
614     /// # Panics
615     ///
616     /// Panics if `instance` does not belong to `store`.
617     ///
618     /// # Examples
619     ///
620     /// ```
621     /// # use wasmtime::*;
622     /// # fn main() -> anyhow::Result<()> {
623     /// # let engine = Engine::default();
624     /// # let mut store = Store::new(&engine, ());
625     /// let mut linker = Linker::new(&engine);
626     ///
627     /// // Instantiate a small instance...
628     /// let wat = r#"(module (func (export "run") ))"#;
629     /// let module = Module::new(&engine, wat)?;
630     /// let instance = linker.instantiate(&mut store, &module)?;
631     ///
632     /// // ... and inform the linker that the name of this instance is
633     /// // `instance1`. This defines the `instance1::run` name for our next
634     /// // module to use.
635     /// linker.instance(&mut store, "instance1", instance)?;
636     ///
637     /// let wat = r#"
638     ///     (module
639     ///         (import "instance1" "run" (func $instance1_run))
640     ///         (func (export "run")
641     ///             call $instance1_run
642     ///         )
643     ///     )
644     /// "#;
645     /// let module = Module::new(&engine, wat)?;
646     /// let instance = linker.instantiate(&mut store, &module)?;
647     /// # Ok(())
648     /// # }
649     /// ```
650     pub fn instance(
651         &mut self,
652         mut store: impl AsContextMut<Data = T>,
653         module_name: &str,
654         instance: Instance,
655     ) -> Result<&mut Self>
656     where
657         T: 'static,
658     {
659         let mut store = store.as_context_mut();
660         let exports = instance
661             .exports(&mut store)
662             .map(|e| {
663                 (
664                     self.import_key(module_name, Some(e.name())),
665                     e.into_extern(),
666                 )
667             })
668             .collect::<Vec<_>>();
669         for (key, export) in exports {
670             self.insert(key, Definition::new(store.0, export))?;
671         }
672         Ok(self)
673     }
674 
675     /// Define automatic instantiations of a [`Module`] in this linker.
676     ///
677     /// This automatically handles [Commands and Reactors] instantiation and
678     /// initialization.
679     ///
680     /// Exported functions of a Command module may be called directly, however
681     /// instead of having a single instance which is reused for each call,
682     /// each call creates a new instance, which lives for the duration of the
683     /// call. The imports of the Command are resolved once, and reused for
684     /// each instantiation, so all dependencies need to be present at the time
685     /// when `Linker::module` is called.
686     ///
687     /// For Reactors, a single instance is created, and an initialization
688     /// function is called, and then its exports may be called.
689     ///
690     /// Ordinary modules which don't declare themselves to be either Commands
691     /// or Reactors are treated as Reactors without any initialization calls.
692     ///
693     /// [Commands and Reactors]: https://github.com/WebAssembly/WASI/blob/main/legacy/application-abi.md#current-unstable-abi
694     ///
695     /// # Errors
696     ///
697     /// Returns an error if the any item is redefined twice in this linker (for
698     /// example the same `module_name` was already defined) and shadowing is
699     /// disallowed, if `instance` comes from a different
700     /// [`Store`](crate::Store) than this [`Linker`] originally was created
701     /// with, or if a Reactor initialization function traps.
702     ///
703     /// # Panics
704     ///
705     /// Panics if any item used to instantiate the provided [`Module`] is not
706     /// owned by `store`, or if the `store` provided comes from a different
707     /// [`Engine`] than this [`Linker`].
708     ///
709     /// # Examples
710     ///
711     /// ```
712     /// # use wasmtime::*;
713     /// # fn main() -> anyhow::Result<()> {
714     /// # let engine = Engine::default();
715     /// # let mut store = Store::new(&engine, ());
716     /// let mut linker = Linker::new(&engine);
717     ///
718     /// // Instantiate a small instance and inform the linker that the name of
719     /// // this instance is `instance1`. This defines the `instance1::run` name
720     /// // for our next module to use.
721     /// let wat = r#"(module (func (export "run") ))"#;
722     /// let module = Module::new(&engine, wat)?;
723     /// linker.module(&mut store, "instance1", &module)?;
724     ///
725     /// let wat = r#"
726     ///     (module
727     ///         (import "instance1" "run" (func $instance1_run))
728     ///         (func (export "run")
729     ///             call $instance1_run
730     ///         )
731     ///     )
732     /// "#;
733     /// let module = Module::new(&engine, wat)?;
734     /// let instance = linker.instantiate(&mut store, &module)?;
735     /// # Ok(())
736     /// # }
737     /// ```
738     ///
739     /// For a Command, a new instance is created for each call.
740     ///
741     /// ```
742     /// # use wasmtime::*;
743     /// # fn main() -> anyhow::Result<()> {
744     /// # let engine = Engine::default();
745     /// # let mut store = Store::new(&engine, ());
746     /// let mut linker = Linker::new(&engine);
747     ///
748     /// // Create a Command that attempts to count the number of times it is run, but is
749     /// // foiled by each call getting a new instance.
750     /// let wat = r#"
751     ///     (module
752     ///         (global $counter (mut i32) (i32.const 0))
753     ///         (func (export "_start")
754     ///             (global.set $counter (i32.add (global.get $counter) (i32.const 1)))
755     ///         )
756     ///         (func (export "read_counter") (result i32)
757     ///             (global.get $counter)
758     ///         )
759     ///     )
760     /// "#;
761     /// let module = Module::new(&engine, wat)?;
762     /// linker.module(&mut store, "commander", &module)?;
763     /// let run = linker.get_default(&mut store, "")?
764     ///     .typed::<(), ()>(&store)?
765     ///     .clone();
766     /// run.call(&mut store, ())?;
767     /// run.call(&mut store, ())?;
768     /// run.call(&mut store, ())?;
769     ///
770     /// let wat = r#"
771     ///     (module
772     ///         (import "commander" "_start" (func $commander_start))
773     ///         (import "commander" "read_counter" (func $commander_read_counter (result i32)))
774     ///         (func (export "run") (result i32)
775     ///             call $commander_start
776     ///             call $commander_start
777     ///             call $commander_start
778     ///             call $commander_read_counter
779     ///         )
780     ///     )
781     /// "#;
782     /// let module = Module::new(&engine, wat)?;
783     /// linker.module(&mut store, "", &module)?;
784     /// let run = linker.get(&mut store, "", "run").unwrap().into_func().unwrap();
785     /// let count = run.typed::<(), i32>(&store)?.call(&mut store, ())?;
786     /// assert_eq!(count, 0, "a Command should get a fresh instance on each invocation");
787     ///
788     /// # Ok(())
789     /// # }
790     /// ```
791     pub fn module(
792         &mut self,
793         mut store: impl AsContextMut<Data = T>,
794         module_name: &str,
795         module: &Module,
796     ) -> Result<&mut Self>
797     where
798         T: 'static,
799     {
800         // NB: this is intended to function the same as `Linker::module_async`,
801         // they should be kept in sync.
802 
803         // This assert isn't strictly necessary since it'll bottom out in the
804         // `HostFunc::to_func` method anyway. This is placed earlier for this
805         // function though to prevent the functions created here from delaying
806         // the panic until they're called.
807         assert!(
808             Engine::same(&self.engine, store.as_context().engine()),
809             "different engines for this linker and the store provided"
810         );
811         match ModuleKind::categorize(module)? {
812             ModuleKind::Command => {
813                 self.command(
814                     store,
815                     module_name,
816                     module,
817                     |store, func_ty, export_name, instance_pre| {
818                         Func::new(
819                             store,
820                             func_ty.clone(),
821                             move |mut caller, params, results| {
822                                 // Create a new instance for this command execution.
823                                 let instance = instance_pre.instantiate(&mut caller)?;
824 
825                                 // `unwrap()` everything here because we know the instance contains a
826                                 // function export with the given name and signature because we're
827                                 // iterating over the module it was instantiated from.
828                                 instance
829                                     .get_export(&mut caller, &export_name)
830                                     .unwrap()
831                                     .into_func()
832                                     .unwrap()
833                                     .call(&mut caller, params, results)?;
834 
835                                 Ok(())
836                             },
837                         )
838                     },
839                 )
840             }
841             ModuleKind::Reactor => {
842                 let instance = self.instantiate(&mut store, &module)?;
843 
844                 if let Some(export) = instance.get_export(&mut store, "_initialize") {
845                     if let Extern::Func(func) = export {
846                         func.typed::<(), ()>(&store)
847                             .and_then(|f| f.call(&mut store, ()))
848                             .context("calling the Reactor initialization function")?;
849                     }
850                 }
851 
852                 self.instance(store, module_name, instance)
853             }
854         }
855     }
856 
857     /// Define automatic instantiations of a [`Module`] in this linker.
858     ///
859     /// This is the same as [`Linker::module`], except for async `Store`s.
860     #[cfg(all(feature = "async", feature = "cranelift"))]
861     pub async fn module_async(
862         &mut self,
863         mut store: impl AsContextMut<Data = T>,
864         module_name: &str,
865         module: &Module,
866     ) -> Result<&mut Self>
867     where
868         T: Send + 'static,
869     {
870         // NB: this is intended to function the same as `Linker::module`, they
871         // should be kept in sync.
872         assert!(
873             Engine::same(&self.engine, store.as_context().engine()),
874             "different engines for this linker and the store provided"
875         );
876         match ModuleKind::categorize(module)? {
877             ModuleKind::Command => self.command(
878                 store,
879                 module_name,
880                 module,
881                 |store, func_ty, export_name, instance_pre| {
882                     let upvars = Arc::new((instance_pre, export_name));
883                     Func::new_async(
884                         store,
885                         func_ty.clone(),
886                         move |mut caller, params, results| {
887                             let upvars = upvars.clone();
888                             Box::new(async move {
889                                 let (instance_pre, export_name) = &*upvars;
890                                 let instance = instance_pre.instantiate_async(&mut caller).await?;
891 
892                                 instance
893                                     .get_export(&mut caller, &export_name)
894                                     .unwrap()
895                                     .into_func()
896                                     .unwrap()
897                                     .call_async(&mut caller, params, results)
898                                     .await?;
899                                 Ok(())
900                             })
901                         },
902                     )
903                 },
904             ),
905             ModuleKind::Reactor => {
906                 let instance = self.instantiate_async(&mut store, &module).await?;
907 
908                 if let Some(export) = instance.get_export(&mut store, "_initialize") {
909                     if let Extern::Func(func) = export {
910                         let func = func
911                             .typed::<(), ()>(&store)
912                             .context("loading the Reactor initialization function")?;
913                         func.call_async(&mut store, ())
914                             .await
915                             .context("calling the Reactor initialization function")?;
916                     }
917                 }
918 
919                 self.instance(store, module_name, instance)
920             }
921         }
922     }
923 
924     fn command(
925         &mut self,
926         mut store: impl AsContextMut<Data = T>,
927         module_name: &str,
928         module: &Module,
929         mk_func: impl Fn(&mut StoreContextMut<T>, &FuncType, String, InstancePre<T>) -> Func,
930     ) -> Result<&mut Self>
931     where
932         T: 'static,
933     {
934         let mut store = store.as_context_mut();
935         for export in module.exports() {
936             if let Some(func_ty) = export.ty().func() {
937                 let instance_pre = self.instantiate_pre(module)?;
938                 let export_name = export.name().to_owned();
939                 let func = mk_func(&mut store, func_ty, export_name, instance_pre);
940                 let key = self.import_key(module_name, Some(export.name()));
941                 self.insert(key, Definition::new(store.0, func.into()))?;
942             } else if export.name() == "memory" && export.ty().memory().is_some() {
943                 // Allow an exported "memory" memory for now.
944             } else if export.name() == "__indirect_function_table" && export.ty().table().is_some()
945             {
946                 // Allow an exported "__indirect_function_table" table for now.
947             } else if export.name() == "table" && export.ty().table().is_some() {
948                 // Allow an exported "table" table for now.
949             } else if export.name() == "__data_end" && 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 '__data_end' is deprecated");
954             } else if export.name() == "__heap_base" && export.ty().global().is_some() {
955                 // Allow an exported "__data_end" 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 '__heap_base' is deprecated");
959             } else if export.name() == "__dso_handle" && export.ty().global().is_some() {
960                 // Allow an exported "__dso_handle" memory for compatibility with toolchains
961                 // which use --export-dynamic, which unfortunately doesn't work the way
962                 // we want it to.
963                 warn!("command module exporting '__dso_handle' is deprecated")
964             } else if export.name() == "__rtti_base" && export.ty().global().is_some() {
965                 // Allow an exported "__rtti_base" memory for compatibility with
966                 // AssemblyScript.
967                 warn!(
968                     "command module exporting '__rtti_base' is deprecated; pass `--runtime half` to the AssemblyScript compiler"
969                 );
970             } else if !self.allow_unknown_exports {
971                 bail!("command export '{}' is not a function", export.name());
972             }
973         }
974 
975         Ok(self)
976     }
977 
978     /// Aliases one item's name as another.
979     ///
980     /// This method will alias an item with the specified `module` and `name`
981     /// under a new name of `as_module` and `as_name`.
982     ///
983     /// # Errors
984     ///
985     /// Returns an error if any shadowing violations happen while defining new
986     /// items, or if the original item wasn't defined.
987     pub fn alias(
988         &mut self,
989         module: &str,
990         name: &str,
991         as_module: &str,
992         as_name: &str,
993     ) -> Result<&mut Self> {
994         let src = self.import_key(module, Some(name));
995         let dst = self.import_key(as_module, Some(as_name));
996         match self.map.get(&src).cloned() {
997             Some(item) => self.insert(dst, item)?,
998             None => bail!("no item named `{}::{}` defined", module, name),
999         }
1000         Ok(self)
1001     }
1002 
1003     /// Aliases one module's name as another.
1004     ///
1005     /// This method will alias all currently defined under `module` to also be
1006     /// defined under the name `as_module` too.
1007     ///
1008     /// # Errors
1009     ///
1010     /// Returns an error if any shadowing violations happen while defining new
1011     /// items.
1012     pub fn alias_module(&mut self, module: &str, as_module: &str) -> Result<()> {
1013         let module = self.intern_str(module);
1014         let as_module = self.intern_str(as_module);
1015         let items = self
1016             .map
1017             .iter()
1018             .filter(|(key, _def)| key.module == module)
1019             .map(|(key, def)| (key.name, def.clone()))
1020             .collect::<Vec<_>>();
1021         for (name, item) in items {
1022             self.insert(
1023                 ImportKey {
1024                     module: as_module,
1025                     name,
1026                 },
1027                 item,
1028             )?;
1029         }
1030         Ok(())
1031     }
1032 
1033     fn insert(&mut self, key: ImportKey, item: Definition) -> Result<()> {
1034         match self.map.entry(key) {
1035             Entry::Occupied(_) if !self.allow_shadowing => {
1036                 let module = &self.strings[key.module];
1037                 let desc = match self.strings.get(key.name) {
1038                     Some(name) => format!("{module}::{name}"),
1039                     None => module.to_string(),
1040                 };
1041                 bail!("import of `{}` defined twice", desc)
1042             }
1043             Entry::Occupied(mut o) => {
1044                 o.insert(item);
1045             }
1046             Entry::Vacant(v) => {
1047                 v.insert(item);
1048             }
1049         }
1050         Ok(())
1051     }
1052 
1053     fn import_key(&mut self, module: &str, name: Option<&str>) -> ImportKey {
1054         ImportKey {
1055             module: self.intern_str(module),
1056             name: name
1057                 .map(|name| self.intern_str(name))
1058                 .unwrap_or(usize::max_value()),
1059         }
1060     }
1061 
1062     fn intern_str(&mut self, string: &str) -> usize {
1063         if let Some(idx) = self.string2idx.get(string) {
1064             return *idx;
1065         }
1066         let string: Arc<str> = string.into();
1067         let idx = self.strings.len();
1068         self.strings.push(string.clone());
1069         self.string2idx.insert(string, idx);
1070         idx
1071     }
1072 
1073     /// Attempts to instantiate the `module` provided.
1074     ///
1075     /// This method will attempt to assemble a list of imports that correspond
1076     /// to the imports required by the [`Module`] provided. This list
1077     /// of imports is then passed to [`Instance::new`] to continue the
1078     /// instantiation process.
1079     ///
1080     /// Each import of `module` will be looked up in this [`Linker`] and must
1081     /// have previously been defined. If it was previously defined with an
1082     /// incorrect signature or if it was not previously defined then an error
1083     /// will be returned because the import can not be satisfied.
1084     ///
1085     /// Per the WebAssembly spec, instantiation includes running the module's
1086     /// start function, if it has one (not to be confused with the `_start`
1087     /// function, which is not run).
1088     ///
1089     /// # Errors
1090     ///
1091     /// This method can fail because an import may not be found, or because
1092     /// instantiation itself may fail. For information on instantiation
1093     /// failures see [`Instance::new`]. If an import is not found, the error
1094     /// may be downcast to an [`UnknownImportError`].
1095     ///
1096     ///
1097     /// # Panics
1098     ///
1099     /// Panics if any item used to instantiate `module` is not owned by
1100     /// `store`. Additionally this will panic if the [`Engine`] that the `store`
1101     /// belongs to is different than this [`Linker`].
1102     ///
1103     /// # Examples
1104     ///
1105     /// ```
1106     /// # use wasmtime::*;
1107     /// # fn main() -> anyhow::Result<()> {
1108     /// # let engine = Engine::default();
1109     /// # let mut store = Store::new(&engine, ());
1110     /// let mut linker = Linker::new(&engine);
1111     /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
1112     ///
1113     /// let wat = r#"
1114     ///     (module
1115     ///         (import "host" "double" (func (param i32) (result i32)))
1116     ///     )
1117     /// "#;
1118     /// let module = Module::new(&engine, wat)?;
1119     /// linker.instantiate(&mut store, &module)?;
1120     /// # Ok(())
1121     /// # }
1122     /// ```
1123     pub fn instantiate(
1124         &self,
1125         mut store: impl AsContextMut<Data = T>,
1126         module: &Module,
1127     ) -> Result<Instance>
1128     where
1129         T: 'static,
1130     {
1131         self._instantiate_pre(module, Some(store.as_context_mut().0))?
1132             .instantiate(store)
1133     }
1134 
1135     /// Attempts to instantiate the `module` provided. This is the same as
1136     /// [`Linker::instantiate`], except for async `Store`s.
1137     #[cfg(feature = "async")]
1138     pub async fn instantiate_async(
1139         &self,
1140         mut store: impl AsContextMut<Data = T>,
1141         module: &Module,
1142     ) -> Result<Instance>
1143     where
1144         T: Send + 'static,
1145     {
1146         self._instantiate_pre(module, Some(store.as_context_mut().0))?
1147             .instantiate_async(store)
1148             .await
1149     }
1150 
1151     /// Performs all checks necessary for instantiating `module` with this
1152     /// linker, except that instantiation doesn't actually finish.
1153     ///
1154     /// This method is used for front-loading type-checking information as well
1155     /// as collecting the imports to use to instantiate a module with. The
1156     /// returned [`InstancePre`] represents a ready-to-be-instantiated module,
1157     /// which can also be instantiated multiple times if desired.
1158     ///
1159     /// # Errors
1160     ///
1161     /// Returns an error which may be downcast to an [`UnknownImportError`] if
1162     /// the module has any unresolvable imports.
1163     ///
1164     /// # Examples
1165     ///
1166     /// ```
1167     /// # use wasmtime::*;
1168     /// # fn main() -> anyhow::Result<()> {
1169     /// # let engine = Engine::default();
1170     /// # let mut store = Store::new(&engine, ());
1171     /// let mut linker = Linker::new(&engine);
1172     /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
1173     ///
1174     /// let wat = r#"
1175     ///     (module
1176     ///         (import "host" "double" (func (param i32) (result i32)))
1177     ///     )
1178     /// "#;
1179     /// let module = Module::new(&engine, wat)?;
1180     /// let instance_pre = linker.instantiate_pre(&module)?;
1181     ///
1182     /// // Finish instantiation after the type-checking has all completed...
1183     /// let instance = instance_pre.instantiate(&mut store)?;
1184     ///
1185     /// // ... and we can even continue to keep instantiating if desired!
1186     /// instance_pre.instantiate(&mut store)?;
1187     /// instance_pre.instantiate(&mut store)?;
1188     ///
1189     /// // Note that functions defined in a linker with `func_wrap` and similar
1190     /// // constructors are not owned by any particular `Store`, so we can also
1191     /// // instantiate our `instance_pre` in other stores because no imports
1192     /// // belong to the original store.
1193     /// let mut new_store = Store::new(&engine, ());
1194     /// instance_pre.instantiate(&mut new_store)?;
1195     /// # Ok(())
1196     /// # }
1197     /// ```
1198     pub fn instantiate_pre(&self, module: &Module) -> Result<InstancePre<T>>
1199     where
1200         T: 'static,
1201     {
1202         self._instantiate_pre(module, None)
1203     }
1204 
1205     /// This is split out to optionally take a `store` so that when the
1206     /// `.instantiate` API is used we can get fresh up-to-date type information
1207     /// for memories and their current size, if necessary.
1208     ///
1209     /// Note that providing a `store` here is not required for correctness
1210     /// per-se. If one is not provided, such as the with the `instantiate_pre`
1211     /// API, then the type information used for memories and tables will reflect
1212     /// their size when inserted into the linker rather than their current size.
1213     /// This isn't expected to be much of a problem though since
1214     /// per-store-`Linker` types are likely using `.instantiate(..)` and
1215     /// per-`Engine` linkers don't have memories/tables in them.
1216     fn _instantiate_pre(
1217         &self,
1218         module: &Module,
1219         store: Option<&StoreOpaque>,
1220     ) -> Result<InstancePre<T>>
1221     where
1222         T: 'static,
1223     {
1224         let mut imports = module
1225             .imports()
1226             .map(|import| self._get_by_import(&import))
1227             .collect::<Result<Vec<_>, _>>()?;
1228         if let Some(store) = store {
1229             for import in imports.iter_mut() {
1230                 import.update_size(store);
1231             }
1232         }
1233         unsafe { InstancePre::new(module, imports) }
1234     }
1235 
1236     /// Returns an iterator over all items defined in this `Linker`, in
1237     /// arbitrary order.
1238     ///
1239     /// The iterator returned will yield 3-tuples where the first two elements
1240     /// are the module name and item name for the external item, and the third
1241     /// item is the item itself that is defined.
1242     ///
1243     /// Note that multiple `Extern` items may be defined for the same
1244     /// module/name pair.
1245     ///
1246     /// # Panics
1247     ///
1248     /// This function will panic if the `store` provided does not come from the
1249     /// same [`Engine`] that this linker was created with.
1250     pub fn iter<'a: 'p, 'p>(
1251         &'a self,
1252         mut store: impl AsContextMut<Data = T> + 'p,
1253     ) -> impl Iterator<Item = (&'a str, &'a str, Extern)> + 'p
1254     where
1255         T: 'static,
1256     {
1257         self.map.iter().map(move |(key, item)| {
1258             let store = store.as_context_mut();
1259             (
1260                 &*self.strings[key.module],
1261                 &*self.strings[key.name],
1262                 // Should be safe since `T` is connecting the linker and store
1263                 unsafe { item.to_extern(store.0) },
1264             )
1265         })
1266     }
1267 
1268     /// Looks up a previously defined value in this [`Linker`], identified by
1269     /// the names provided.
1270     ///
1271     /// Returns `None` if this name was not previously defined in this
1272     /// [`Linker`].
1273     ///
1274     /// # Panics
1275     ///
1276     /// This function will panic if the `store` provided does not come from the
1277     /// same [`Engine`] that this linker was created with.
1278     pub fn get(
1279         &self,
1280         mut store: impl AsContextMut<Data = T>,
1281         module: &str,
1282         name: &str,
1283     ) -> Option<Extern>
1284     where
1285         T: 'static,
1286     {
1287         let store = store.as_context_mut().0;
1288         // Should be safe since `T` is connecting the linker and store
1289         Some(unsafe { self._get(module, name)?.to_extern(store) })
1290     }
1291 
1292     fn _get(&self, module: &str, name: &str) -> Option<&Definition> {
1293         let key = ImportKey {
1294             module: *self.string2idx.get(module)?,
1295             name: *self.string2idx.get(name)?,
1296         };
1297         self.map.get(&key)
1298     }
1299 
1300     /// Looks up a value in this `Linker` which matches the `import` type
1301     /// provided.
1302     ///
1303     /// Returns `None` if no match was found.
1304     ///
1305     /// # Panics
1306     ///
1307     /// This function will panic if the `store` provided does not come from the
1308     /// same [`Engine`] that this linker was created with.
1309     pub fn get_by_import(
1310         &self,
1311         mut store: impl AsContextMut<Data = T>,
1312         import: &ImportType,
1313     ) -> Option<Extern>
1314     where
1315         T: 'static,
1316     {
1317         let store = store.as_context_mut().0;
1318         // Should be safe since `T` is connecting the linker and store
1319         Some(unsafe { self._get_by_import(import).ok()?.to_extern(store) })
1320     }
1321 
1322     fn _get_by_import(&self, import: &ImportType) -> Result<Definition, UnknownImportError> {
1323         match self._get(import.module(), import.name()) {
1324             Some(item) => Ok(item.clone()),
1325             None => Err(UnknownImportError::new(import)),
1326         }
1327     }
1328 
1329     /// Returns the "default export" of a module.
1330     ///
1331     /// An export with an empty string is considered to be a "default export".
1332     /// "_start" is also recognized for compatibility.
1333     ///
1334     /// # Panics
1335     ///
1336     /// Panics if the default function found is not owned by `store`. This
1337     /// function will also panic if the `store` provided does not come from the
1338     /// same [`Engine`] that this linker was created with.
1339     pub fn get_default(&self, mut store: impl AsContextMut<Data = T>, module: &str) -> Result<Func>
1340     where
1341         T: 'static,
1342     {
1343         if let Some(external) = self.get(&mut store, module, "") {
1344             if let Extern::Func(func) = external {
1345                 return Ok(func);
1346             }
1347             bail!("default export in '{}' is not a function", module);
1348         }
1349 
1350         // For compatibility, also recognize "_start".
1351         if let Some(external) = self.get(&mut store, module, "_start") {
1352             if let Extern::Func(func) = external {
1353                 return Ok(func);
1354             }
1355             bail!("`_start` in '{}' is not a function", module);
1356         }
1357 
1358         // Otherwise return a no-op function.
1359         Ok(Func::wrap(store, || {}))
1360     }
1361 }
1362 
1363 impl<T: 'static> Default for Linker<T> {
1364     fn default() -> Linker<T> {
1365         Linker::new(&Engine::default())
1366     }
1367 }
1368 
1369 impl Definition {
1370     fn new(store: &StoreOpaque, item: Extern) -> Definition {
1371         let ty = DefinitionType::from(store, &item);
1372         Definition::Extern(item, ty)
1373     }
1374 
1375     pub(crate) fn ty(&self) -> DefinitionType {
1376         match self {
1377             Definition::Extern(_, ty) => ty.clone(),
1378             Definition::HostFunc(func) => DefinitionType::Func(func.sig_index()),
1379         }
1380     }
1381 
1382     /// Inserts this definition into the `store` provided.
1383     ///
1384     /// # Safety
1385     ///
1386     /// Note the unsafety here is due to calling `HostFunc::to_func`. The
1387     /// requirement here is that the `T` that was originally used to create the
1388     /// `HostFunc` matches the `T` on the store.
1389     pub(crate) unsafe fn to_extern(&self, store: &mut StoreOpaque) -> Extern {
1390         match self {
1391             Definition::Extern(e, _) => e.clone(),
1392             // SAFETY: the contract of this function is the same as what's
1393             // required of `to_func`, that `T` of the store matches the `T` of
1394             // this original definition.
1395             Definition::HostFunc(func) => unsafe { func.to_func(store).into() },
1396         }
1397     }
1398 
1399     pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque) -> bool {
1400         match self {
1401             Definition::Extern(e, _) => e.comes_from_same_store(store),
1402             Definition::HostFunc(_func) => true,
1403         }
1404     }
1405 
1406     fn update_size(&mut self, store: &StoreOpaque) {
1407         match self {
1408             Definition::Extern(Extern::Memory(m), DefinitionType::Memory(_, size)) => {
1409                 *size = m.internal_size(store);
1410             }
1411             Definition::Extern(Extern::SharedMemory(m), DefinitionType::Memory(_, size)) => {
1412                 *size = m.size();
1413             }
1414             Definition::Extern(Extern::Table(m), DefinitionType::Table(_, size)) => {
1415                 *size = m._size(store);
1416             }
1417             _ => {}
1418         }
1419     }
1420 }
1421 
1422 impl DefinitionType {
1423     pub(crate) fn from(store: &StoreOpaque, item: &Extern) -> DefinitionType {
1424         match item {
1425             Extern::Func(f) => DefinitionType::Func(f.type_index(store)),
1426             Extern::Table(t) => DefinitionType::Table(*t.wasmtime_ty(store), t._size(store)),
1427             Extern::Global(t) => DefinitionType::Global(*t.wasmtime_ty(store)),
1428             Extern::Memory(t) => {
1429                 DefinitionType::Memory(*t.wasmtime_ty(store), t.internal_size(store))
1430             }
1431             Extern::SharedMemory(t) => DefinitionType::Memory(*t.ty().wasmtime_memory(), t.size()),
1432             Extern::Tag(t) => DefinitionType::Tag(*t.wasmtime_ty(store)),
1433         }
1434     }
1435 
1436     pub(crate) fn desc(&self) -> &'static str {
1437         match self {
1438             DefinitionType::Func(_) => "function",
1439             DefinitionType::Table(..) => "table",
1440             DefinitionType::Memory(..) => "memory",
1441             DefinitionType::Global(_) => "global",
1442             DefinitionType::Tag(_) => "tag",
1443         }
1444     }
1445 }
1446 
1447 /// Modules can be interpreted either as Commands or Reactors.
1448 enum ModuleKind {
1449     /// The instance is a Command, meaning an instance is created for each
1450     /// exported function and lives for the duration of the function call.
1451     Command,
1452 
1453     /// The instance is a Reactor, meaning one instance is created which
1454     /// may live across multiple calls.
1455     Reactor,
1456 }
1457 
1458 impl ModuleKind {
1459     /// Determine whether the given module is a Command or a Reactor.
1460     fn categorize(module: &Module) -> Result<ModuleKind> {
1461         let command_start = module.get_export("_start");
1462         let reactor_start = module.get_export("_initialize");
1463         match (command_start, reactor_start) {
1464             (Some(command_start), None) => {
1465                 if let Some(_) = command_start.func() {
1466                     Ok(ModuleKind::Command)
1467                 } else {
1468                     bail!("`_start` must be a function")
1469                 }
1470             }
1471             (None, Some(reactor_start)) => {
1472                 if let Some(_) = reactor_start.func() {
1473                     Ok(ModuleKind::Reactor)
1474                 } else {
1475                     bail!("`_initialize` must be a function")
1476                 }
1477             }
1478             (None, None) => {
1479                 // Module declares neither of the recognized functions, so treat
1480                 // it as a reactor with no initialization function.
1481                 Ok(ModuleKind::Reactor)
1482             }
1483             (Some(_), Some(_)) => {
1484                 // Module declares itself to be both a Command and a Reactor.
1485                 bail!("Program cannot be both a Command and a Reactor")
1486             }
1487         }
1488     }
1489 }
1490 
1491 /// Error for an unresolvable import.
1492 ///
1493 /// Returned - wrapped in an [`anyhow::Error`] - by [`Linker::instantiate`] and
1494 /// related methods for modules with unresolvable imports.
1495 #[derive(Clone, Debug)]
1496 pub struct UnknownImportError {
1497     module: String,
1498     name: String,
1499     ty: ExternType,
1500 }
1501 
1502 impl UnknownImportError {
1503     fn new(import: &ImportType) -> Self {
1504         Self {
1505             module: import.module().to_string(),
1506             name: import.name().to_string(),
1507             ty: import.ty(),
1508         }
1509     }
1510 
1511     /// Returns the module name that the unknown import was expected to come from.
1512     pub fn module(&self) -> &str {
1513         &self.module
1514     }
1515 
1516     /// Returns the field name of the module that the unknown import was expected to come from.
1517     pub fn name(&self) -> &str {
1518         &self.name
1519     }
1520 
1521     /// Returns the type of the unknown import.
1522     pub fn ty(&self) -> ExternType {
1523         self.ty.clone()
1524     }
1525 }
1526 
1527 impl fmt::Display for UnknownImportError {
1528     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1529         write!(
1530             f,
1531             "unknown import: `{}::{}` has not been defined",
1532             self.module, self.name,
1533         )
1534     }
1535 }
1536 
1537 impl core::error::Error for UnknownImportError {}
1538