Skip to content

Commit 20a1937

Browse files
committed
use new store internal errors in executor
1 parent 16f4598 commit 20a1937

File tree

3 files changed

+99
-59
lines changed

3 files changed

+99
-59
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::{
22
exec,
33
state::{DoneReason, Ip, Mem0Len, Mem0Ptr, Sp, Stack, VmState},
4-
utils::set_value,
4+
utils::{resolve_instance, set_value},
55
};
66
use crate::{
77
engine::{executor::handler::utils, CallParams, CallResults, CodeMap, EngineFunc},
@@ -95,7 +95,7 @@ impl<'a, T> WasmFuncCall<'a, T, state::Init> {
9595
}
9696

9797
fn execute_until_done(&mut self) -> Option<DoneReason> {
98-
let instance = self.store.inner.resolve_instance(&self.instance).into();
98+
let instance = resolve_instance(self.store.prune(), &self.instance).into();
9999
let store = self.store.prune();
100100
let (mem0, mem0_len) = utils::extract_mem0(store, instance);
101101
let state = VmState::new(store, self.stack, self.code);
@@ -130,7 +130,7 @@ pub fn init_wasm_func_call<'a, T>(
130130
let callee_ip = Ip::from(compiled_func.ops());
131131
let frame_size = compiled_func.len_stack_slots();
132132
let callee_params = BoundedSlotSpan::new(SlotSpan::new(Slot::from(0)), frame_size);
133-
let instance_ref = store.inner.resolve_instance(&instance);
133+
let instance_ref = resolve_instance(store.prune(), &instance);
134134
let callee_sp = stack.push_frame(
135135
None,
136136
callee_ip,

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

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{
22
dispatch::Done,
33
eval,
44
state::{mem0_bytes, Ip, Mem0Len, Mem0Ptr, Sp, VmState},
5-
utils::{get_value, memory_bytes, offset_ip, resolve_func, set_value, IntoTrapResult as _},
5+
utils::{fetch_func, get_value, memory_bytes, offset_ip, set_value, IntoTrapResult as _},
66
};
77
use crate::{
88
core::{wasm, UntypedVal},
@@ -14,8 +14,12 @@ use crate::{
1414
exec_copy_span_asc,
1515
exec_copy_span_des,
1616
extract_mem0,
17+
fetch_global,
18+
fetch_memory,
19+
resolve_func,
1720
resolve_global,
1821
resolve_indirect_func,
22+
resolve_instance,
1923
resolve_memory,
2024
set_global,
2125
update_instance,
@@ -26,8 +30,8 @@ use crate::{
2630
errors::{FuelError, MemoryError},
2731
func::FuncEntity,
2832
instance::InstanceEntity,
29-
ir,
30-
ir::{Slot, SlotSpan},
33+
ir::{self, Slot, SlotSpan},
34+
store::StoreError,
3135
TrapCode,
3236
};
3337
use core::{cmp, ptr::NonNull};
@@ -139,8 +143,9 @@ pub fn global_get(
139143
instance: NonNull<InstanceEntity>,
140144
) -> Done {
141145
let (ip, crate::ir::decode::GlobalGet { result, global }) = unsafe { decode_op(ip) };
142-
let global = resolve_global(instance, global);
143-
let value = *state.store.inner().resolve_global(&global).get_untyped();
146+
let global = fetch_global(instance, global);
147+
let global = resolve_global(state.store, &global);
148+
let value = *global.get_untyped();
144149
set_value(sp, result, value);
145150
dispatch!(state, ip, sp, mem0, mem0_len, instance)
146151
}
@@ -217,19 +222,15 @@ pub fn call_imported(
217222
instance: NonNull<InstanceEntity>,
218223
) -> Done {
219224
let (caller_ip, crate::ir::decode::CallImported { params, func }) = unsafe { decode_op(ip) };
220-
let func = resolve_func(instance, func);
221-
let func = state.store.inner().resolve_func(&func);
225+
let func = fetch_func(instance, func);
226+
let func = resolve_func(state.store, &func);
222227
let (callee_ip, sp, mem0, mem0_len, instance) = match func {
223228
FuncEntity::Wasm(func) => {
224229
let engine_func = func.func_body();
225230
let callee_instance = *func.instance();
226231
let (callee_ip, size) =
227232
compile_or_get_func!(state, ip, sp, mem0, mem0_len, instance, engine_func);
228-
let callee_instance: NonNull<InstanceEntity> = state
229-
.store
230-
.inner()
231-
.resolve_instance(&callee_instance)
232-
.into();
233+
let callee_instance = resolve_instance(state.store, &callee_instance).into();
233234
let callee_sp = match state.stack.push_frame(
234235
Some(caller_ip),
235236
callee_ip,
@@ -272,18 +273,15 @@ pub fn call_indirect(
272273
Ok(func) => func,
273274
Err(trap) => break_with_trap!(trap, state, ip, sp, mem0, mem0_len, instance),
274275
};
275-
let func = state.store.inner().resolve_func(&func);
276+
let func = resolve_func(state.store, &func);
276277
let (callee_ip, sp, mem0, mem0_len, instance) = match func {
277278
FuncEntity::Wasm(func) => {
278279
let engine_func = func.func_body();
279280
let callee_instance = *func.instance();
280281
let (callee_ip, size) =
281282
compile_or_get_func!(state, ip, sp, mem0, mem0_len, instance, engine_func);
282-
let callee_instance: NonNull<InstanceEntity> = state
283-
.store
284-
.inner()
285-
.resolve_instance(&callee_instance)
286-
.into();
283+
let callee_instance: NonNull<InstanceEntity> =
284+
resolve_instance(state.store, &callee_instance).into();
287285
let callee_sp = match state.stack.push_frame(
288286
Some(caller_ip),
289287
callee_ip,
@@ -366,8 +364,8 @@ pub fn memory_size(
366364
instance: NonNull<InstanceEntity>,
367365
) -> Done {
368366
let (ip, crate::ir::decode::MemorySize { memory, result }) = unsafe { decode_op(ip) };
369-
let memory = resolve_memory(instance, memory);
370-
let size = state.store.inner().resolve_memory(&memory).size();
367+
let memory = fetch_memory(instance, memory);
368+
let size = resolve_memory(state.store, &memory).size();
371369
set_value(sp, result, size);
372370
dispatch!(state, ip, sp, mem0, mem0_len, instance)
373371
}
@@ -389,7 +387,7 @@ pub fn memory_grow(
389387
},
390388
) = unsafe { decode_op(ip) };
391389
let delta: u64 = get_value(delta, sp);
392-
let memref = resolve_memory(instance, memory);
390+
let memref = fetch_memory(instance, memory);
393391
let mut mem0 = mem0;
394392
let mut mem0_len = mem0_len;
395393
let return_value = match state.store.grow_memory(&memref, delta) {
@@ -402,18 +400,20 @@ pub fn memory_grow(
402400
}
403401
return_value
404402
}
405-
Err(MemoryError::OutOfBoundsGrowth | MemoryError::OutOfSystemMemory) => {
406-
let memory_ty = state.store.inner().resolve_memory(&memref).ty();
403+
Err(StoreError::External(
404+
MemoryError::OutOfBoundsAccess | MemoryError::OutOfSystemMemory,
405+
)) => {
406+
let memory_ty = resolve_memory(state.store, &memref).ty();
407407
match memory_ty.is_64() {
408408
true => u64::MAX,
409409
false => u64::from(u32::MAX),
410410
}
411411
}
412-
Err(MemoryError::OutOfFuel { required_fuel }) => {
412+
Err(StoreError::External(MemoryError::OutOfFuel { required_fuel })) => {
413413
state.done(DoneReason::OutOfFuel { required_fuel });
414414
return exec_break!(ip, sp, mem0, mem0_len, instance);
415415
}
416-
Err(MemoryError::ResourceLimiterDeniedAllocation) => {
416+
Err(StoreError::External(MemoryError::ResourceLimiterDeniedAllocation)) => {
417417
break_with_trap!(
418418
TrapCode::GrowthOperationLimited,
419419
state,
@@ -424,7 +424,16 @@ pub fn memory_grow(
424424
instance
425425
)
426426
}
427-
Err(error) => panic!("encountered an unexpected error: {error}"),
427+
Err(StoreError::Internal(_error)) => {
428+
// TODO: we do not want to panic in the executor handlers so we somehow
429+
// want to establish a way to signal to the executor that a panic
430+
// occurred, instead.
431+
todo!()
432+
}
433+
Err(error) => {
434+
// TODO: see above
435+
panic!("encountered an unexpected error: {error}")
436+
}
428437
};
429438
set_value(sp, result, return_value);
430439
dispatch!(state, ip, sp, mem0, mem0_len, instance)

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

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
use super::state::{mem0_bytes, Ip, Mem0Len, Mem0Ptr, Sp, VmState};
22
use crate::{
3-
core::{ReadAs, UntypedVal, WriteAs},
3+
core::{CoreElementSegment, CoreGlobal, CoreMemory, CoreTable, ReadAs, UntypedVal, WriteAs},
44
engine::{DedupFuncType, EngineFunc},
5+
func::FuncEntity,
56
instance::InstanceEntity,
67
ir::{index, Address, BranchOffset, Offset16, Sign, Slot, SlotSpan},
7-
store::PrunedStore,
8+
memory::DataSegment,
9+
store::{PrunedStore, StoreInner},
10+
table::ElementSegment,
811
Error,
912
Func,
1013
Global,
14+
Instance,
1115
Memory,
1216
Ref,
1317
Table,
@@ -178,7 +182,7 @@ pub fn extract_mem0(
178182
let Some(memory) = instance.get_memory(0) else {
179183
return (Mem0Ptr::from([].as_mut_ptr()), Mem0Len::from(0));
180184
};
181-
let mem0 = store.inner_mut().resolve_memory_mut(&memory).data_mut();
185+
let mem0 = resolve_memory_mut(store, &memory).data_mut();
182186
let mem0_ptr = mem0.as_mut_ptr();
183187
let mem0_len = mem0.len();
184188
(Mem0Ptr::from(mem0_ptr), Mem0Len::from(mem0_len))
@@ -198,11 +202,7 @@ pub fn memory_bytes<'a>(
198202
let Some(memory) = instance.get_memory(u32::from(u16::from(memory))) else {
199203
return &mut [];
200204
};
201-
state
202-
.store
203-
.inner_mut()
204-
.resolve_memory_mut(&memory)
205-
.data_mut()
205+
resolve_memory_mut(state.store, &memory).data_mut()
206206
}
207207
}
208208
}
@@ -211,7 +211,7 @@ pub fn offset_ip(ip: Ip, offset: BranchOffset) -> Ip {
211211
unsafe { ip.offset(i32::from(offset) as isize) }
212212
}
213213

214-
macro_rules! impl_resolve_entity {
214+
macro_rules! impl_fetch_from_instance {
215215
(
216216
$( fn $fn:ident($param:ident: $ty:ty) -> $ret:ty = $getter:expr );* $(;)?
217217
) => {
@@ -232,16 +232,52 @@ macro_rules! impl_resolve_entity {
232232
)*
233233
};
234234
}
235-
impl_resolve_entity! {
236-
fn resolve_func(func: index::Func) -> Func = InstanceEntity::get_func;
237-
fn resolve_global(global: index::Global) -> Global = InstanceEntity::get_global;
238-
fn resolve_memory(memory: index::Memory) -> Memory = InstanceEntity::get_memory;
239-
fn resolve_table(table: index::Table) -> Table = InstanceEntity::get_table;
240-
fn resolve_func_type_dedup(func_type: index::FuncType) -> DedupFuncType = {
235+
impl_fetch_from_instance! {
236+
fn fetch_data(func: index::Data) -> DataSegment = InstanceEntity::get_data_segment;
237+
fn fetch_elem(func: index::Elem) -> ElementSegment = InstanceEntity::get_element_segment;
238+
fn fetch_func(func: index::Func) -> Func = InstanceEntity::get_func;
239+
fn fetch_global(global: index::Global) -> Global = InstanceEntity::get_global;
240+
fn fetch_memory(memory: index::Memory) -> Memory = InstanceEntity::get_memory;
241+
fn fetch_table(table: index::Table) -> Table = InstanceEntity::get_table;
242+
fn fetch_func_type(func_type: index::FuncType) -> DedupFuncType = {
241243
|instance: &InstanceEntity, index: u32| instance.get_signature(index).copied()
242244
};
243245
}
244246

247+
macro_rules! impl_resolve_from_store {
248+
(
249+
$( fn $fn:ident($param:ident: $ty:ty) -> $ret:ty = $getter:expr );* $(;)?
250+
) => {
251+
$(
252+
pub fn $fn<'a>(store: &'a mut PrunedStore, $param: $ty) -> $ret {
253+
match $getter(store.inner_mut(), $param) {
254+
::core::result::Result::Ok($param) => $param,
255+
::core::result::Result::Err(error) => unsafe {
256+
$crate::engine::utils::unreachable_unchecked!(
257+
::core::concat!("could not resolve stored ", ::core::stringify!($param), ": {:?}"),
258+
error,
259+
)
260+
},
261+
}
262+
}
263+
)*
264+
};
265+
}
266+
impl_resolve_from_store! {
267+
fn resolve_elem(elem: &ElementSegment) -> &'a CoreElementSegment = StoreInner::try_resolve_element;
268+
fn resolve_func(func: &Func) -> &'a FuncEntity = StoreInner::try_resolve_func;
269+
fn resolve_global(global: &Global) -> &'a CoreGlobal = StoreInner::try_resolve_global;
270+
fn resolve_memory(memory: &Memory) -> &'a CoreMemory = StoreInner::try_resolve_memory;
271+
fn resolve_table(table: &Table) -> &'a CoreTable = StoreInner::try_resolve_table;
272+
fn resolve_instance(func: &Instance) -> &'a InstanceEntity = StoreInner::try_resolve_instance;
273+
// fn resolve_func_type(func_type: DedupFuncType) -> DedupFuncType = StoreInner::resolve_func_type;
274+
275+
fn resolve_elem_mut(elem: &ElementSegment) -> &'a mut CoreElementSegment = StoreInner::try_resolve_element_mut;
276+
fn resolve_global_mut(global: &Global) -> &'a mut CoreGlobal = StoreInner::try_resolve_global_mut;
277+
fn resolve_memory_mut(memory: &Memory) -> &'a mut CoreMemory = StoreInner::try_resolve_memory_mut;
278+
fn resolve_table_mut(table: &Table) -> &'a mut CoreTable = StoreInner::try_resolve_table_mut;
279+
}
280+
245281
pub fn resolve_indirect_func(
246282
index: Slot,
247283
table: index::Table,
@@ -250,19 +286,17 @@ pub fn resolve_indirect_func(
250286
sp: Sp,
251287
instance: NonNull<InstanceEntity>,
252288
) -> Result<Func, TrapCode> {
253-
let table = resolve_table(instance, table);
254289
let index = get_value(index, sp);
255-
let funcref = state
256-
.store
257-
.inner()
258-
.resolve_table(&table)
290+
let table = fetch_table(instance, table);
291+
let table = resolve_table(state.store, &table);
292+
let funcref = table
259293
.get_untyped(index)
260294
.map(<Ref<Func>>::from)
261295
.ok_or(TrapCode::TableOutOfBounds)?;
262296
let func = funcref.val().ok_or(TrapCode::IndirectCallToNull)?;
263-
let actual_signature = state.store.inner().resolve_func(func).ty_dedup();
264-
let expected_signature = resolve_func_type_dedup(instance, func_type);
265-
if expected_signature.ne(actual_signature) {
297+
let actual_fnty = resolve_func(state.store, func).ty_dedup();
298+
let expected_fnty = fetch_func_type(instance, func_type);
299+
if expected_fnty.ne(actual_fnty) {
266300
return Err(TrapCode::BadSignature);
267301
}
268302
Ok(*func)
@@ -274,13 +308,10 @@ pub fn set_global(
274308
state: &mut VmState,
275309
instance: NonNull<InstanceEntity>,
276310
) {
277-
let global = resolve_global(instance, global);
278-
let mut global_ptr = state
279-
.store
280-
.inner_mut()
281-
.resolve_global_mut(&global)
282-
.get_untyped_ptr();
283-
let global_ref = unsafe { global_ptr.as_mut() };
311+
let global = fetch_global(instance, global);
312+
let global = resolve_global_mut(state.store, &global);
313+
let mut value_ptr = global.get_untyped_ptr();
314+
let global_ref = unsafe { value_ptr.as_mut() };
284315
*global_ref = value;
285316
}
286317

0 commit comments

Comments
 (0)