Skip to main content

wasmtime/runtime/
linker.rs

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