diff --git a/crates/wasmi/src/engine/translator/func/control_frame.rs b/crates/wasmi/src/engine/translator/func/control_frame.rs index 2325d2b44b..a4491ee2aa 100644 --- a/crates/wasmi/src/engine/translator/func/control_frame.rs +++ b/crates/wasmi/src/engine/translator/func/control_frame.rs @@ -1,6 +1,6 @@ use super::LabelRef; use crate::{ - engine::{translator::Instr, BlockType, TranslationError}, + engine::{translator::utils::Instr, BlockType, TranslationError}, ir::{BoundedRegSpan, RegSpan}, Engine, Error, diff --git a/crates/wasmi/src/engine/translator/func/instr_encoder.rs b/crates/wasmi/src/engine/translator/func/instr_encoder.rs index ebd4f0ec88..85848bb7c3 100644 --- a/crates/wasmi/src/engine/translator/func/instr_encoder.rs +++ b/crates/wasmi/src/engine/translator/func/instr_encoder.rs @@ -18,7 +18,13 @@ use crate::{ ValueStack, }, relink_result::RelinkResult as _, - utils::{BumpFuelConsumption as _, FuelInfo, IsInstructionParameter as _, WasmInteger}, + utils::{ + BumpFuelConsumption as _, + FuelInfo, + Instr, + IsInstructionParameter as _, + WasmInteger, + }, visit_register::VisitInputRegisters as _, }, ir::{ @@ -38,53 +44,6 @@ use crate::{ use alloc::vec::{Drain, Vec}; use core::mem; -/// A reference to an instruction of the partially -/// constructed function body of the [`InstrEncoder`]. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Instr(u32); - -impl Instr { - /// Creates an [`Instr`] from the given `usize` value. - /// - /// # Note - /// - /// This intentionally is an API intended for test purposes only. - /// - /// # Panics - /// - /// If the `value` exceeds limitations for [`Instr`]. - pub fn from_usize(value: usize) -> Self { - let value = value.try_into().unwrap_or_else(|error| { - panic!("invalid index {value} for instruction reference: {error}") - }); - Self(value) - } - - /// Returns an `usize` representation of the instruction index. - pub fn into_usize(self) -> usize { - self.0 as usize - } - - /// Creates an [`Instr`] form the given `u32` value. - pub fn from_u32(value: u32) -> Self { - Self(value) - } - - /// Returns an `u32` representation of the instruction index. - pub fn into_u32(self) -> u32 { - self.0 - } - - /// Returns the absolute distance between `self` and `other`. - /// - /// - Returns `0` if `self == other`. - /// - Returns `1` if `self` is adjacent to `other` in the sequence of instructions. - /// - etc.. - pub fn distance(self, other: Self) -> u32 { - self.0.abs_diff(other.0) - } -} - /// Encodes Wasmi bytecode instructions to an [`Instruction`] stream. #[derive(Debug, Default)] pub struct InstrEncoder { @@ -150,10 +109,9 @@ impl InstrSequence { /// If there are too many instructions in the instruction sequence. fn push_before(&mut self, instr: Instr, instruction: Instruction) -> Result { self.instrs.insert(instr.into_usize(), instruction); - let shifted_instr = instr - .into_u32() + let shifted_instr = u32::from(instr) .checked_add(1) - .map(Instr::from_u32) + .map(Instr::from) .unwrap_or_else(|| panic!("pushed to many instructions to a single function")); Ok(shifted_instr) } diff --git a/crates/wasmi/src/engine/translator/func/mod.rs b/crates/wasmi/src/engine/translator/func/mod.rs index 7d124d6ed8..ddfc978c58 100644 --- a/crates/wasmi/src/engine/translator/func/mod.rs +++ b/crates/wasmi/src/engine/translator/func/mod.rs @@ -15,7 +15,7 @@ mod simd; pub use self::{ control_frame::ControlFrame, control_stack::ControlStack, - instr_encoder::{Instr, InstrEncoder}, + instr_encoder::InstrEncoder, stack::TypedProvider, }; use self::{ @@ -38,7 +38,7 @@ use crate::{ code_map::CompiledFuncEntity, translator::{ labels::{LabelRef, LabelRegistry}, - utils::{FuelInfo, WasmFloat, WasmInteger, Wrap}, + utils::{FuelInfo, Instr, WasmFloat, WasmInteger, Wrap}, WasmTranslator, }, BlockType, @@ -224,7 +224,7 @@ impl WasmTranslator<'_> for FuncTranslator { // the compiled function. // Note: The function enclosing block fuel instruction is always // the instruction at the 0th index if fuel metering is enabled. - let fuel_instr = Instr::from_u32(0); + let fuel_instr = Instr::from(0_u32); let fuel_info = FuelInfo::some(fuel_costs.clone(), fuel_instr); self.instr_encoder .bump_fuel_consumption(&fuel_info, |costs| { diff --git a/crates/wasmi/src/engine/translator/labels.rs b/crates/wasmi/src/engine/translator/labels.rs index 6e469e1c15..cce29a3a2e 100644 --- a/crates/wasmi/src/engine/translator/labels.rs +++ b/crates/wasmi/src/engine/translator/labels.rs @@ -1,4 +1,4 @@ -use crate::{engine::translator::Instr, ir::BranchOffset, Error}; +use crate::{engine::translator::utils::Instr, ir::BranchOffset, Error}; use alloc::vec::Vec; use core::{ fmt::{self, Display}, @@ -147,7 +147,7 @@ impl LabelRegistry { ) -> Result { let offset = match *self.get_label(label) { Label::Pinned(target) => { - BranchOffset::from_src_to_dst(user.into_u32(), target.into_u32())? + BranchOffset::from_src_to_dst(u32::from(user), u32::from(target))? } Label::Unpinned => { self.users.push(LabelUser::new(label, user)); @@ -206,7 +206,7 @@ impl Iterator for ResolvedUserIter<'_> { .resolve_label(next.label) .unwrap_or_else(|err| panic!("failed to resolve user: {err}")); let offset = - BranchOffset::from_src_to_dst(src.into_u32(), dst.into_u32()).map_err(Into::into); + BranchOffset::from_src_to_dst(u32::from(src), u32::from(dst)).map_err(Into::into); Some((src, offset)) } } diff --git a/crates/wasmi/src/engine/translator/mod.rs b/crates/wasmi/src/engine/translator/mod.rs index 297d7a41ae..a3f04e4584 100644 --- a/crates/wasmi/src/engine/translator/mod.rs +++ b/crates/wasmi/src/engine/translator/mod.rs @@ -18,7 +18,7 @@ use crate::Engine; pub use self::{ driver::FuncTranslationDriver, error::TranslationError, - func::{FuncTranslator, FuncTranslatorAllocations, Instr}, + func::{FuncTranslator, FuncTranslatorAllocations}, }; use super::code_map::CompiledFuncEntity; use crate::{ diff --git a/crates/wasmi/src/engine/translator/utils.rs b/crates/wasmi/src/engine/translator/utils.rs index f7dc9affd7..e085526a12 100644 --- a/crates/wasmi/src/engine/translator/utils.rs +++ b/crates/wasmi/src/engine/translator/utils.rs @@ -1,4 +1,3 @@ -use super::Instr; use crate::{ core::{FuelCostsProvider, Typed, TypedVal, ValType}, ir::{Const16, Instruction, Sign}, @@ -215,3 +214,56 @@ impl IsInstructionParameter for Instruction { ) } } + +/// A reference to an encoded [`Instruction`]. +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct Instr(u32); + +impl From for Instr { + fn from(index: u32) -> Self { + Self(index) + } +} + +impl From for u32 { + fn from(instr: Instr) -> Self { + instr.0 + } +} + +impl Instr { + /// Creates an [`Instr`] from the given `usize` value. + /// + /// # Note + /// + /// This intentionally is an API intended for test purposes only. + /// + /// # Panics + /// + /// If the `value` exceeds limitations for [`Instr`]. + pub fn from_usize(value: usize) -> Self { + let Ok(index) = u32::try_from(value) else { + panic!("out of bounds index {value} for `Instr`") + }; + Self(index) + } + + /// Returns an `usize` representation of the instruction index. + pub fn into_usize(self) -> usize { + match usize::try_from(self.0) { + Ok(index) => index, + Err(error) => { + panic!("out of bound index {} for `Instr`: {error}", self.0) + } + } + } + + /// Returns the absolute distance between `self` and `other`. + /// + /// - Returns `0` if `self == other`. + /// - Returns `1` if `self` is adjacent to `other` in the sequence of instructions. + /// - etc.. + pub fn distance(self, other: Self) -> u32 { + self.0.abs_diff(other.0) + } +}