soroban_wasmi/module/
export.rs

1use super::GlobalIdx;
2use crate::{collections::map::Iter as MapIter, Error, ExternType, Module};
3use std::boxed::Box;
4
5/// The index of a function declaration within a [`Module`].
6///
7/// [`Module`]: [`super::Module`]
8#[derive(Debug, Copy, Clone)]
9pub struct FuncIdx(u32);
10
11impl From<u32> for FuncIdx {
12    fn from(index: u32) -> Self {
13        Self(index)
14    }
15}
16
17impl FuncIdx {
18    /// Returns the [`FuncIdx`] as `u32`.
19    pub fn into_u32(self) -> u32 {
20        self.0
21    }
22}
23
24/// The index of a table declaration within a [`Module`].
25///
26/// [`Module`]: [`super::Module`]
27#[derive(Debug, Copy, Clone)]
28pub struct TableIdx(u32);
29
30impl From<u32> for TableIdx {
31    fn from(index: u32) -> Self {
32        Self(index)
33    }
34}
35
36impl TableIdx {
37    /// Returns the [`TableIdx`] as `u32`.
38    pub fn into_u32(self) -> u32 {
39        self.0
40    }
41}
42
43/// The index of a linear memory declaration within a [`Module`].
44///
45/// [`Module`]: [`super::Module`]
46#[derive(Debug, Copy, Clone)]
47pub struct MemoryIdx(u32);
48
49impl From<u32> for MemoryIdx {
50    fn from(index: u32) -> Self {
51        Self(index)
52    }
53}
54
55impl MemoryIdx {
56    /// Returns the [`MemoryIdx`] as `u32`.
57    pub fn into_u32(self) -> u32 {
58        self.0
59    }
60}
61
62/// An external item of an [`ExportType`] definition within a [`Module`].
63///
64/// [`Module`]: [`crate::Module`]
65#[derive(Debug, Copy, Clone)]
66pub enum ExternIdx {
67    /// An exported function and its index within the [`Module`].
68    ///
69    /// [`Module`]: [`super::Module`]
70    Func(FuncIdx),
71    /// An exported table and its index within the [`Module`].
72    ///
73    /// [`Module`]: [`super::Module`]
74    Table(TableIdx),
75    /// An exported linear memory and its index within the [`Module`].
76    ///
77    /// [`Module`]: [`super::Module`]
78    Memory(MemoryIdx),
79    /// An exported global variable and its index within the [`Module`].
80    ///
81    /// [`Module`]: [`super::Module`]
82    Global(GlobalIdx),
83}
84
85impl ExternIdx {
86    /// Create a new [`ExternIdx`] from the given [`wasmparser::ExternalKind`] and `index`.
87    ///
88    /// # Errors
89    ///
90    /// If an unsupported external definition is encountered.
91    pub fn new(kind: wasmparser::ExternalKind, index: u32) -> Result<Self, Error> {
92        match kind {
93            wasmparser::ExternalKind::Func => Ok(ExternIdx::Func(FuncIdx(index))),
94            wasmparser::ExternalKind::Table => Ok(ExternIdx::Table(TableIdx(index))),
95            wasmparser::ExternalKind::Memory => Ok(ExternIdx::Memory(MemoryIdx(index))),
96            wasmparser::ExternalKind::Global => Ok(ExternIdx::Global(GlobalIdx::from(index))),
97            wasmparser::ExternalKind::Tag => {
98                panic!("wasmi does not support the `exception-handling` Wasm proposal")
99            }
100        }
101    }
102}
103
104/// An iterator over the exports of a [`Module`].
105///
106/// [`Module`]: [`super::Module`]
107#[derive(Debug)]
108pub struct ModuleExportsIter<'module> {
109    exports: MapIter<'module, Box<str>, ExternIdx>,
110    module: &'module Module,
111}
112
113/// A descriptor for an exported WebAssembly value of a [`Module`].
114///
115/// This type is primarily accessed from the [`Module::exports`] method and describes
116/// what names are exported from a Wasm [`Module`] and the type of the item that is exported.
117#[derive(Debug)]
118pub struct ExportType<'module> {
119    name: &'module str,
120    ty: ExternType,
121}
122
123impl<'module> ExportType<'module> {
124    /// Returns the name by which the export is known.
125    pub fn name(&self) -> &'module str {
126        self.name
127    }
128
129    /// Returns the type of the exported item.
130    pub fn ty(&self) -> &ExternType {
131        &self.ty
132    }
133}
134
135impl<'module> ModuleExportsIter<'module> {
136    /// Creates a new [`ModuleExportsIter`] from the given [`Module`].
137    pub(super) fn new(module: &'module Module) -> Self {
138        Self {
139            exports: module.module_header().exports.iter(),
140            module,
141        }
142    }
143}
144
145impl<'module> Iterator for ModuleExportsIter<'module> {
146    type Item = ExportType<'module>;
147
148    fn next(&mut self) -> Option<Self::Item> {
149        self.exports.next().map(|(name, idx)| {
150            let ty = self.module.get_extern_type(*idx);
151            ExportType { name, ty }
152        })
153    }
154}