dusk_wasmtime_environ/
module_types.rs1use 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#[derive(Default, Serialize, Deserialize)]
17#[allow(missing_docs)]
18pub struct ModuleTypes {
19 wasm_types: PrimaryMap<ModuleInternedTypeIndex, WasmFuncType>,
20}
21
22impl ModuleTypes {
23 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#[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 pub fn reserve_wasm_signatures(&mut self, amt: usize) {
50 self.types.wasm_types.reserve(amt);
51 }
52
53 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 pub fn finish(self) -> ModuleTypes {
74 self.types
75 }
76
77 pub fn wasm_signatures(
80 &self,
81 ) -> impl Iterator<Item = (ModuleInternedTypeIndex, &WasmFuncType)> {
82 self.types.wasm_types()
83 }
84}
85
86impl<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}