wasmtime/runtime/
linker.rs

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