wasmtime/runtime/
linker.rs

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