1 use crate::error::OutOfMemory;
2 use crate::func::HostFunc;
3 use crate::instance::InstancePre;
4 use crate::store::StoreOpaque;
5 use crate::{
6     AsContext, AsContextMut, Caller, Engine, Extern, ExternType, Func, FuncType, ImportType,
7     Instance, IntoFunc, Module, Result, StoreContextMut, Val, ValRaw, prelude::*,
8 };
9 use alloc::sync::Arc;
10 use core::fmt::{self, Debug};
11 #[cfg(feature = "async")]
12 use core::future::Future;
13 use core::marker;
14 use core::mem::MaybeUninit;
15 use log::warn;
16 use wasmtime_environ::{Atom, PanicOnOom, StringPool};
17 
18 /// Structure used to link wasm modules/instances together.
19 ///
20 /// This structure is used to assist in instantiating a [`Module`]. A [`Linker`]
21 /// is a way of performing name resolution to make instantiating a module easier
22 /// than specifying positional imports to [`Instance::new`]. [`Linker`] is a
23 /// name-based resolver where names are dynamically defined and then used to
24 /// instantiate a [`Module`].
25 ///
26 /// An important method is [`Linker::instantiate`] which takes a module to
27 /// instantiate into the provided store. This method will automatically select
28 /// all the right imports for the [`Module`] to be instantiated, and will
29 /// otherwise return an error if an import isn't satisfied.
30 ///
31 /// ## Name Resolution
32 ///
33 /// As mentioned previously, `Linker` is a form of name resolver. It will be
34 /// using the string-based names of imports on a module to attempt to select a
35 /// matching item to hook up to it. This name resolution has two-levels of
36 /// namespaces, a module level and a name level. Each item is defined within a
37 /// module and then has its own name. This basically follows the wasm standard
38 /// for modularization.
39 ///
40 /// Names in a `Linker` cannot be defined twice, but allowing duplicates by
41 /// shadowing the previous definition can be controlled with the
42 /// [`Linker::allow_shadowing`] method.
43 ///
44 /// ## Commands and Reactors
45 ///
46 /// The [`Linker`] type provides conveniences for working with WASI Commands and
47 /// Reactors through the [`Linker::module`] method. This will automatically
48 /// handle instantiation and calling `_start` and such as appropriate
49 /// depending on the inferred type of module.
50 ///
51 /// ## Type parameter `T`
52 ///
53 /// It's worth pointing out that the type parameter `T` on [`Linker<T>`] does
54 /// not represent that `T` is stored within a [`Linker`]. Rather the `T` is used
55 /// to ensure that linker-defined functions and stores instantiated into all use
56 /// the same matching `T` as host state.
57 ///
58 /// ## Multiple `Store`s
59 ///
60 /// The [`Linker`] type is designed to be compatible, in some scenarios, with
61 /// instantiation in multiple [`Store`]s. Specifically host-defined functions
62 /// created in [`Linker`] with [`Linker::func_new`], [`Linker::func_wrap`], and
63 /// their async versions are compatible to instantiate into any [`Store`]. This
64 /// enables programs which want to instantiate lots of modules to create one
65 /// [`Linker`] value at program start up and use that continuously for each
66 /// [`Store`] created over the lifetime of the program.
67 ///
68 /// Note that once [`Store`]-owned items, such as [`Global`], are defined within
69 /// a [`Linker`] then it is no longer compatible with any [`Store`]. At that
70 /// point only the [`Store`] that owns the [`Global`] can be used to instantiate
71 /// modules.
72 ///
73 /// ## Multiple `Engine`s
74 ///
75 /// The [`Linker`] type is not compatible with usage between multiple [`Engine`]
76 /// values. An [`Engine`] is provided when a [`Linker`] is created and only
77 /// stores and items which originate from that [`Engine`] can be used with this
78 /// [`Linker`]. If more than one [`Engine`] is used with a [`Linker`] then that
79 /// may cause a panic at runtime, similar to how if a [`Func`] is used with the
80 /// wrong [`Store`] that can also panic at runtime.
81 ///
82 /// [`Store`]: crate::Store
83 /// [`Global`]: crate::Global
84 pub struct Linker<T> {
85     engine: Engine,
86     pool: StringPool,
87     map: TryHashMap<ImportKey, Definition>,
88     allow_shadowing: bool,
89     allow_unknown_exports: bool,
90     _marker: marker::PhantomData<fn() -> T>,
91 }
92 
93 impl<T> Debug for Linker<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result94     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95         f.debug_struct("Linker").finish_non_exhaustive()
96     }
97 }
98 
99 impl<T> Clone for Linker<T> {
clone(&self) -> Linker<T>100     fn clone(&self) -> Linker<T> {
101         Linker {
102             engine: self.engine.clone(),
103             pool: self.pool.clone_panic_on_oom(),
104             map: self.map.clone_panic_on_oom(),
105             allow_shadowing: self.allow_shadowing,
106             allow_unknown_exports: self.allow_unknown_exports,
107             _marker: self._marker,
108         }
109     }
110 }
111 
112 #[derive(Copy, Clone, Hash, PartialEq, Eq)]
113 struct ImportKey {
114     module: Atom,
115     name: Option<Atom>,
116 }
117 
118 impl TryClone for ImportKey {
119     #[inline]
try_clone(&self) -> Result<Self, OutOfMemory>120     fn try_clone(&self) -> Result<Self, OutOfMemory> {
121         Ok(*self)
122     }
123 }
124 
125 #[derive(Clone)]
126 pub(crate) enum Definition {
127     Extern(Extern, DefinitionType),
128     HostFunc(Arc<HostFunc>),
129 }
130 
131 impl TryClone for Definition {
try_clone(&self) -> core::result::Result<Self, OutOfMemory>132     fn try_clone(&self) -> core::result::Result<Self, OutOfMemory> {
133         Ok(self.clone())
134     }
135 }
136 
137 /// This is a sort of slimmed down `ExternType` which notably doesn't have a
138 /// `FuncType`, which is an allocation, and additionally retains the current
139 /// size of the table/memory.
140 #[derive(Clone, Copy, Debug)]
141 pub(crate) enum DefinitionType {
142     Func(wasmtime_environ::VMSharedTypeIndex),
143     Global(wasmtime_environ::Global),
144     // Note that tables and memories store not only the original type
145     // information but additionally the current size of the table/memory, as
146     // this is used during linking since the min size specified in the type may
147     // no longer be the current size of the table/memory.
148     Table(wasmtime_environ::Table, u64),
149     Memory(wasmtime_environ::Memory, u64),
150     Tag(wasmtime_environ::Tag),
151 }
152 
153 impl<T> Linker<T> {
154     /// Creates a new [`Linker`].
155     ///
156     /// The linker will define functions within the context of the `engine`
157     /// provided and can only instantiate modules for a [`Store`][crate::Store]
158     /// that is also defined within the same [`Engine`]. Usage of stores with
159     /// different [`Engine`]s may cause a panic when used with this [`Linker`].
new(engine: &Engine) -> Linker<T>160     pub fn new(engine: &Engine) -> Linker<T> {
161         Linker {
162             engine: engine.clone(),
163             map: TryHashMap::new(),
164             pool: StringPool::new(),
165             allow_shadowing: false,
166             allow_unknown_exports: false,
167             _marker: marker::PhantomData,
168         }
169     }
170 
171     /// Returns the [`Engine`] this is connected to.
engine(&self) -> &Engine172     pub fn engine(&self) -> &Engine {
173         &self.engine
174     }
175 
176     /// Configures whether this [`Linker`] will shadow previous duplicate
177     /// definitions of the same signature.
178     ///
179     /// By default a [`Linker`] will disallow duplicate definitions of the same
180     /// signature. This method, however, can be used to instead allow duplicates
181     /// and have the latest definition take precedence when linking modules.
182     ///
183     /// # Examples
184     ///
185     /// ```
186     /// # use wasmtime::*;
187     /// # fn main() -> Result<()> {
188     /// # let engine = Engine::default();
189     /// let mut linker = Linker::<()>::new(&engine);
190     /// linker.func_wrap("", "", || {})?;
191     ///
192     /// // by default, duplicates are disallowed
193     /// assert!(linker.func_wrap("", "", || {}).is_err());
194     ///
195     /// // but shadowing can be configured to be allowed as well
196     /// linker.allow_shadowing(true);
197     /// linker.func_wrap("", "", || {})?;
198     /// # Ok(())
199     /// # }
200     /// ```
allow_shadowing(&mut self, allow: bool) -> &mut Self201     pub fn allow_shadowing(&mut self, allow: bool) -> &mut Self {
202         self.allow_shadowing = allow;
203         self
204     }
205 
206     /// Configures whether this [`Linker`] will allow unknown exports from
207     /// command modules.
208     ///
209     /// By default a [`Linker`] will error when unknown exports are encountered
210     /// in a command module while using [`Linker::module`].
211     ///
212     /// This method can be used to allow unknown exports from command modules.
213     ///
214     /// # Examples
215     ///
216     /// ```
217     /// # use wasmtime::*;
218     /// # fn main() -> Result<()> {
219     /// # let engine = Engine::default();
220     /// # let module = Module::new(&engine, "(module)")?;
221     /// # let mut store = Store::new(&engine, ());
222     /// let mut linker = Linker::new(&engine);
223     /// linker.allow_unknown_exports(true);
224     /// linker.module(&mut store, "mod", &module)?;
225     /// # Ok(())
226     /// # }
227     /// ```
allow_unknown_exports(&mut self, allow: bool) -> &mut Self228     pub fn allow_unknown_exports(&mut self, allow: bool) -> &mut Self {
229         self.allow_unknown_exports = allow;
230         self
231     }
232 
233     /// Implement any imports of the given [`Module`] with a function which traps.
234     ///
235     /// By default a [`Linker`] will error when unknown imports are encountered
236     /// in a command module while using [`Linker::module`].
237     ///
238     /// This method can be used to allow unknown imports from command modules.
239     ///
240     /// # Examples
241     ///
242     /// ```
243     /// # use wasmtime::*;
244     /// # fn main() -> Result<()> {
245     /// # let engine = Engine::default();
246     /// # let module = Module::new(&engine, "(module (import \"unknown\" \"import\" (func)))")?;
247     /// # let mut store = Store::new(&engine, ());
248     /// let mut linker = Linker::new(&engine);
249     /// linker.define_unknown_imports_as_traps(&module)?;
250     /// linker.instantiate(&mut store, &module)?;
251     /// # Ok(())
252     /// # }
253     /// ```
define_unknown_imports_as_traps(&mut self, module: &Module) -> Result<()> where T: 'static,254     pub fn define_unknown_imports_as_traps(&mut self, module: &Module) -> Result<()>
255     where
256         T: 'static,
257     {
258         for import in module.imports() {
259             if let Err(import_err) = self._get_by_import(&import) {
260                 if let ExternType::Func(func_ty) = import_err.ty() {
261                     self.func_new(import.module(), import.name(), func_ty, move |_, _, _| {
262                         bail!(import_err.clone());
263                     })?;
264                 }
265             }
266         }
267         Ok(())
268     }
269 
270     /// Implement any function imports of the [`Module`] with a function that
271     /// ignores its arguments and returns default values.
272     ///
273     /// Default values are either zero or null, depending on the value type.
274     ///
275     /// This method can be used to allow unknown imports from command modules.
276     ///
277     /// # Example
278     ///
279     /// ```
280     /// # use wasmtime::*;
281     /// # fn main() -> Result<()> {
282     /// # let engine = Engine::default();
283     /// # let module = Module::new(&engine, "(module (import \"unknown\" \"import\" (func)))")?;
284     /// # let mut store = Store::new(&engine, ());
285     /// let mut linker = Linker::new(&engine);
286     /// linker.define_unknown_imports_as_default_values(&mut store, &module)?;
287     /// linker.instantiate(&mut store, &module)?;
288     /// # Ok(())
289     /// # }
290     /// ```
define_unknown_imports_as_default_values( &mut self, mut store: impl AsContextMut<Data = T>, module: &Module, ) -> Result<()> where T: 'static,291     pub fn define_unknown_imports_as_default_values(
292         &mut self,
293         mut store: impl AsContextMut<Data = T>,
294         module: &Module,
295     ) -> Result<()>
296     where
297         T: 'static,
298     {
299         let mut store = store.as_context_mut();
300         for import in module.imports() {
301             if let Err(import_err) = self._get_by_import(&import) {
302                 let default_extern =
303                     import_err.ty().default_value(&mut store).with_context(|| {
304                         format_err!(
305                             "no default value exists for `{}::{}` with type `{:?}`",
306                             import.module(),
307                             import.name(),
308                             import_err.ty(),
309                         )
310                     })?;
311                 self.define(
312                     store.as_context(),
313                     import.module(),
314                     import.name(),
315                     default_extern,
316                 )?;
317             }
318         }
319         Ok(())
320     }
321 
322     /// Defines a new item in this [`Linker`].
323     ///
324     /// This method will add a new definition, by name, to this instance of
325     /// [`Linker`]. The `module` and `name` provided are what to name the
326     /// `item`.
327     ///
328     /// # Errors
329     ///
330     /// Returns an error if the `module` and `name` already identify an item
331     /// of the same type as the `item` provided and if shadowing is disallowed.
332     /// For more information see the documentation on [`Linker`].
333     ///
334     /// # Examples
335     ///
336     /// ```
337     /// # use wasmtime::*;
338     /// # fn main() -> Result<()> {
339     /// # let engine = Engine::default();
340     /// # let mut store = Store::new(&engine, ());
341     /// let mut linker = Linker::new(&engine);
342     /// let ty = GlobalType::new(ValType::I32, Mutability::Const);
343     /// let global = Global::new(&mut store, ty, Val::I32(0x1234))?;
344     /// linker.define(&store, "host", "offset", global)?;
345     ///
346     /// let wat = r#"
347     ///     (module
348     ///         (import "host" "offset" (global i32))
349     ///         (memory 1)
350     ///         (data (global.get 0) "foo")
351     ///     )
352     /// "#;
353     /// let module = Module::new(&engine, wat)?;
354     /// linker.instantiate(&mut store, &module)?;
355     /// # Ok(())
356     /// # }
357     /// ```
define( &mut self, store: impl AsContext<Data = T>, module: &str, name: &str, item: impl Into<Extern>, ) -> Result<&mut Self> where T: 'static,358     pub fn define(
359         &mut self,
360         store: impl AsContext<Data = T>,
361         module: &str,
362         name: &str,
363         item: impl Into<Extern>,
364     ) -> Result<&mut Self>
365     where
366         T: 'static,
367     {
368         let store = store.as_context();
369         let key = self.import_key(module, Some(name))?;
370         self.insert(key, Definition::new(store.0, item.into()))?;
371         Ok(self)
372     }
373 
374     /// Same as [`Linker::define`], except only the name of the import is
375     /// provided, not a module name as well.
376     ///
377     /// This is only relevant when working with the module linking proposal
378     /// where one-level names are allowed (in addition to two-level names).
379     /// Otherwise this method need not be used.
define_name( &mut self, store: impl AsContext<Data = T>, name: &str, item: impl Into<Extern>, ) -> Result<&mut Self> where T: 'static,380     pub fn define_name(
381         &mut self,
382         store: impl AsContext<Data = T>,
383         name: &str,
384         item: impl Into<Extern>,
385     ) -> Result<&mut Self>
386     where
387         T: 'static,
388     {
389         let store = store.as_context();
390         let key = self.import_key(name, None)?;
391         self.insert(key, Definition::new(store.0, item.into()))?;
392         Ok(self)
393     }
394 
func_insert(&mut self, module: &str, name: &str, func: HostFunc) -> Result<&mut Self> where T: 'static,395     fn func_insert(&mut self, module: &str, name: &str, func: HostFunc) -> Result<&mut Self>
396     where
397         T: 'static,
398     {
399         let key = self.import_key(module, Some(name))?;
400         self.insert(key, Definition::HostFunc(try_new(func)?))?;
401         Ok(self)
402     }
403 
404     /// Creates a [`Func::new`]-style function named in this linker.
405     ///
406     /// For more information see [`Linker::func_wrap`].
407     ///
408     /// # Panics
409     ///
410     /// Panics if the given function type is not associated with the same engine
411     /// as this linker.
func_new( &mut self, module: &str, name: &str, ty: FuncType, func: impl Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<()> + Send + Sync + 'static, ) -> Result<&mut Self> where T: 'static,412     pub fn func_new(
413         &mut self,
414         module: &str,
415         name: &str,
416         ty: FuncType,
417         func: impl Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<()> + Send + Sync + 'static,
418     ) -> Result<&mut Self>
419     where
420         T: 'static,
421     {
422         self.func_insert(module, name, HostFunc::new(&self.engine, ty, func)?)
423     }
424 
425     /// Creates a [`Func::new_unchecked`]-style function named in this linker.
426     ///
427     /// For more information see [`Linker::func_wrap`].
428     ///
429     /// # Panics
430     ///
431     /// Panics if the given function type is not associated with the same engine
432     /// as this linker.
433     ///
434     /// # Safety
435     ///
436     /// See [`Func::new_unchecked`] for more safety information.
func_new_unchecked( &mut self, module: &str, name: &str, ty: FuncType, func: impl Fn(Caller<'_, T>, &mut [MaybeUninit<ValRaw>]) -> Result<()> + Send + Sync + 'static, ) -> Result<&mut Self> where T: 'static,437     pub unsafe fn func_new_unchecked(
438         &mut self,
439         module: &str,
440         name: &str,
441         ty: FuncType,
442         func: impl Fn(Caller<'_, T>, &mut [MaybeUninit<ValRaw>]) -> Result<()> + Send + Sync + 'static,
443     ) -> Result<&mut Self>
444     where
445         T: 'static,
446     {
447         // SAFETY: the contract of this function is the same as `new_unchecked`.
448         let func = unsafe { HostFunc::new_unchecked(&self.engine, ty, func)? };
449         self.func_insert(module, name, func)
450     }
451 
452     /// Creates a [`Func::new_async`]-style function named in this linker.
453     ///
454     /// For more information see [`Linker::func_wrap`].
455     ///
456     /// # Panics
457     ///
458     /// This method panics in the following situations:
459     ///
460     /// * If the given function type is not associated with the same engine as
461     ///   this linker.
462     #[cfg(feature = "async")]
func_new_async<F>( &mut self, module: &str, name: &str, ty: FuncType, func: F, ) -> Result<&mut Self> where F: for<'a> Fn( Caller<'a, T>, &'a [Val], &'a mut [Val], ) -> Box<dyn Future<Output = Result<()>> + Send + 'a> + Send + Sync + 'static, T: Send + 'static,463     pub fn func_new_async<F>(
464         &mut self,
465         module: &str,
466         name: &str,
467         ty: FuncType,
468         func: F,
469     ) -> Result<&mut Self>
470     where
471         F: for<'a> Fn(
472                 Caller<'a, T>,
473                 &'a [Val],
474                 &'a mut [Val],
475             ) -> Box<dyn Future<Output = Result<()>> + Send + 'a>
476             + Send
477             + Sync
478             + 'static,
479         T: Send + 'static,
480     {
481         self.func_insert(module, name, HostFunc::new_async(&self.engine, ty, func)?)
482     }
483 
484     /// Define a host function within this linker.
485     ///
486     /// For information about how the host function operates, see
487     /// [`Func::wrap`]. That includes information about translating Rust types
488     /// to WebAssembly native types.
489     ///
490     /// This method creates a host-provided function in this linker under the
491     /// provided name. This method is distinct in its capability to create a
492     /// [`Store`](crate::Store)-independent function. This means that the
493     /// function defined here can be used to instantiate instances in multiple
494     /// different stores, or in other words the function can be loaded into
495     /// different stores.
496     ///
497     /// Note that the capability mentioned here applies to all other
498     /// host-function-defining-methods on [`Linker`] as well. All of them can be
499     /// used to create instances of [`Func`] within multiple stores. In a
500     /// multithreaded program, for example, this means that the host functions
501     /// could be called concurrently if different stores are executing on
502     /// different threads.
503     ///
504     /// # Errors
505     ///
506     /// Returns an error if the `module` and `name` already identify an item
507     /// of the same type as the `item` provided and if shadowing is disallowed.
508     /// For more information see the documentation on [`Linker`].
509     ///
510     /// # Examples
511     ///
512     /// ```
513     /// # use wasmtime::*;
514     /// # fn main() -> Result<()> {
515     /// # let engine = Engine::default();
516     /// let mut linker = Linker::new(&engine);
517     /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
518     /// linker.func_wrap("host", "log_i32", |x: i32| println!("{}", x))?;
519     /// linker.func_wrap("host", "log_str", |caller: Caller<'_, ()>, ptr: i32, len: i32| {
520     ///     // ...
521     /// })?;
522     ///
523     /// let wat = r#"
524     ///     (module
525     ///         (import "host" "double" (func (param i32) (result i32)))
526     ///         (import "host" "log_i32" (func (param i32)))
527     ///         (import "host" "log_str" (func (param i32 i32)))
528     ///     )
529     /// "#;
530     /// let module = Module::new(&engine, wat)?;
531     ///
532     /// // instantiate in multiple different stores
533     /// for _ in 0..10 {
534     ///     let mut store = Store::new(&engine, ());
535     ///     linker.instantiate(&mut store, &module)?;
536     /// }
537     /// # Ok(())
538     /// # }
539     /// ```
func_wrap<Params, Args>( &mut self, module: &str, name: &str, func: impl IntoFunc<T, Params, Args>, ) -> Result<&mut Self> where T: 'static,540     pub fn func_wrap<Params, Args>(
541         &mut self,
542         module: &str,
543         name: &str,
544         func: impl IntoFunc<T, Params, Args>,
545     ) -> Result<&mut Self>
546     where
547         T: 'static,
548     {
549         self.func_insert(module, name, func.into_func(&self.engine)?)
550     }
551 
552     /// Asynchronous analog of [`Linker::func_wrap`].
553     #[cfg(feature = "async")]
func_wrap_async<F, Params: crate::WasmTyList, Args: crate::WasmRet>( &mut self, module: &str, name: &str, func: F, ) -> Result<&mut Self> where F: for<'a> Fn(Caller<'a, T>, Params) -> Box<dyn Future<Output = Args> + Send + 'a> + Send + Sync + 'static, T: Send + 'static,554     pub fn func_wrap_async<F, Params: crate::WasmTyList, Args: crate::WasmRet>(
555         &mut self,
556         module: &str,
557         name: &str,
558         func: F,
559     ) -> Result<&mut Self>
560     where
561         F: for<'a> Fn(Caller<'a, T>, Params) -> Box<dyn Future<Output = Args> + Send + 'a>
562             + Send
563             + Sync
564             + 'static,
565         T: Send + 'static,
566     {
567         self.func_insert(module, name, HostFunc::wrap_async(&self.engine, func)?)
568     }
569 
570     /// Convenience wrapper to define an entire [`Instance`] in this linker.
571     ///
572     /// This function is a convenience wrapper around [`Linker::define`] which
573     /// will define all exports on `instance` into this linker. The module name
574     /// for each export is `module_name`, and the name for each export is the
575     /// name in the instance itself.
576     ///
577     /// Note that when this API is used the [`Linker`] is no longer compatible
578     /// with multi-[`Store`][crate::Store] instantiation because the items
579     /// defined within this store will belong to the `store` provided, and only
580     /// the `store` provided.
581     ///
582     /// # Errors
583     ///
584     /// Returns an error if the any item is redefined twice in this linker (for
585     /// example the same `module_name` was already defined) and shadowing is
586     /// disallowed, or if `instance` comes from a different
587     /// [`Store`](crate::Store) than this [`Linker`] originally was created
588     /// with.
589     ///
590     /// # Panics
591     ///
592     /// Panics if `instance` does not belong to `store`.
593     ///
594     /// # Examples
595     ///
596     /// ```
597     /// # use wasmtime::*;
598     /// # fn main() -> Result<()> {
599     /// # let engine = Engine::default();
600     /// # let mut store = Store::new(&engine, ());
601     /// let mut linker = Linker::new(&engine);
602     ///
603     /// // Instantiate a small instance...
604     /// let wat = r#"(module (func (export "run") ))"#;
605     /// let module = Module::new(&engine, wat)?;
606     /// let instance = linker.instantiate(&mut store, &module)?;
607     ///
608     /// // ... and inform the linker that the name of this instance is
609     /// // `instance1`. This defines the `instance1::run` name for our next
610     /// // module to use.
611     /// linker.instance(&mut store, "instance1", instance)?;
612     ///
613     /// let wat = r#"
614     ///     (module
615     ///         (import "instance1" "run" (func $instance1_run))
616     ///         (func (export "run")
617     ///             call $instance1_run
618     ///         )
619     ///     )
620     /// "#;
621     /// let module = Module::new(&engine, wat)?;
622     /// let instance = linker.instantiate(&mut store, &module)?;
623     /// # Ok(())
624     /// # }
625     /// ```
instance( &mut self, mut store: impl AsContextMut<Data = T>, module_name: &str, instance: Instance, ) -> Result<&mut Self> where T: 'static,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: TryVec<_> = instance
637             .exports(&mut store)
638             .map(|e| {
639                 Ok((
640                     self.import_key(module_name, Some(e.name()))?,
641                     e.into_extern(),
642                 ))
643             })
644             .try_collect::<_, Error>()?;
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     /// ```
module( &mut self, mut store: impl AsContextMut<Data = T>, module_name: &str, module: &Module, ) -> Result<&mut Self> where T: 'static,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")]
module_async( &mut self, mut store: impl AsContextMut<Data = T>, module_name: &str, module: &Module, ) -> Result<&mut Self> where T: Send + 'static,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 
command( &mut self, mut store: impl AsContextMut<Data = T>, module_name: &str, module: &Module, mk_func: impl Fn(&mut StoreContextMut<T>, &FuncType, String, InstancePre<T>) -> Func, ) -> Result<&mut Self> where T: 'static,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.
alias( &mut self, module: &str, name: &str, as_module: &str, as_name: &str, ) -> Result<&mut Self>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.
alias_module(&mut self, module: &str, as_module: &str) -> Result<()>988     pub fn alias_module(&mut self, module: &str, as_module: &str) -> Result<()> {
989         let module = self.pool.insert(module)?;
990         let as_module = self.pool.insert(as_module)?;
991         let items: TryVec<_> = self
992             .map
993             .iter()
994             .filter(|(key, _def)| key.module == module)
995             .map(|(key, def)| Ok((key.name, def.clone())))
996             .try_collect::<_, Error>()?;
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 
insert(&mut self, key: ImportKey, item: Definition) -> Result<()>1009     fn insert(&mut self, key: ImportKey, item: Definition) -> Result<()> {
1010         if !self.allow_shadowing && self.map.contains_key(&key) {
1011             let module = &self.pool[key.module];
1012             match key.name.and_then(|n| self.pool.get(n)) {
1013                 Some(name) => bail!("import of `{module}::{name}` defined twice"),
1014                 None => bail!("import of `{module}` defined twice"),
1015             }
1016         }
1017 
1018         self.map.insert(key, item)?;
1019         Ok(())
1020     }
1021 
import_key(&mut self, module: &str, name: Option<&str>) -> Result<ImportKey, OutOfMemory>1022     fn import_key(&mut self, module: &str, name: Option<&str>) -> Result<ImportKey, OutOfMemory> {
1023         Ok(ImportKey {
1024             module: self.pool.insert(module)?,
1025             name: name.map(|name| self.pool.insert(name)).transpose()?,
1026         })
1027     }
1028 
1029     /// Attempts to instantiate the `module` provided.
1030     ///
1031     /// This method will attempt to assemble a list of imports that correspond
1032     /// to the imports required by the [`Module`] provided. This list
1033     /// of imports is then passed to [`Instance::new`] to continue the
1034     /// instantiation process.
1035     ///
1036     /// Each import of `module` will be looked up in this [`Linker`] and must
1037     /// have previously been defined. If it was previously defined with an
1038     /// incorrect signature or if it was not previously defined then an error
1039     /// will be returned because the import can not be satisfied.
1040     ///
1041     /// Per the WebAssembly spec, instantiation includes running the module's
1042     /// start function, if it has one (not to be confused with the `_start`
1043     /// function, which is not run).
1044     ///
1045     /// # Errors
1046     ///
1047     /// This method can fail because an import may not be found, or because
1048     /// instantiation itself may fail. For information on instantiation
1049     /// failures see [`Instance::new`]. If an import is not found, the error
1050     /// may be downcast to an [`UnknownImportError`].
1051     ///
1052     ///
1053     /// # Panics
1054     ///
1055     /// Panics if any item used to instantiate `module` is not owned by
1056     /// `store`. Additionally this will panic if the [`Engine`] that the `store`
1057     /// belongs to is different than this [`Linker`].
1058     ///
1059     /// # Examples
1060     ///
1061     /// ```
1062     /// # use wasmtime::*;
1063     /// # fn main() -> Result<()> {
1064     /// # let engine = Engine::default();
1065     /// # let mut store = Store::new(&engine, ());
1066     /// let mut linker = Linker::new(&engine);
1067     /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
1068     ///
1069     /// let wat = r#"
1070     ///     (module
1071     ///         (import "host" "double" (func (param i32) (result i32)))
1072     ///     )
1073     /// "#;
1074     /// let module = Module::new(&engine, wat)?;
1075     /// linker.instantiate(&mut store, &module)?;
1076     /// # Ok(())
1077     /// # }
1078     /// ```
instantiate( &self, mut store: impl AsContextMut<Data = T>, module: &Module, ) -> Result<Instance> where T: 'static,1079     pub fn instantiate(
1080         &self,
1081         mut store: impl AsContextMut<Data = T>,
1082         module: &Module,
1083     ) -> Result<Instance>
1084     where
1085         T: 'static,
1086     {
1087         self._instantiate_pre(module, Some(store.as_context_mut().0))?
1088             .instantiate(store)
1089     }
1090 
1091     /// Attempts to instantiate the `module` provided. This is the same as
1092     /// [`Linker::instantiate`], except for async `Store`s.
1093     #[cfg(feature = "async")]
instantiate_async( &self, mut store: impl AsContextMut<Data = T>, module: &Module, ) -> Result<Instance> where T: Send + 'static,1094     pub async fn instantiate_async(
1095         &self,
1096         mut store: impl AsContextMut<Data = T>,
1097         module: &Module,
1098     ) -> Result<Instance>
1099     where
1100         T: Send + 'static,
1101     {
1102         self._instantiate_pre(module, Some(store.as_context_mut().0))?
1103             .instantiate_async(store)
1104             .await
1105     }
1106 
1107     /// Performs all checks necessary for instantiating `module` with this
1108     /// linker, except that instantiation doesn't actually finish.
1109     ///
1110     /// This method is used for front-loading type-checking information as well
1111     /// as collecting the imports to use to instantiate a module with. The
1112     /// returned [`InstancePre`] represents a ready-to-be-instantiated module,
1113     /// which can also be instantiated multiple times if desired.
1114     ///
1115     /// # Errors
1116     ///
1117     /// Returns an error which may be downcast to an [`UnknownImportError`] if
1118     /// the module has any unresolvable imports.
1119     ///
1120     /// # Examples
1121     ///
1122     /// ```
1123     /// # use wasmtime::*;
1124     /// # fn main() -> Result<()> {
1125     /// # let engine = Engine::default();
1126     /// # let mut store = Store::new(&engine, ());
1127     /// let mut linker = Linker::new(&engine);
1128     /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
1129     ///
1130     /// let wat = r#"
1131     ///     (module
1132     ///         (import "host" "double" (func (param i32) (result i32)))
1133     ///     )
1134     /// "#;
1135     /// let module = Module::new(&engine, wat)?;
1136     /// let instance_pre = linker.instantiate_pre(&module)?;
1137     ///
1138     /// // Finish instantiation after the type-checking has all completed...
1139     /// let instance = instance_pre.instantiate(&mut store)?;
1140     ///
1141     /// // ... and we can even continue to keep instantiating if desired!
1142     /// instance_pre.instantiate(&mut store)?;
1143     /// instance_pre.instantiate(&mut store)?;
1144     ///
1145     /// // Note that functions defined in a linker with `func_wrap` and similar
1146     /// // constructors are not owned by any particular `Store`, so we can also
1147     /// // instantiate our `instance_pre` in other stores because no imports
1148     /// // belong to the original store.
1149     /// let mut new_store = Store::new(&engine, ());
1150     /// instance_pre.instantiate(&mut new_store)?;
1151     /// # Ok(())
1152     /// # }
1153     /// ```
instantiate_pre(&self, module: &Module) -> Result<InstancePre<T>> where T: 'static,1154     pub fn instantiate_pre(&self, module: &Module) -> Result<InstancePre<T>>
1155     where
1156         T: 'static,
1157     {
1158         self._instantiate_pre(module, None)
1159     }
1160 
1161     /// This is split out to optionally take a `store` so that when the
1162     /// `.instantiate` API is used we can get fresh up-to-date type information
1163     /// for memories and their current size, if necessary.
1164     ///
1165     /// Note that providing a `store` here is not required for correctness
1166     /// per-se. If one is not provided, such as the with the `instantiate_pre`
1167     /// API, then the type information used for memories and tables will reflect
1168     /// their size when inserted into the linker rather than their current size.
1169     /// This isn't expected to be much of a problem though since
1170     /// per-store-`Linker` types are likely using `.instantiate(..)` and
1171     /// per-`Engine` linkers don't have memories/tables in them.
_instantiate_pre( &self, module: &Module, store: Option<&StoreOpaque>, ) -> Result<InstancePre<T>> where T: 'static,1172     fn _instantiate_pre(
1173         &self,
1174         module: &Module,
1175         store: Option<&StoreOpaque>,
1176     ) -> Result<InstancePre<T>>
1177     where
1178         T: 'static,
1179     {
1180         let mut imports: TryVec<_> = module
1181             .imports()
1182             .map(|import| Ok(self._get_by_import(&import)?))
1183             .try_collect::<_, Error>()?;
1184         if let Some(store) = store {
1185             for import in imports.iter_mut() {
1186                 import.update_size(store);
1187             }
1188         }
1189         unsafe { InstancePre::new(module, imports) }
1190     }
1191 
1192     /// Returns an iterator over all items defined in this `Linker`, in
1193     /// arbitrary order.
1194     ///
1195     /// The iterator returned will yield 3-tuples where the first two elements
1196     /// are the module name and item name for the external item, and the third
1197     /// item is the item itself that is defined.
1198     ///
1199     /// Note that multiple `Extern` items may be defined for the same
1200     /// module/name pair.
1201     ///
1202     /// # Panics
1203     ///
1204     /// This function will panic if the `store` provided does not come from the
1205     /// same [`Engine`] that this linker was created with.
iter<'a: 'p, 'p>( &'a self, mut store: impl AsContextMut<Data = T> + 'p, ) -> impl Iterator<Item = (&'a str, &'a str, Extern)> + 'p where T: 'static,1206     pub fn iter<'a: 'p, 'p>(
1207         &'a self,
1208         mut store: impl AsContextMut<Data = T> + 'p,
1209     ) -> impl Iterator<Item = (&'a str, &'a str, Extern)> + 'p
1210     where
1211         T: 'static,
1212     {
1213         self.map.iter().map(move |(key, item)| {
1214             let store = store.as_context_mut();
1215             (
1216                 &self.pool[key.module],
1217                 &self.pool[key.name.unwrap()],
1218                 // Should be safe since `T` is connecting the linker and store
1219                 unsafe { item.to_extern(store.0).panic_on_oom() },
1220             )
1221         })
1222     }
1223 
1224     /// Looks up a previously defined value in this [`Linker`], identified by
1225     /// the names provided.
1226     ///
1227     /// Returns an error if this name was not previously defined in this
1228     /// [`Linker`].
1229     ///
1230     /// # Panics
1231     ///
1232     /// This function will panic if the `store` provided does not come from the
1233     /// same [`Engine`] that this linker was created with.
get( &self, mut store: impl AsContextMut<Data = T>, module: &str, name: &str, ) -> Result<Extern> where T: 'static,1234     pub fn get(
1235         &self,
1236         mut store: impl AsContextMut<Data = T>,
1237         module: &str,
1238         name: &str,
1239     ) -> Result<Extern>
1240     where
1241         T: 'static,
1242     {
1243         let store = store.as_context_mut().0;
1244         match self._get(module, name) {
1245             // Safety: `T` is connecting the linker and store.
1246             Some(def) => Ok(unsafe { def.to_extern(store)? }),
1247             None => bail!("missing definition for `{module}::{name}`"),
1248         }
1249     }
1250 
_get(&self, module: &str, name: &str) -> Option<&Definition>1251     fn _get(&self, module: &str, name: &str) -> Option<&Definition> {
1252         let key = ImportKey {
1253             module: self.pool.get_atom(module)?,
1254             name: Some(self.pool.get_atom(name)?),
1255         };
1256         self.map.get(&key)
1257     }
1258 
1259     /// Looks up a value in this `Linker` which matches the `import` type
1260     /// provided.
1261     ///
1262     /// Returns `None` if no match was found.
1263     ///
1264     /// # Panics
1265     ///
1266     /// This function will panic if the `store` provided does not come from the
1267     /// same [`Engine`] that this linker was created with.
get_by_import( &self, store: impl AsContextMut<Data = T>, import: &ImportType, ) -> Option<Extern> where T: 'static,1268     pub fn get_by_import(
1269         &self,
1270         store: impl AsContextMut<Data = T>,
1271         import: &ImportType,
1272     ) -> Option<Extern>
1273     where
1274         T: 'static,
1275     {
1276         self.try_get_by_import(store, import)
1277             .expect("out of memory")
1278     }
1279 
1280     /// Same as [`Linker::get_by_import`] but returns an error instead of
1281     /// panicking on allocation failure.
try_get_by_import( &self, mut store: impl AsContextMut<Data = T>, import: &ImportType, ) -> Result<Option<Extern>> where T: 'static,1282     pub fn try_get_by_import(
1283         &self,
1284         mut store: impl AsContextMut<Data = T>,
1285         import: &ImportType,
1286     ) -> Result<Option<Extern>>
1287     where
1288         T: 'static,
1289     {
1290         let store = store.as_context_mut().0;
1291         match self._get_by_import(import) {
1292             // Should be safe since `T` is connecting the linker and store
1293             Ok(def) => Ok(Some(unsafe { def.to_extern(store)? })),
1294             Err(_) => Ok(None),
1295         }
1296     }
1297 
_get_by_import(&self, import: &ImportType) -> Result<Definition, UnknownImportError>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.
get_default(&self, mut store: impl AsContextMut<Data = T>, module: &str) -> Result<Func> where T: 'static,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, "").map(Some).or_else(|e| {
1320             if e.is::<OutOfMemory>() {
1321                 Err(e)
1322             } else {
1323                 Ok(None)
1324             }
1325         })? {
1326             if let Extern::Func(func) = external {
1327                 return Ok(func);
1328             }
1329             bail!("default export in '{module}' is not a function");
1330         }
1331 
1332         // For compatibility, also recognize "_start".
1333         if let Some(external) = self
1334             .get(&mut store, module, "_start")
1335             .map(Some)
1336             .or_else(|e| {
1337                 if e.is::<OutOfMemory>() {
1338                     Err(e)
1339                 } else {
1340                     Ok(None)
1341                 }
1342             })?
1343         {
1344             if let Extern::Func(func) = external {
1345                 return Ok(func);
1346             }
1347             bail!("`_start` in '{module}' is not a function");
1348         }
1349 
1350         // Otherwise return a no-op function.
1351         Ok(Func::wrap(store, || {}))
1352     }
1353 }
1354 
1355 impl<T: 'static> Default for Linker<T> {
default() -> Linker<T>1356     fn default() -> Linker<T> {
1357         Linker::new(&Engine::default())
1358     }
1359 }
1360 
1361 impl Definition {
new(store: &StoreOpaque, item: Extern) -> Definition1362     fn new(store: &StoreOpaque, item: Extern) -> Definition {
1363         let ty = DefinitionType::from(store, &item);
1364         Definition::Extern(item, ty)
1365     }
1366 
ty(&self) -> DefinitionType1367     pub(crate) fn ty(&self) -> DefinitionType {
1368         match self {
1369             Definition::Extern(_, ty) => *ty,
1370             Definition::HostFunc(func) => DefinitionType::Func(func.sig_index()),
1371         }
1372     }
1373 
1374     /// Inserts this definition into the `store` provided.
1375     ///
1376     /// # Safety
1377     ///
1378     /// Note the unsafety here is due to calling `HostFunc::to_func`. The
1379     /// requirement here is that the `T` that was originally used to create the
1380     /// `HostFunc` matches the `T` on the store.
to_extern(&self, store: &mut StoreOpaque) -> Result<Extern, OutOfMemory>1381     pub(crate) unsafe fn to_extern(&self, store: &mut StoreOpaque) -> Result<Extern, OutOfMemory> {
1382         match self {
1383             Definition::Extern(e, _) => Ok(e.clone()),
1384             // SAFETY: the contract of this function is the same as what's
1385             // required of `to_func`, that `T` of the store matches the `T` of
1386             // this original definition.
1387             Definition::HostFunc(func) => unsafe { Ok(func.to_func(store)?.into()) },
1388         }
1389     }
1390 
comes_from_same_store(&self, store: &StoreOpaque) -> bool1391     pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque) -> bool {
1392         match self {
1393             Definition::Extern(e, _) => e.comes_from_same_store(store),
1394             Definition::HostFunc(_func) => true,
1395         }
1396     }
1397 
update_size(&mut self, store: &StoreOpaque)1398     fn update_size(&mut self, store: &StoreOpaque) {
1399         match self {
1400             Definition::Extern(Extern::Memory(m), DefinitionType::Memory(_, size)) => {
1401                 *size = m.internal_size(store);
1402             }
1403             Definition::Extern(Extern::SharedMemory(m), DefinitionType::Memory(_, size)) => {
1404                 *size = m.size();
1405             }
1406             Definition::Extern(Extern::Table(m), DefinitionType::Table(_, size)) => {
1407                 *size = m._size(store);
1408             }
1409             _ => {}
1410         }
1411     }
1412 }
1413 
1414 impl DefinitionType {
from(store: &StoreOpaque, item: &Extern) -> DefinitionType1415     pub(crate) fn from(store: &StoreOpaque, item: &Extern) -> DefinitionType {
1416         match item {
1417             Extern::Func(f) => DefinitionType::Func(f.type_index(store)),
1418             Extern::Table(t) => DefinitionType::Table(*t.wasmtime_ty(store), t._size(store)),
1419             Extern::Global(t) => DefinitionType::Global(*t.wasmtime_ty(store)),
1420             Extern::Memory(t) => {
1421                 DefinitionType::Memory(*t.wasmtime_ty(store), t.internal_size(store))
1422             }
1423             Extern::SharedMemory(t) => DefinitionType::Memory(*t.ty().wasmtime_memory(), t.size()),
1424             Extern::Tag(t) => DefinitionType::Tag(*t.wasmtime_ty(store)),
1425         }
1426     }
1427 
desc(&self) -> &'static str1428     pub(crate) fn desc(&self) -> &'static str {
1429         match self {
1430             DefinitionType::Func(_) => "function",
1431             DefinitionType::Table(..) => "table",
1432             DefinitionType::Memory(..) => "memory",
1433             DefinitionType::Global(_) => "global",
1434             DefinitionType::Tag(_) => "tag",
1435         }
1436     }
1437 }
1438 
1439 /// Modules can be interpreted either as Commands or Reactors.
1440 enum ModuleKind {
1441     /// The instance is a Command, meaning an instance is created for each
1442     /// exported function and lives for the duration of the function call.
1443     Command,
1444 
1445     /// The instance is a Reactor, meaning one instance is created which
1446     /// may live across multiple calls.
1447     Reactor,
1448 }
1449 
1450 impl ModuleKind {
1451     /// Determine whether the given module is a Command or a Reactor.
categorize(module: &Module) -> Result<ModuleKind>1452     fn categorize(module: &Module) -> Result<ModuleKind> {
1453         let command_start = module.get_export("_start");
1454         let reactor_start = module.get_export("_initialize");
1455         match (command_start, reactor_start) {
1456             (Some(command_start), None) => {
1457                 if let Some(_) = command_start.func() {
1458                     Ok(ModuleKind::Command)
1459                 } else {
1460                     bail!("`_start` must be a function")
1461                 }
1462             }
1463             (None, Some(reactor_start)) => {
1464                 if let Some(_) = reactor_start.func() {
1465                     Ok(ModuleKind::Reactor)
1466                 } else {
1467                     bail!("`_initialize` must be a function")
1468                 }
1469             }
1470             (None, None) => {
1471                 // Module declares neither of the recognized functions, so treat
1472                 // it as a reactor with no initialization function.
1473                 Ok(ModuleKind::Reactor)
1474             }
1475             (Some(_), Some(_)) => {
1476                 // Module declares itself to be both a Command and a Reactor.
1477                 bail!("Program cannot be both a Command and a Reactor")
1478             }
1479         }
1480     }
1481 }
1482 
1483 /// Error for an unresolvable import.
1484 ///
1485 /// Returned - wrapped in an [`Error`][crate::Error] - by
1486 /// [`Linker::instantiate`] and related methods for modules with unresolvable
1487 /// imports.
1488 #[derive(Clone, Debug)]
1489 pub struct UnknownImportError {
1490     module: String,
1491     name: String,
1492     ty: ExternType,
1493 }
1494 
1495 impl UnknownImportError {
new(import: &ImportType) -> Self1496     fn new(import: &ImportType) -> Self {
1497         Self {
1498             module: import.module().to_string(),
1499             name: import.name().to_string(),
1500             ty: import.ty(),
1501         }
1502     }
1503 
1504     /// Returns the module name that the unknown import was expected to come from.
module(&self) -> &str1505     pub fn module(&self) -> &str {
1506         &self.module
1507     }
1508 
1509     /// Returns the field name of the module that the unknown import was expected to come from.
name(&self) -> &str1510     pub fn name(&self) -> &str {
1511         &self.name
1512     }
1513 
1514     /// Returns the type of the unknown import.
ty(&self) -> ExternType1515     pub fn ty(&self) -> ExternType {
1516         self.ty.clone()
1517     }
1518 }
1519 
1520 impl fmt::Display for UnknownImportError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1521     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1522         write!(
1523             f,
1524             "unknown import: `{}::{}` has not been defined",
1525             self.module, self.name,
1526         )
1527     }
1528 }
1529 
1530 impl core::error::Error for UnknownImportError {}
1531