wasmer_compiler/translator/
state.rs1use std::boxed::Box;
5use wasmer_types::entity::PrimaryMap;
6use wasmer_types::{SignatureIndex, WasmResult};
7
8pub(crate) type WasmTypes =
10 PrimaryMap<SignatureIndex, (Box<[wasmparser::ValType]>, Box<[wasmparser::ValType]>)>;
11
12#[derive(Debug)]
19pub struct ModuleTranslationState {
20 pub(crate) code_section_offset: Option<usize>,
22
23 pub(crate) wasm_types: WasmTypes,
28}
29
30impl ModuleTranslationState {
31 pub fn new() -> Self {
33 Self {
34 code_section_offset: None,
35 wasm_types: PrimaryMap::new(),
36 }
37 }
38
39 pub fn code_section_offset(&self) -> Option<usize> {
41 self.code_section_offset
42 }
43
44 pub fn blocktype_params_results<'a>(
46 &'a self,
47 ty_or_ft: &'a wasmparser::BlockType,
48 ) -> WasmResult<(&'a [wasmparser::ValType], SingleOrMultiValue<'a>)> {
49 Ok(match ty_or_ft {
50 wasmparser::BlockType::Type(ty) => (&[], SingleOrMultiValue::Single(ty)),
51 wasmparser::BlockType::FuncType(ty_index) => {
52 let sig_idx = SignatureIndex::from_u32(*ty_index);
53 let (ref params, ref results) = self.wasm_types[sig_idx];
54 (params, SingleOrMultiValue::Multi(results.as_ref()))
55 }
56 wasmparser::BlockType::Empty => (&[], SingleOrMultiValue::Multi(&[])),
57 })
58 }
59}
60
61#[derive(Clone)]
63pub enum SingleOrMultiValue<'a> {
64 Single(&'a wasmparser::ValType),
66 Multi(&'a [wasmparser::ValType]),
68}
69
70impl SingleOrMultiValue<'_> {
71 pub fn is_empty(&self) -> bool {
73 match self {
74 SingleOrMultiValue::Single(_) => false,
75 SingleOrMultiValue::Multi(values) => values.is_empty(),
76 }
77 }
78
79 pub fn len(&self) -> usize {
81 match self {
82 SingleOrMultiValue::Single(_) => 1,
83 SingleOrMultiValue::Multi(values) => values.len(),
84 }
85 }
86
87 pub fn iter(&self) -> SingleOrMultiValueIterator<'_> {
89 match self {
90 SingleOrMultiValue::Single(v) => SingleOrMultiValueIterator::Single(v),
91 SingleOrMultiValue::Multi(items) => SingleOrMultiValueIterator::Multi {
92 index: 0,
93 values: items,
94 },
95 }
96 }
97}
98
99pub enum SingleOrMultiValueIterator<'a> {
100 Done,
101 Single(&'a wasmparser::ValType),
102 Multi {
103 index: usize,
104 values: &'a [wasmparser::ValType],
105 },
106}
107
108impl<'a> Iterator for SingleOrMultiValueIterator<'a> {
109 type Item = &'a wasmparser::ValType;
110
111 fn next(&mut self) -> Option<Self::Item> {
112 match self {
113 SingleOrMultiValueIterator::Done => None,
114 SingleOrMultiValueIterator::Single(v) => {
115 let v = *v;
116 *self = SingleOrMultiValueIterator::Done;
117 Some(v)
118 }
119 SingleOrMultiValueIterator::Multi { index, values } => {
120 if let Some(x) = values.get(*index) {
121 *index += 1;
122 Some(x)
123 } else {
124 *self = SingleOrMultiValueIterator::Done;
125 None
126 }
127 }
128 }
129 }
130}
131
132impl PartialEq<[wasmparser::ValType]> for SingleOrMultiValue<'_> {
133 fn eq(&self, other: &[wasmparser::ValType]) -> bool {
134 match self {
135 SingleOrMultiValue::Single(ty) => other.len() == 1 && &other[0] == *ty,
136 SingleOrMultiValue::Multi(tys) => *tys == other,
137 }
138 }
139}
140
141impl<'a> PartialEq<SingleOrMultiValue<'a>> for &'a [wasmparser::ValType] {
142 fn eq(&self, other: &SingleOrMultiValue<'a>) -> bool {
143 match other {
144 SingleOrMultiValue::Single(ty) => self.len() == 1 && &self[0] == *ty,
145 SingleOrMultiValue::Multi(tys) => tys == self,
146 }
147 }
148}