Skip to content

Commit 1bd4df8

Browse files
committed
refactor and simplify executor in preparation of resumable functions
1 parent 99116d4 commit 1bd4df8

File tree

5 files changed

+77
-141
lines changed

5 files changed

+77
-141
lines changed

crates/wasmi/src/engine/executor/handler/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ mod state;
99
#[cfg(feature = "trampolines")]
1010
use self::dispatch::ControlContinue;
1111
pub use self::{
12-
dispatch::{init_wasm_func_call, op_code_to_handler},
12+
dispatch::{init_wasm_func_call, op_code_to_handler, ExecutionOutcome},
1313
state::{Inst, Stack},
1414
};
1515
use self::{

crates/wasmi/src/engine/executor/mod.rs

Lines changed: 75 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
pub use self::handler::{op_code_to_handler, Inst, Stack};
2-
use super::{code_map::CodeMap, ResumableError};
2+
use super::code_map::CodeMap;
33
use crate::{
44
engine::{
5-
executor::handler::init_wasm_func_call,
5+
executor::handler::{init_wasm_func_call, ExecutionOutcome},
66
CallParams,
77
CallResults,
88
EngineInner,
@@ -41,13 +41,9 @@ impl EngineInner {
4141
{
4242
let mut stack = self.stacks.lock().reuse_or_new();
4343
let results = EngineExecutor::new(&self.code_map, &mut stack)
44-
.execute_root_func(ctx.store, func, params, results)
45-
.map_err(|error| match error.into_resumable() {
46-
Ok(error) => error.into_error(),
47-
Err(error) => error,
48-
});
44+
.execute_root_func(ctx.store, func, params, results)?;
4945
self.stacks.lock().recycle(stack);
50-
results
46+
Ok(results)
5147
}
5248

5349
/// Executes the given [`Func`] resumably with the given `params` and returns the `results`.
@@ -69,42 +65,39 @@ impl EngineInner {
6965
{
7066
let store = ctx.store;
7167
let mut stack = self.stacks.lock().reuse_or_new();
72-
let results = EngineExecutor::new(&self.code_map, &mut stack)
68+
let outcome = EngineExecutor::new(&self.code_map, &mut stack)
7369
.execute_root_func(store, func, params, results);
74-
match results {
75-
Ok(results) => {
70+
let results = match outcome {
71+
Ok(results) => results,
72+
Err(ExecutionOutcome::Host(error)) => {
73+
let host_func = *error.host_func();
74+
let caller_results = *error.caller_results();
75+
let host_error = error.into_error();
76+
return Ok(ResumableCallBase::HostTrap(ResumableCallHostTrap::new(
77+
store.engine().clone(),
78+
*func,
79+
host_func,
80+
host_error,
81+
caller_results,
82+
stack,
83+
)));
84+
}
85+
Err(ExecutionOutcome::OutOfFuel(error)) => {
86+
let required_fuel = error.required_fuel();
87+
return Ok(ResumableCallBase::OutOfFuel(ResumableCallOutOfFuel::new(
88+
store.engine().clone(),
89+
*func,
90+
stack,
91+
required_fuel,
92+
)));
93+
}
94+
Err(ExecutionOutcome::Error(error)) => {
7695
self.stacks.lock().recycle(stack);
77-
Ok(ResumableCallBase::Finished(results))
96+
return Err(error);
7897
}
79-
Err(error) => match error.into_resumable() {
80-
Ok(ResumableError::HostTrap(error)) => {
81-
let host_func = *error.host_func();
82-
let caller_results = *error.caller_results();
83-
let host_error = error.into_error();
84-
Ok(ResumableCallBase::HostTrap(ResumableCallHostTrap::new(
85-
store.engine().clone(),
86-
*func,
87-
host_func,
88-
host_error,
89-
caller_results,
90-
stack,
91-
)))
92-
}
93-
Ok(ResumableError::OutOfFuel(error)) => {
94-
let required_fuel = error.required_fuel();
95-
Ok(ResumableCallBase::OutOfFuel(ResumableCallOutOfFuel::new(
96-
store.engine().clone(),
97-
*func,
98-
stack,
99-
required_fuel,
100-
)))
101-
}
102-
Err(error) => {
103-
self.stacks.lock().recycle(stack);
104-
Err(error)
105-
}
106-
},
107-
}
98+
};
99+
self.stacks.lock().recycle(stack);
100+
Ok(ResumableCallBase::Finished(results))
108101
}
109102

110103
/// Resumes the given [`Func`] with the given `params` and returns the `results`.
@@ -126,30 +119,27 @@ impl EngineInner {
126119
{
127120
let caller_results = invocation.caller_results();
128121
let mut executor = EngineExecutor::new(&self.code_map, invocation.common.stack_mut());
129-
let results = executor.resume_func_host_trap(ctx.store, params, caller_results, results);
130-
match results {
131-
Ok(results) => {
122+
let outcome = executor.resume_func_host_trap(ctx.store, params, caller_results, results);
123+
let results = match outcome {
124+
Ok(results) => results,
125+
Err(ExecutionOutcome::Host(error)) => {
126+
let host_func = *error.host_func();
127+
let caller_results = *error.caller_results();
128+
invocation.update(host_func, error.into_error(), caller_results);
129+
return Ok(ResumableCallBase::HostTrap(invocation));
130+
}
131+
Err(ExecutionOutcome::OutOfFuel(error)) => {
132+
let required_fuel = error.required_fuel();
133+
let invocation = invocation.update_to_out_of_fuel(required_fuel);
134+
return Ok(ResumableCallBase::OutOfFuel(invocation));
135+
}
136+
Err(ExecutionOutcome::Error(error)) => {
132137
self.stacks.lock().recycle(invocation.common.take_stack());
133-
Ok(ResumableCallBase::Finished(results))
138+
return Err(error);
134139
}
135-
Err(error) => match error.into_resumable() {
136-
Ok(ResumableError::HostTrap(error)) => {
137-
let host_func = *error.host_func();
138-
let caller_results = *error.caller_results();
139-
invocation.update(host_func, error.into_error(), caller_results);
140-
Ok(ResumableCallBase::HostTrap(invocation))
141-
}
142-
Ok(ResumableError::OutOfFuel(error)) => {
143-
let required_fuel = error.required_fuel();
144-
let invocation = invocation.update_to_out_of_fuel(required_fuel);
145-
Ok(ResumableCallBase::OutOfFuel(invocation))
146-
}
147-
Err(error) => {
148-
self.stacks.lock().recycle(invocation.common.take_stack());
149-
Err(error)
150-
}
151-
},
152-
}
140+
};
141+
self.stacks.lock().recycle(invocation.common.take_stack());
142+
Ok(ResumableCallBase::Finished(results))
153143
}
154144

155145
/// Resumes the given [`Func`] after running out of fuel and returns the `results`.
@@ -169,33 +159,27 @@ impl EngineInner {
169159
Results: CallResults,
170160
{
171161
let mut executor = EngineExecutor::new(&self.code_map, invocation.common.stack_mut());
172-
let results = executor.resume_func_out_of_fuel(ctx.store, results);
173-
match results {
174-
Ok(results) => {
162+
let outcome = executor.resume_func_out_of_fuel(ctx.store, results);
163+
let results = match outcome {
164+
Ok(results) => results,
165+
Err(ExecutionOutcome::Host(error)) => {
166+
let host_func = *error.host_func();
167+
let caller_results = *error.caller_results();
168+
let invocation =
169+
invocation.update_to_host_trap(host_func, error.into_error(), caller_results);
170+
return Ok(ResumableCallBase::HostTrap(invocation));
171+
}
172+
Err(ExecutionOutcome::OutOfFuel(error)) => {
173+
invocation.update(error.required_fuel());
174+
return Ok(ResumableCallBase::OutOfFuel(invocation));
175+
}
176+
Err(ExecutionOutcome::Error(error)) => {
175177
self.stacks.lock().recycle(invocation.common.take_stack());
176-
Ok(ResumableCallBase::Finished(results))
178+
return Err(error);
177179
}
178-
Err(error) => match error.into_resumable() {
179-
Ok(ResumableError::HostTrap(error)) => {
180-
let host_func = *error.host_func();
181-
let caller_results = *error.caller_results();
182-
let invocation = invocation.update_to_host_trap(
183-
host_func,
184-
error.into_error(),
185-
caller_results,
186-
);
187-
Ok(ResumableCallBase::HostTrap(invocation))
188-
}
189-
Ok(ResumableError::OutOfFuel(error)) => {
190-
invocation.update(error.required_fuel());
191-
Ok(ResumableCallBase::OutOfFuel(invocation))
192-
}
193-
Err(error) => {
194-
self.stacks.lock().recycle(invocation.common.take_stack());
195-
Err(error)
196-
}
197-
},
198-
}
180+
};
181+
self.stacks.lock().recycle(invocation.common.take_stack());
182+
Ok(ResumableCallBase::Finished(results))
199183
}
200184
}
201185

@@ -229,7 +213,7 @@ impl<'engine> EngineExecutor<'engine> {
229213
func: &Func,
230214
params: impl CallParams,
231215
results: Results,
232-
) -> Result<<Results as CallResults>::Results, Error>
216+
) -> Result<<Results as CallResults>::Results, ExecutionOutcome>
233217
where
234218
Results: CallResults,
235219
{
@@ -269,7 +253,7 @@ impl<'engine> EngineExecutor<'engine> {
269253
_params: impl CallParams,
270254
_caller_results: SlotSpan,
271255
_results: Results,
272-
) -> Result<<Results as CallResults>::Results, Error>
256+
) -> Result<<Results as CallResults>::Results, ExecutionOutcome>
273257
where
274258
Results: CallResults,
275259
{
@@ -302,7 +286,7 @@ impl<'engine> EngineExecutor<'engine> {
302286
&mut self,
303287
_store: &mut Store<T>,
304288
_results: Results,
305-
) -> Result<<Results as CallResults>::Results, Error>
289+
) -> Result<<Results as CallResults>::Results, ExecutionOutcome>
306290
where
307291
Results: CallResults,
308292
{

crates/wasmi/src/engine/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ pub use self::{
3737
ResumableCall,
3838
ResumableCallHostTrap,
3939
ResumableCallOutOfFuel,
40-
ResumableError,
4140
ResumableHostTrapError,
4241
ResumableOutOfFuelError,
4342
TypedResumableCall,

crates/wasmi/src/engine/resumable.rs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use crate::{
77
AsContextMut,
88
Engine,
99
Error,
10-
TrapCode,
1110
Val,
1211
WasmResults,
1312
};
@@ -32,23 +31,6 @@ pub(crate) enum ResumableCallBase<T> {
3231
OutOfFuel(ResumableCallOutOfFuel),
3332
}
3433

35-
/// Any resumable error.
36-
#[derive(Debug)]
37-
pub enum ResumableError {
38-
HostTrap(ResumableHostTrapError),
39-
OutOfFuel(ResumableOutOfFuelError),
40-
}
41-
42-
impl ResumableError {
43-
/// Consumes `self` to return the underlying [`Error`].
44-
pub fn into_error(self) -> Error {
45-
match self {
46-
ResumableError::HostTrap(error) => error.into_error(),
47-
ResumableError::OutOfFuel(error) => error.into_error(),
48-
}
49-
}
50-
}
51-
5234
/// Error returned from a called host function in a resumable state.
5335
#[derive(Debug)]
5436
pub struct ResumableHostTrapError {
@@ -125,11 +107,6 @@ impl ResumableOutOfFuelError {
125107
pub(crate) fn required_fuel(self) -> u64 {
126108
self.required_fuel
127109
}
128-
129-
/// Consumes `self` to return the underlying [`Error`].
130-
pub(crate) fn into_error(self) -> Error {
131-
Error::from(TrapCode::OutOfFuel)
132-
}
133110
}
134111

135112
/// Returned by calling a [`Func`] in a resumable way.

crates/wasmi/src/error.rs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use super::errors::{
77
LinkerError,
88
};
99
use crate::{
10-
engine::{ResumableError, ResumableHostTrapError, ResumableOutOfFuelError, TranslationError},
10+
engine::{ResumableHostTrapError, ResumableOutOfFuelError, TranslationError},
1111
module::ReadError,
1212
TrapCode,
1313
};
@@ -140,30 +140,6 @@ impl Error {
140140
| ErrorKind::Fuel(FuelError::OutOfFuel { .. })
141141
)
142142
}
143-
144-
pub(crate) fn into_resumable(self) -> Result<ResumableError, Error> {
145-
if matches!(
146-
self.kind(),
147-
ErrorKind::ResumableHostTrap(_)
148-
| ErrorKind::ResumableOutOfFuel(_)
149-
| ErrorKind::Table(TableError::OutOfFuel { .. })
150-
| ErrorKind::Memory(MemoryError::OutOfFuel { .. })
151-
| ErrorKind::Fuel(FuelError::OutOfFuel { .. })
152-
) {
153-
let resumable_error = match *self.kind {
154-
ErrorKind::ResumableHostTrap(error) => ResumableError::HostTrap(error),
155-
ErrorKind::ResumableOutOfFuel(error) => ResumableError::OutOfFuel(error),
156-
ErrorKind::Table(TableError::OutOfFuel { required_fuel })
157-
| ErrorKind::Memory(MemoryError::OutOfFuel { required_fuel })
158-
| ErrorKind::Fuel(FuelError::OutOfFuel { required_fuel }) => {
159-
ResumableError::OutOfFuel(ResumableOutOfFuelError::new(required_fuel))
160-
}
161-
unexpected => unreachable!("unexpected error kind: {:?}", unexpected),
162-
};
163-
return Ok(resumable_error);
164-
}
165-
Err(self)
166-
}
167143
}
168144

169145
impl core::error::Error for Error {}

0 commit comments

Comments
 (0)