wasmtime/runtime/
linker.rs

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