wasmer_runtime_core_fl/
export.rs

1//! This module contains types to manipulate and access a Wasm module's exports
2//! including memories, tables, globals, and functions.
3use crate::{
4    error,
5    global::Global,
6    instance::{Exports, InstanceInner},
7    memory::Memory,
8    module::ExportIndex,
9    module::ModuleInner,
10    table::Table,
11    types::FuncSig,
12    vm,
13};
14use indexmap::map::Iter as IndexMapIter;
15use std::{ptr::NonNull, sync::Arc};
16
17/// A kind of Context.
18#[derive(Debug, Copy, Clone)]
19pub enum Context {
20    /// External context include a mutable pointer to `Ctx`.
21    External(*mut vm::Ctx),
22
23    /// External context with an environment include a mutable pointer
24    /// to `Ctx` and an optional non-null pointer to `FuncEnv`.
25    ExternalWithEnv(*mut vm::Ctx, Option<NonNull<vm::FuncEnv>>),
26
27    /// Internal context.
28    Internal,
29}
30
31// Manually implemented because context contains a raw pointer to Ctx
32unsafe impl Send for Context {}
33
34/// Kind of WebAssembly export.
35#[derive(Debug, Clone)]
36pub enum Export {
37    /// Function export.
38    Function {
39        /// A pointer to a function.
40        func: FuncPointer,
41        /// A kind of context.
42        ctx: Context,
43        /// The signature of the function.
44        signature: Arc<FuncSig>,
45    },
46    /// Memory export.
47    Memory(Memory),
48    /// Table export.
49    Table(Table),
50    /// Global export.
51    Global(Global),
52}
53
54/// Const pointer to a `Func`.
55#[derive(Debug, Clone)]
56pub struct FuncPointer(*const vm::Func);
57
58// Manually implemented because FuncPointer contains a raw pointer to Ctx
59unsafe impl Send for FuncPointer {}
60
61impl FuncPointer {
62    /// This needs to be unsafe because there is
63    /// no way to check whether the passed function
64    /// is valid and has the right signature.
65    pub unsafe fn new(f: *const vm::Func) -> Self {
66        FuncPointer(f)
67    }
68
69    pub(crate) fn inner(&self) -> *const vm::Func {
70        self.0
71    }
72}
73
74/// An iterator to an instance's exports.
75pub struct ExportIter<'a> {
76    inner: &'a InstanceInner,
77    iter: IndexMapIter<'a, String, ExportIndex>,
78    module: &'a ModuleInner,
79}
80
81impl<'a> ExportIter<'a> {
82    pub(crate) fn new(module: &'a ModuleInner, inner: &'a InstanceInner) -> Self {
83        Self {
84            inner,
85            iter: module.info.exports.iter(),
86            module,
87        }
88    }
89}
90
91impl<'a> Iterator for ExportIter<'a> {
92    type Item = (String, Export);
93    fn next(&mut self) -> Option<(String, Export)> {
94        let (name, export_index) = self.iter.next()?;
95        Some((
96            name.clone(),
97            self.inner.get_export_from_index(&self.module, export_index),
98        ))
99    }
100}
101
102/// This trait is used to mark types as gettable from an [`Instance`].
103pub trait Exportable<'a>: Sized {
104    /// Implementation of how to get the export corresponding to the implementing type
105    /// from an [`Instance`] by name.
106    fn get_self(exports: &'a Exports, name: &str) -> error::ResolveResult<Self>;
107}