Skip to content

Commit

Permalink
Merge branch 'master' into rf-bytecode-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Robbepop committed Oct 31, 2022
2 parents d1187c3 + f5e1c46 commit 4b3d74d
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 52 deletions.
12 changes: 12 additions & 0 deletions crates/core/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,12 @@ impl_wrap_into!(u64, f32, F32);
// largest or smallest finite value representable by f32. This is a bug and will be fixed.
impl_wrap_into!(f64, f32);

// Casting to self
impl_wrap_into!(i32, i32);
impl_wrap_into!(i64, i64);
impl_wrap_into!(F32, F32);
impl_wrap_into!(F64, F64);

impl WrapInto<F32> for F64 {
#[inline]
fn wrap_into(self) -> F32 {
Expand Down Expand Up @@ -626,6 +632,12 @@ impl_extend_into!(i64, f64, F64);
impl_extend_into!(u64, f64, F64);
impl_extend_into!(f32, f64, F64);

// Casting to self
impl_extend_into!(i32, i32);
impl_extend_into!(i64, i64);
impl_extend_into!(F32, F32);
impl_extend_into!(F64, F64);

impl ExtendInto<F64> for F32 {
#[inline]
fn extend_into(self) -> F64 {
Expand Down
36 changes: 10 additions & 26 deletions crates/wasmi/src/engine/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,21 +329,10 @@ impl<'ctx, 'engine, 'func, HostData> Executor<'ctx, 'engine, 'func, HostData> {
/// - `f64.load`
fn execute_load<T>(&mut self, offset: Offset) -> Result<(), TrapCode>
where
T: ExtendInto<T> + LittleEndianConvert,
UntypedValue: From<T>,
T: LittleEndianConvert,
{
self.value_stack.try_eval_top(|address| {
let raw_address = u32::from(address);
let address = Self::effective_address(offset, raw_address)?;
let mut bytes = <<T as LittleEndianConvert>::Bytes as Default>::default();
self.cache
.default_memory_bytes(self.ctx.as_context_mut())
.read(address, bytes.as_mut())?;
let value = <T as LittleEndianConvert>::from_le_bytes(bytes);
Ok(value.into())
})?;
self.next_instr();
Ok(())
self.execute_load_extend::<T, T>(offset)
}

/// Loads a value of type `U` from the default memory at the given address offset and extends it into `T`.
Expand Down Expand Up @@ -393,17 +382,9 @@ impl<'ctx, 'engine, 'func, HostData> Executor<'ctx, 'engine, 'func, HostData> {
/// - `f64.store`
fn execute_store<T>(&mut self, offset: Offset) -> Result<(), TrapCode>
where
T: LittleEndianConvert + From<UntypedValue>,
T: WrapInto<T> + LittleEndianConvert + From<UntypedValue>,
{
let (address, value) = self.value_stack.pop2();
let value = T::from(value);
let address = Self::effective_address(offset, u32::from(address))?;
let bytes = <T as LittleEndianConvert>::into_le_bytes(value);
self.cache
.default_memory_bytes(self.ctx.as_context_mut())
.write(address, bytes.as_ref())?;
self.next_instr();
Ok(())
self.execute_store_wrap::<T, T>(offset)
}

/// Stores a value of type `T` wrapped to type `U` into the default memory at the given address offset.
Expand Down Expand Up @@ -635,10 +616,13 @@ impl<'ctx, 'engine, 'func, HostData> Executor<'ctx, 'engine, 'func, HostData> {
}

fn visit_select(&mut self) {
self.value_stack.pop2_eval(|e1, e2, e3| {
self.value_stack.eval_top3(|e1, e2, e3| {
let condition = <bool as From<UntypedValue>>::from(e3);
let result = if condition { *e1 } else { e2 };
*e1 = result;
if condition {
e1
} else {
e2
}
});
self.next_instr()
}
Expand Down
2 changes: 1 addition & 1 deletion crates/wasmi/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ impl EngineInner {
CallOutcome::NestedCall(called_func) => {
match called_func.as_internal(ctx.as_context()) {
FuncEntityInternal::Wasm(wasm_func) => {
self.stack.call_wasm(frame, wasm_func, &self.code_map)?;
*frame = self.stack.call_wasm(frame, wasm_func, &self.code_map)?;
}
FuncEntityInternal::Host(host_func) => {
cache.reset_default_memory_bytes();
Expand Down
14 changes: 3 additions & 11 deletions crates/wasmi/src/engine/stack/frames.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use super::{err_stack_overflow, DEFAULT_MAX_RECURSION_DEPTH};
use crate::{core::TrapCode, engine::code_map::InstructionPtr, Instance};
use alloc::vec::Vec;
use core::mem::replace;

/// A function frame of a function on the call stack.
#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -72,20 +71,13 @@ impl CallStack {
FuncFrame::new(ip, instance)
}

/// Pushes a Wasm function onto the [`CallStack`].
pub(crate) fn push(
&mut self,
caller: &mut FuncFrame,
ip: InstructionPtr,
instance: Instance,
) -> Result<FuncFrame, TrapCode> {
/// Pushes a Wasm caller function onto the [`CallStack`].
pub(crate) fn push(&mut self, caller: FuncFrame) -> Result<(), TrapCode> {
if self.len() == self.recursion_limit {
return Err(err_stack_overflow());
}
let frame = FuncFrame::new(ip, instance);
let caller = replace(caller, frame);
self.frames.push(caller);
Ok(frame)
Ok(())
}

/// Pops the last [`FuncFrame`] from the [`CallStack`] if any.
Expand Down
5 changes: 3 additions & 2 deletions crates/wasmi/src/engine/stack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,14 @@ impl Stack {
/// Prepares the [`Stack`] for the given Wasm function call.
pub(crate) fn call_wasm<'engine>(
&mut self,
caller: &mut FuncFrame,
caller: &FuncFrame,
wasm_func: &WasmFuncEntity,
code_map: &'engine CodeMap,
) -> Result<FuncFrame, TrapCode> {
let ip = self.call_wasm_impl(wasm_func, code_map)?;
self.frames.push(*caller)?;
let instance = wasm_func.instance();
let frame = self.frames.push(caller, ip, instance)?;
let frame = FuncFrame::new(ip, instance);
Ok(frame)
}

Expand Down
17 changes: 5 additions & 12 deletions crates/wasmi/src/engine/stack/values/vref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,22 +211,15 @@ impl<'a> ValueStackRef<'a> {
)
}

/// Evaluates `f` on the top three stack entries.
///
/// In summary this procedure does the following:
///
/// - Pop entry `e3`.
/// - Pop entry `e2`.
/// - Peek entry `&mut e1_ptr`.
/// - Evaluate `f(e1_ptr, e2, e3)`.
/// Evaluates the given closure `f` for the 3 top most stack values.
#[inline]
pub fn pop2_eval<F>(&mut self, f: F)
pub fn eval_top3<F>(&mut self, f: F)
where
F: FnOnce(&mut UntypedValue, UntypedValue, UntypedValue),
F: FnOnce(UntypedValue, UntypedValue, UntypedValue) -> UntypedValue,
{
let (e2, e3) = self.pop2();
let e1 = self.last_mut();
f(e1, e2, e3)
let e1 = self.last();
*self.last_mut() = f(e1, e2, e3)
}

/// Evaluates the given closure `f` for the top most stack value.
Expand Down

0 comments on commit 4b3d74d

Please sign in to comment.