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