wasmtime_environ/
module_types.rs1use crate::{ModuleInternedRecGroupIndex, ModuleInternedTypeIndex, PrimaryMap, WasmSubType};
2use core::ops::{Index, Range};
3use cranelift_entity::{packed_option::PackedOption, SecondaryMap};
4use serde_derive::{Deserialize, Serialize};
5
6#[derive(Default, Serialize, Deserialize)]
11pub struct ModuleTypes {
12 rec_groups: PrimaryMap<ModuleInternedRecGroupIndex, Range<ModuleInternedTypeIndex>>,
13 wasm_types: PrimaryMap<ModuleInternedTypeIndex, WasmSubType>,
14 trampoline_types: SecondaryMap<ModuleInternedTypeIndex, PackedOption<ModuleInternedTypeIndex>>,
15}
16
17impl ModuleTypes {
18 pub fn wasm_types(
21 &self,
22 ) -> impl ExactSizeIterator<Item = (ModuleInternedTypeIndex, &WasmSubType)> {
23 self.wasm_types.iter()
24 }
25
26 pub fn get(&self, ty: ModuleInternedTypeIndex) -> Option<&WasmSubType> {
28 self.wasm_types.get(ty)
29 }
30
31 pub fn rec_groups(
34 &self,
35 ) -> impl ExactSizeIterator<Item = (ModuleInternedRecGroupIndex, Range<ModuleInternedTypeIndex>)> + '_
36 {
37 self.rec_groups.iter().map(|(k, v)| (k, v.clone()))
38 }
39
40 pub fn rec_group_elements(
42 &self,
43 rec_group: ModuleInternedRecGroupIndex,
44 ) -> impl ExactSizeIterator<Item = ModuleInternedTypeIndex> + use<> {
45 let range = &self.rec_groups[rec_group];
46 (range.start.as_u32()..range.end.as_u32()).map(|i| ModuleInternedTypeIndex::from_u32(i))
47 }
48
49 pub fn len_types(&self) -> usize {
51 self.wasm_types.len()
52 }
53
54 pub fn push(&mut self, ty: WasmSubType) -> ModuleInternedTypeIndex {
56 self.wasm_types.push(ty)
57 }
58
59 pub fn trampoline_types(
67 &self,
68 ) -> impl Iterator<Item = (ModuleInternedTypeIndex, ModuleInternedTypeIndex)> + '_ {
69 self.trampoline_types
70 .iter()
71 .filter_map(|(k, v)| v.expand().map(|v| (k, v)))
72 }
73
74 pub fn trampoline_type(&self, ty: ModuleInternedTypeIndex) -> ModuleInternedTypeIndex {
79 debug_assert!(self[ty].is_func());
80 self.trampoline_types[ty].unwrap()
81 }
82}
83
84#[cfg(feature = "compile")]
86impl ModuleTypes {
87 pub fn set_trampoline_type(
89 &mut self,
90 for_ty: ModuleInternedTypeIndex,
91 trampoline_ty: ModuleInternedTypeIndex,
92 ) {
93 use cranelift_entity::packed_option::ReservedValue;
94
95 debug_assert!(!for_ty.is_reserved_value());
96 debug_assert!(!trampoline_ty.is_reserved_value());
97 debug_assert!(self.wasm_types[for_ty].is_func());
98 debug_assert!(self.trampoline_types[for_ty].is_none());
99 debug_assert!(self.wasm_types[trampoline_ty]
100 .unwrap_func()
101 .is_trampoline_type());
102
103 self.trampoline_types[for_ty] = Some(trampoline_ty).into();
104 }
105
106 pub fn push_rec_group(
108 &mut self,
109 range: Range<ModuleInternedTypeIndex>,
110 ) -> ModuleInternedRecGroupIndex {
111 self.rec_groups.push(range)
112 }
113
114 pub fn reserve(&mut self, amt: usize) {
116 self.wasm_types.reserve(amt)
117 }
118
119 pub fn next_rec_group(&self) -> ModuleInternedRecGroupIndex {
121 self.rec_groups.next_key()
122 }
123
124 pub fn next_ty(&self) -> ModuleInternedTypeIndex {
126 self.wasm_types.next_key()
127 }
128}
129
130impl Index<ModuleInternedTypeIndex> for ModuleTypes {
131 type Output = WasmSubType;
132
133 fn index(&self, sig: ModuleInternedTypeIndex) -> &WasmSubType {
134 &self.wasm_types[sig]
135 }
136}