wasmtime_environ/
module_types.rs1use crate::{
2 ModuleInternedRecGroupIndex, ModuleInternedTypeIndex, PrimaryMap, TypeTrace, WasmSubType,
3};
4use core::ops::{Index, Range};
5use cranelift_entity::{packed_option::PackedOption, SecondaryMap};
6use serde_derive::{Deserialize, Serialize};
7
8#[derive(Default, Serialize, Deserialize)]
13pub struct ModuleTypes {
14 rec_groups: PrimaryMap<ModuleInternedRecGroupIndex, Range<ModuleInternedTypeIndex>>,
15 wasm_types: PrimaryMap<ModuleInternedTypeIndex, WasmSubType>,
16 trampoline_types: SecondaryMap<ModuleInternedTypeIndex, PackedOption<ModuleInternedTypeIndex>>,
17}
18
19impl TypeTrace for ModuleTypes {
20 fn trace<F, E>(&self, func: &mut F) -> Result<(), E>
21 where
22 F: FnMut(crate::EngineOrModuleTypeIndex) -> Result<(), E>,
23 {
24 for ty in self.wasm_types.values() {
25 ty.trace(func)?;
26 }
27 Ok(())
28 }
29
30 fn trace_mut<F, E>(&mut self, func: &mut F) -> Result<(), E>
31 where
32 F: FnMut(&mut crate::EngineOrModuleTypeIndex) -> Result<(), E>,
33 {
34 for ty in self.wasm_types.values_mut() {
35 ty.trace_mut(func)?;
36 }
37 Ok(())
38 }
39}
40
41impl ModuleTypes {
42 pub fn wasm_types(
45 &self,
46 ) -> impl ExactSizeIterator<Item = (ModuleInternedTypeIndex, &WasmSubType)> {
47 self.wasm_types.iter()
48 }
49
50 pub fn get(&self, ty: ModuleInternedTypeIndex) -> Option<&WasmSubType> {
52 self.wasm_types.get(ty)
53 }
54
55 pub fn rec_groups(
58 &self,
59 ) -> impl ExactSizeIterator<Item = (ModuleInternedRecGroupIndex, Range<ModuleInternedTypeIndex>)> + '_
60 {
61 self.rec_groups.iter().map(|(k, v)| (k, v.clone()))
62 }
63
64 pub fn rec_group_elements(
66 &self,
67 rec_group: ModuleInternedRecGroupIndex,
68 ) -> impl ExactSizeIterator<Item = ModuleInternedTypeIndex> + use<> {
69 let range = &self.rec_groups[rec_group];
70 (range.start.as_u32()..range.end.as_u32()).map(|i| ModuleInternedTypeIndex::from_u32(i))
71 }
72
73 pub fn len_types(&self) -> usize {
75 self.wasm_types.len()
76 }
77
78 pub fn push(&mut self, ty: WasmSubType) -> ModuleInternedTypeIndex {
80 self.wasm_types.push(ty)
81 }
82
83 pub fn trampoline_types(
91 &self,
92 ) -> impl Iterator<Item = (ModuleInternedTypeIndex, ModuleInternedTypeIndex)> + '_ {
93 self.trampoline_types
94 .iter()
95 .filter_map(|(k, v)| v.expand().map(|v| (k, v)))
96 }
97
98 pub fn trampoline_type(&self, ty: ModuleInternedTypeIndex) -> ModuleInternedTypeIndex {
103 debug_assert!(self[ty].is_func());
104 self.trampoline_types[ty].unwrap()
105 }
106
107 pub fn iter_mut(&mut self) -> impl ExactSizeIterator<Item = &mut WasmSubType> {
109 self.wasm_types.iter_mut().map(|(_id, ty)| ty)
110 }
111}
112
113#[cfg(feature = "compile")]
115impl ModuleTypes {
116 pub fn set_trampoline_type(
118 &mut self,
119 for_ty: ModuleInternedTypeIndex,
120 trampoline_ty: ModuleInternedTypeIndex,
121 ) {
122 use cranelift_entity::packed_option::ReservedValue;
123
124 debug_assert!(!for_ty.is_reserved_value());
125 debug_assert!(!trampoline_ty.is_reserved_value());
126 debug_assert!(self.wasm_types[for_ty].is_func());
127 debug_assert!(self.trampoline_types[for_ty].is_none());
128 debug_assert!(self.wasm_types[trampoline_ty]
129 .unwrap_func()
130 .is_trampoline_type());
131
132 self.trampoline_types[for_ty] = Some(trampoline_ty).into();
133 }
134
135 pub fn push_rec_group(
137 &mut self,
138 range: Range<ModuleInternedTypeIndex>,
139 ) -> ModuleInternedRecGroupIndex {
140 self.rec_groups.push(range)
141 }
142
143 pub fn reserve(&mut self, amt: usize) {
145 self.wasm_types.reserve(amt)
146 }
147
148 pub fn next_rec_group(&self) -> ModuleInternedRecGroupIndex {
150 self.rec_groups.next_key()
151 }
152
153 pub fn next_ty(&self) -> ModuleInternedTypeIndex {
155 self.wasm_types.next_key()
156 }
157}
158
159impl Index<ModuleInternedTypeIndex> for ModuleTypes {
160 type Output = WasmSubType;
161
162 fn index(&self, sig: ModuleInternedTypeIndex) -> &WasmSubType {
163 &self.wasm_types[sig]
164 }
165}