dusk_wasmtime_environ/
module_types.rs

1use crate::{Module, ModuleType, PrimaryMap, TypeConvert, WasmFuncType, WasmHeapType};
2use serde_derive::{Deserialize, Serialize};
3use std::collections::HashMap;
4use std::ops::Index;
5use wasmparser::types::CoreTypeId;
6use wasmparser::UnpackedIndex;
7use wasmtime_types::{EngineOrModuleTypeIndex, ModuleInternedTypeIndex, TypeIndex};
8
9/// All types used in a core wasm module.
10///
11/// At this time this only contains function types. Note, though, that function
12/// types are deduplicated within this [`ModuleTypes`].
13///
14/// Note that accesing this type is primarily done through the `Index`
15/// implementations for this type.
16#[derive(Default, Serialize, Deserialize)]
17#[allow(missing_docs)]
18pub struct ModuleTypes {
19    wasm_types: PrimaryMap<ModuleInternedTypeIndex, WasmFuncType>,
20}
21
22impl ModuleTypes {
23    /// Returns an iterator over all the wasm function signatures found within
24    /// this module.
25    pub fn wasm_types(&self) -> impl Iterator<Item = (ModuleInternedTypeIndex, &WasmFuncType)> {
26        self.wasm_types.iter()
27    }
28}
29
30impl Index<ModuleInternedTypeIndex> for ModuleTypes {
31    type Output = WasmFuncType;
32
33    fn index(&self, sig: ModuleInternedTypeIndex) -> &WasmFuncType {
34        &self.wasm_types[sig]
35    }
36}
37
38/// A builder for [`ModuleTypes`].
39#[derive(Default)]
40#[allow(missing_docs)]
41pub struct ModuleTypesBuilder {
42    types: ModuleTypes,
43    interned_func_types: HashMap<WasmFuncType, ModuleInternedTypeIndex>,
44    wasmparser_to_wasmtime: HashMap<CoreTypeId, ModuleInternedTypeIndex>,
45}
46
47impl ModuleTypesBuilder {
48    /// Reserves space for `amt` more type signatures.
49    pub fn reserve_wasm_signatures(&mut self, amt: usize) {
50        self.types.wasm_types.reserve(amt);
51    }
52
53    /// Interns the `sig` specified and returns a unique `SignatureIndex` that
54    /// can be looked up within [`ModuleTypes`] to recover the [`WasmFuncType`]
55    /// at runtime.
56    pub fn wasm_func_type(&mut self, id: CoreTypeId, sig: WasmFuncType) -> ModuleInternedTypeIndex {
57        let sig = self.intern_func_type(sig);
58        self.wasmparser_to_wasmtime.insert(id, sig);
59        sig
60    }
61
62    fn intern_func_type(&mut self, sig: WasmFuncType) -> ModuleInternedTypeIndex {
63        if let Some(idx) = self.interned_func_types.get(&sig) {
64            return *idx;
65        }
66
67        let idx = self.types.wasm_types.push(sig.clone());
68        self.interned_func_types.insert(sig, idx);
69        return idx;
70    }
71
72    /// Returns the result [`ModuleTypes`] of this builder.
73    pub fn finish(self) -> ModuleTypes {
74        self.types
75    }
76
77    /// Returns an iterator over all the wasm function signatures found within
78    /// this module.
79    pub fn wasm_signatures(
80        &self,
81    ) -> impl Iterator<Item = (ModuleInternedTypeIndex, &WasmFuncType)> {
82        self.types.wasm_types()
83    }
84}
85
86// Forward the indexing impl to the internal `ModuleTypes`
87impl<T> Index<T> for ModuleTypesBuilder
88where
89    ModuleTypes: Index<T>,
90{
91    type Output = <ModuleTypes as Index<T>>::Output;
92
93    fn index(&self, sig: T) -> &Self::Output {
94        &self.types[sig]
95    }
96}
97
98#[allow(missing_docs)]
99pub struct WasmparserTypeConverter<'a> {
100    pub types: &'a ModuleTypesBuilder,
101    pub module: &'a Module,
102}
103
104impl TypeConvert for WasmparserTypeConverter<'_> {
105    fn lookup_heap_type(&self, index: UnpackedIndex) -> WasmHeapType {
106        match index {
107            UnpackedIndex::Id(id) => {
108                let signature = self.types.wasmparser_to_wasmtime[&id];
109                WasmHeapType::Concrete(EngineOrModuleTypeIndex::Module(signature))
110            }
111            UnpackedIndex::RecGroup(_) => unreachable!(),
112            UnpackedIndex::Module(i) => {
113                let i = TypeIndex::from_u32(i);
114                match self.module.types[i] {
115                    ModuleType::Function(sig) => {
116                        WasmHeapType::Concrete(EngineOrModuleTypeIndex::Module(sig))
117                    }
118                }
119            }
120        }
121    }
122}