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