wasmer_compiler/translator/
middleware.rs1use smallvec::SmallVec;
5use std::collections::VecDeque;
6use std::fmt::Debug;
7use std::ops::{Deref, Range};
8use wasmer_types::{LocalFunctionIndex, MiddlewareError, ModuleInfo, WasmError, WasmResult};
9use wasmparser::{BinaryReader, FunctionBody, Operator, OperatorsReader, ValType};
10
11use super::error::from_binaryreadererror_wasmerror;
12use crate::translator::environ::FunctionBinaryReader;
13
14pub trait ModuleMiddleware: Debug + Send + Sync {
16 fn generate_function_middleware(
22 &self,
23 local_function_index: LocalFunctionIndex,
24 ) -> Box<dyn FunctionMiddleware>;
25
26 fn transform_module_info(&self, _: &mut ModuleInfo) -> Result<(), MiddlewareError> {
28 Ok(())
29 }
30}
31
32pub trait FunctionMiddleware: Debug {
34 fn feed<'a>(
36 &mut self,
37 operator: Operator<'a>,
38 state: &mut MiddlewareReaderState<'a>,
39 ) -> Result<(), MiddlewareError> {
40 state.push_operator(operator);
41 Ok(())
42 }
43}
44
45pub struct MiddlewareBinaryReader<'a> {
47 state: MiddlewareReaderState<'a>,
49
50 chain: Vec<Box<dyn FunctionMiddleware>>,
52}
53
54enum MiddlewareInnerReader<'a> {
55 Binary {
56 reader: BinaryReader<'a>,
57 original_reader: BinaryReader<'a>,
58 },
59 Operator(OperatorsReader<'a>),
60}
61
62pub struct MiddlewareReaderState<'a> {
64 inner: Option<MiddlewareInnerReader<'a>>,
66
67 pending_operations: VecDeque<Operator<'a>>,
69}
70
71pub trait ModuleMiddlewareChain {
73 fn generate_function_middleware_chain(
75 &self,
76 local_function_index: LocalFunctionIndex,
77 ) -> Vec<Box<dyn FunctionMiddleware>>;
78
79 fn apply_on_module_info(&self, module_info: &mut ModuleInfo) -> Result<(), MiddlewareError>;
81}
82
83impl<T: Deref<Target = dyn ModuleMiddleware>> ModuleMiddlewareChain for [T] {
84 fn generate_function_middleware_chain(
86 &self,
87 local_function_index: LocalFunctionIndex,
88 ) -> Vec<Box<dyn FunctionMiddleware>> {
89 self.iter()
90 .map(|x| x.generate_function_middleware(local_function_index))
91 .collect()
92 }
93
94 fn apply_on_module_info(&self, module_info: &mut ModuleInfo) -> Result<(), MiddlewareError> {
96 for item in self {
97 item.transform_module_info(module_info)?;
98 }
99 Ok(())
100 }
101}
102
103impl<'a> MiddlewareReaderState<'a> {
104 pub fn push_operator(&mut self, operator: Operator<'a>) {
106 self.pending_operations.push_back(operator);
107 }
108}
109
110impl<'a> Extend<Operator<'a>> for MiddlewareReaderState<'a> {
111 fn extend<I: IntoIterator<Item = Operator<'a>>>(&mut self, iter: I) {
112 self.pending_operations.extend(iter);
113 }
114}
115
116impl<'a: 'b, 'b> Extend<&'b Operator<'a>> for MiddlewareReaderState<'a> {
117 fn extend<I: IntoIterator<Item = &'b Operator<'a>>>(&mut self, iter: I) {
118 self.pending_operations.extend(iter.into_iter().cloned());
119 }
120}
121
122impl<'a> MiddlewareBinaryReader<'a> {
123 pub fn new_with_offset(data: &'a [u8], original_offset: usize) -> Self {
125 let inner = BinaryReader::new(data, original_offset);
126 Self {
127 state: MiddlewareReaderState {
128 inner: Some(MiddlewareInnerReader::Binary {
129 original_reader: inner.clone(),
130 reader: inner,
131 }),
132 pending_operations: VecDeque::new(),
133 },
134 chain: vec![],
135 }
136 }
137
138 pub fn set_middleware_chain(&mut self, stages: Vec<Box<dyn FunctionMiddleware>>) {
140 self.chain = stages;
141 }
142}
143
144impl<'a> FunctionBinaryReader<'a> for MiddlewareBinaryReader<'a> {
145 fn read_local_count(&mut self) -> WasmResult<u32> {
146 match self.state.inner.as_mut().expect("inner state must exist") {
147 MiddlewareInnerReader::Binary { reader, .. } => reader
148 .read_var_u32()
149 .map_err(from_binaryreadererror_wasmerror),
150 MiddlewareInnerReader::Operator(..) => Err(WasmError::InvalidWebAssembly {
151 message: "locals must be read before the function body".to_string(),
152 offset: self.current_position(),
153 }),
154 }
155 }
156
157 fn read_local_decl(&mut self) -> WasmResult<(u32, ValType)> {
158 match self.state.inner.as_mut().expect("inner state must exist") {
159 MiddlewareInnerReader::Binary { reader, .. } => {
160 let count = reader
161 .read_var_u32()
162 .map_err(from_binaryreadererror_wasmerror)?;
163 let ty: ValType = reader
164 .read::<ValType>()
165 .map_err(from_binaryreadererror_wasmerror)?;
166 Ok((count, ty))
167 }
168 MiddlewareInnerReader::Operator(..) => Err(WasmError::InvalidWebAssembly {
169 message: "locals must be read before the function body".to_string(),
170 offset: self.current_position(),
171 }),
172 }
173 }
174
175 fn read_operator(&mut self) -> WasmResult<Operator<'a>> {
176 if let Some(inner) = self.state.inner.take() {
177 self.state.inner = Some(match inner {
178 MiddlewareInnerReader::Binary {
179 original_reader, ..
180 } => {
181 let operator_reader = FunctionBody::new(original_reader)
182 .get_operators_reader()
183 .map_err(from_binaryreadererror_wasmerror)?;
184 MiddlewareInnerReader::Operator(operator_reader)
185 }
186 other => other,
187 });
188 }
189
190 let read_operator = |state: &mut MiddlewareReaderState<'a>| {
191 let Some(MiddlewareInnerReader::Operator(operator_reader)) = state.inner.as_mut()
192 else {
193 unreachable!();
194 };
195 operator_reader
196 .read()
197 .map_err(from_binaryreadererror_wasmerror)
198 };
199
200 if self.chain.is_empty() {
201 return read_operator(&mut self.state);
203 }
204
205 while self.state.pending_operations.is_empty() {
207 let raw_op = read_operator(&mut self.state)?;
208
209 self.state.pending_operations.push_back(raw_op);
211
212 for stage in &mut self.chain {
214 let pending: SmallVec<[Operator<'a>; 2]> =
216 self.state.pending_operations.drain(0..).collect();
217
218 for pending_op in pending {
220 stage.feed(pending_op, &mut self.state)?;
221 }
222 }
223 }
224
225 Ok(self.state.pending_operations.pop_front().unwrap())
226 }
227
228 fn current_position(&self) -> usize {
229 match self.state.inner.as_ref().expect("inner state must exist") {
230 MiddlewareInnerReader::Binary { reader, .. } => reader.current_position(),
231 MiddlewareInnerReader::Operator(operator_reader) => {
232 operator_reader.get_binary_reader().current_position()
233 }
234 }
235 }
236
237 fn original_position(&self) -> usize {
238 match self.state.inner.as_ref().expect("inner state must exist") {
239 MiddlewareInnerReader::Binary { reader, .. } => reader.original_position(),
240 MiddlewareInnerReader::Operator(operator_reader) => operator_reader.original_position(),
241 }
242 }
243
244 fn bytes_remaining(&self) -> usize {
245 match self.state.inner.as_ref().expect("inner state must exist") {
246 MiddlewareInnerReader::Binary { reader, .. } => reader.bytes_remaining(),
247 MiddlewareInnerReader::Operator(operator_reader) => {
248 operator_reader.get_binary_reader().bytes_remaining()
249 }
250 }
251 }
252
253 fn eof(&self) -> bool {
254 match self.state.inner.as_ref().expect("inner state must exist") {
255 MiddlewareInnerReader::Binary { reader, .. } => reader.eof(),
256 MiddlewareInnerReader::Operator(operator_reader) => operator_reader.eof(),
257 }
258 }
259
260 fn range(&self) -> Range<usize> {
261 match self.state.inner.as_ref().expect("inner state must exist") {
262 MiddlewareInnerReader::Binary { reader, .. } => reader.range(),
263 MiddlewareInnerReader::Operator(operator_reader) => {
264 operator_reader.get_binary_reader().range()
265 }
266 }
267 }
268}