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) wasm_types: WasmTypes,
25}
26
27impl ModuleTranslationState {
28 pub fn new() -> Self {
30 Self {
31 wasm_types: PrimaryMap::new(),
32 }
33 }
34
35 pub fn blocktype_params_results<'a>(
37 &'a self,
38 ty_or_ft: &'a wasmparser::BlockType,
39 ) -> WasmResult<(&'a [wasmparser::ValType], SingleOrMultiValue<'a>)> {
40 Ok(match ty_or_ft {
41 wasmparser::BlockType::Type(ty) => (&[], SingleOrMultiValue::Single(ty)),
42 wasmparser::BlockType::FuncType(ty_index) => {
43 let sig_idx = SignatureIndex::from_u32(*ty_index);
44 let (ref params, ref results) = self.wasm_types[sig_idx];
45 (params, SingleOrMultiValue::Multi(results.as_ref()))
46 }
47 wasmparser::BlockType::Empty => (&[], SingleOrMultiValue::Multi(&[])),
48 })
49 }
50}
51
52#[derive(Clone)]
54pub enum SingleOrMultiValue<'a> {
55 Single(&'a wasmparser::ValType),
57 Multi(&'a [wasmparser::ValType]),
59}
60
61impl<'a> SingleOrMultiValue<'a> {
62 pub fn is_empty(&self) -> bool {
64 match self {
65 SingleOrMultiValue::Single(_) => false,
66 SingleOrMultiValue::Multi(values) => values.is_empty(),
67 }
68 }
69
70 pub fn len(&self) -> usize {
72 match self {
73 SingleOrMultiValue::Single(_) => 1,
74 SingleOrMultiValue::Multi(values) => values.len(),
75 }
76 }
77
78 pub fn iter(&self) -> SingleOrMultiValueIterator<'_> {
80 match self {
81 SingleOrMultiValue::Single(v) => SingleOrMultiValueIterator::Single(v),
82 SingleOrMultiValue::Multi(items) => SingleOrMultiValueIterator::Multi {
83 index: 0,
84 values: items,
85 },
86 }
87 }
88}
89
90pub enum SingleOrMultiValueIterator<'a> {
91 Done,
92 Single(&'a wasmparser::ValType),
93 Multi {
94 index: usize,
95 values: &'a [wasmparser::ValType],
96 },
97}
98
99impl<'a> Iterator for SingleOrMultiValueIterator<'a> {
100 type Item = &'a wasmparser::ValType;
101
102 fn next(&mut self) -> Option<Self::Item> {
103 match self {
104 SingleOrMultiValueIterator::Done => None,
105 SingleOrMultiValueIterator::Single(v) => {
106 let v = *v;
107 *self = SingleOrMultiValueIterator::Done;
108 Some(v)
109 }
110 SingleOrMultiValueIterator::Multi { index, values } => {
111 if let Some(x) = values.get(*index) {
112 *index += 1;
113 Some(x)
114 } else {
115 *self = SingleOrMultiValueIterator::Done;
116 None
117 }
118 }
119 }
120 }
121}
122
123impl<'a> PartialEq<[wasmparser::ValType]> for SingleOrMultiValue<'a> {
124 fn eq(&self, other: &[wasmparser::ValType]) -> bool {
125 match self {
126 SingleOrMultiValue::Single(ty) => other.len() == 1 && &other[0] == *ty,
127 SingleOrMultiValue::Multi(tys) => *tys == other,
128 }
129 }
130}
131
132impl<'a> PartialEq<SingleOrMultiValue<'a>> for &'a [wasmparser::ValType] {
133 fn eq(&self, other: &SingleOrMultiValue<'a>) -> bool {
134 match other {
135 SingleOrMultiValue::Single(ty) => self.len() == 1 && &self[0] == *ty,
136 SingleOrMultiValue::Multi(tys) => tys == self,
137 }
138 }
139}