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