zingen/wasm/
func.rs

1//! Function handler
2use crate::{wasm::Exports, Error, Result};
3use std::{
4    collections::BTreeMap,
5    ops::{Deref, DerefMut},
6};
7use wasmparser::{FuncType, FuncValidator, FunctionBody, ValidatorResources, WasmModuleResources};
8
9/// Function with validator.
10pub struct Function<'f> {
11    /// Function validator.
12    pub validator: FuncValidator<ValidatorResources>,
13    /// Function body.
14    pub body: FunctionBody<'f>,
15}
16
17impl Function<'_> {
18    /// Get function index.
19    pub fn index(&self) -> u32 {
20        self.validator.index()
21    }
22
23    /// Get the function signature.
24    pub fn sig(&self) -> Result<FuncType> {
25        let func_index = self.validator.index();
26        let sig = self
27            .validator
28            .resources()
29            .type_of_function(func_index)
30            .ok_or(Error::InvalidFunctionSignature)?
31            .clone();
32
33        Ok(sig)
34    }
35}
36
37/// WASM Functions by indexes.
38#[derive(Default)]
39pub struct Functions<'f>(BTreeMap<u32, Function<'f>>);
40
41impl<'f> Functions<'f> {
42    /// Add function to the list.
43    pub fn add(
44        &mut self,
45        validator: FuncValidator<ValidatorResources>,
46        function: FunctionBody<'f>,
47    ) {
48        self.0.insert(
49            validator.index(),
50            Function {
51                validator,
52                body: function,
53            },
54        );
55    }
56
57    /// Remove all selector functions
58    pub fn drain_selectors(&mut self, exports: &Exports) -> Self {
59        let mut functions = Self::default();
60
61        for index in exports.selectors() {
62            if let Some(function) = self.0.remove(&index) {
63                functions.0.insert(index, function);
64            }
65        }
66
67        functions
68    }
69
70    /// Get all functions
71    pub fn into_funcs(self) -> Vec<Function<'f>> {
72        self.0.into_values().collect()
73    }
74}
75
76impl<'f> Deref for Functions<'f> {
77    type Target = BTreeMap<u32, Function<'f>>;
78
79    fn deref(&self) -> &Self::Target {
80        &self.0
81    }
82}
83
84impl DerefMut for Functions<'_> {
85    fn deref_mut(&mut self) -> &mut Self::Target {
86        &mut self.0
87    }
88}