Skip to content

Commit

Permalink
Add StackOffsets utility type (#1070)
Browse files Browse the repository at this point in the history
add StackOffsets utility type
  • Loading branch information
Robbepop authored Jun 15, 2024
1 parent 8ce43fe commit f11e850
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 29 deletions.
11 changes: 5 additions & 6 deletions crates/wasmi/src/engine/executor/instrs/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,12 @@ impl<'engine> Executor<'engine> {
.call_stack
.peek()
.expect("need to have a caller on the call stack");
let (mut uninit_params, base_ptr, frame_ptr) =
self.value_stack.alloc_call_frame(func, |this| {
// Safety: We use the base offset of a live call frame on the call stack.
self.sp = unsafe { this.stack_ptr_at(caller.base_offset()) };
})?;
let (mut uninit_params, offsets) = self.value_stack.alloc_call_frame(func, |this| {
// Safety: We use the base offset of a live call frame on the call stack.
self.sp = unsafe { this.stack_ptr_at(caller.base_offset()) };
})?;
let instr_ptr = InstructionPtr::new(func.instrs().as_ptr());
let frame = CallFrame::new(instr_ptr, frame_ptr, base_ptr, results, *instance);
let frame = CallFrame::new(instr_ptr, offsets, results, *instance);
if <C as CallContext>::HAS_PARAMS {
self.copy_call_params(&mut uninit_params);
}
Expand Down
5 changes: 2 additions & 3 deletions crates/wasmi/src/engine/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ impl<'engine> EngineExecutor<'engine> {
.res
.code_map
.get(Some(store.inner.fuel_mut()), compiled_func)?;
let (mut uninit_params, base_ptr, frame_ptr) = self
let (mut uninit_params, offsets) = self
.stack
.values
.alloc_call_frame(compiled_func, do_nothing)?;
Expand All @@ -217,8 +217,7 @@ impl<'engine> EngineExecutor<'engine> {
uninit_params.init_zeroes();
self.stack.calls.push(CallFrame::new(
InstructionPtr::new(compiled_func.instrs().as_ptr()),
frame_ptr,
base_ptr,
offsets,
RegisterSpan::new(Register::from_i16(0)),
instance,
))?;
Expand Down
49 changes: 33 additions & 16 deletions crates/wasmi/src/engine/executor/stack/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,39 @@ impl CallStack {
}
}

/// Offsets for a [`CallFrame`] into the [`ValueStack`].
#[derive(Debug, Copy, Clone)]
pub struct StackOffsets {
/// Offset to the first mutable cell of a [`CallFrame`].
pub base: BaseValueStackOffset,
/// Offset to the first cell of a [`CallFrame`].
pub frame: FrameValueStackOffset,
}

impl StackOffsets {
/// Moves the [`StackOffsets`] values down by `delta`.
///
/// # Note
///
/// This is used for the implementation of tail calls.
#[inline(always)]
fn move_down(&mut self, delta: usize) {
let base = usize::from(self.base);
let frame = usize::from(self.frame);
debug_assert!(delta <= base);
debug_assert!(delta <= frame);
self.base = BaseValueStackOffset::new(base - delta);
self.frame = FrameValueStackOffset::new(frame - delta);
}
}

/// A single frame of a called [`CompiledFunc`].
#[derive(Debug, Copy, Clone)]
pub struct CallFrame {
/// The pointer to the [`Instruction`] that is executed next.
instr_ptr: InstructionPtr,
/// Pointer to the first mutable cell of a [`CallFrame`].
base_ptr: BaseValueStackOffset,
/// Pointer to the first cell of a [`CallFrame`].
frame_ptr: FrameValueStackOffset,
/// Offsets of the [`CallFrame`] into the [`ValueStack`].
offsets: StackOffsets,
/// Span of registers were the caller expects them in its [`CallFrame`].
results: RegisterSpan,
/// The instance in which the function has been defined.
Expand All @@ -137,15 +161,13 @@ impl CallFrame {
/// Creates a new [`CallFrame`].
pub fn new(
instr_ptr: InstructionPtr,
frame_ptr: FrameValueStackOffset,
base_ptr: BaseValueStackOffset,
offsets: StackOffsets,
results: RegisterSpan,
instance: Instance,
) -> Self {
Self {
instr_ptr,
base_ptr,
frame_ptr,
offsets,
results,
instance,
}
Expand All @@ -157,12 +179,7 @@ impl CallFrame {
///
/// This is used for the implementation of tail calls.
pub fn move_down(&mut self, delta: usize) {
let base_index = usize::from(self.base_offset());
let frame_index = usize::from(self.frame_offset());
debug_assert!(delta <= base_index);
debug_assert!(delta <= frame_index);
self.base_ptr = BaseValueStackOffset::new(base_index - delta);
self.frame_ptr = FrameValueStackOffset::new(frame_index - delta);
self.offsets.move_down(delta);
}

/// Updates the [`InstructionPtr`] of the [`CallFrame`].
Expand All @@ -181,12 +198,12 @@ impl CallFrame {

/// Returns the [`FrameValueStackOffset`] of the [`CallFrame`].
pub fn frame_offset(&self) -> FrameValueStackOffset {
self.frame_ptr
self.offsets.frame
}

/// Returns the [`BaseValueStackOffset`] of the [`CallFrame`].
pub fn base_offset(&self) -> BaseValueStackOffset {
self.base_ptr
self.offsets.base
}

/// Returns the [`RegisterSpan`] of the [`CallFrame`].
Expand Down
10 changes: 6 additions & 4 deletions crates/wasmi/src/engine/executor/stack/values.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::err_stack_overflow;
use super::{calls::StackOffsets, err_stack_overflow};
use crate::{
core::{TrapCode, UntypedVal},
engine::{bytecode::Register, CompiledFuncEntity},
Expand Down Expand Up @@ -225,7 +225,7 @@ impl ValueStack {
&mut self,
func: &CompiledFuncEntity,
on_resize: impl FnMut(&mut Self),
) -> Result<(FrameParams, BaseValueStackOffset, FrameValueStackOffset), TrapCode> {
) -> Result<(FrameParams, StackOffsets), TrapCode> {
let len_registers = func.len_registers();
let len_consts = func.consts().len();
let len = self.len();
Expand All @@ -242,8 +242,10 @@ impl ValueStack {
let base = ValueStackOffset(len + len_consts);
Ok((
params,
BaseValueStackOffset(base),
FrameValueStackOffset(frame),
StackOffsets {
base: BaseValueStackOffset(base),
frame: FrameValueStackOffset(frame),
},
))
}

Expand Down

0 comments on commit f11e850

Please sign in to comment.