wasmtime/runtime/
linker.rs

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