radix_wasmi/module/
export.rs

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