From 25b798275baada2f090fbe21908a0874e541c044 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 26 Sep 2022 13:09:16 +0200 Subject: [PATCH 01/15] rename InstructionIdx -> Instr --- crates/wasmi/src/engine/bytecode/utils.rs | 12 ++++----- .../src/engine/func_builder/inst_builder.rs | 25 ++++++++----------- crates/wasmi/src/engine/func_builder/mod.rs | 6 ++--- crates/wasmi/src/engine/mod.rs | 2 +- crates/wasmi/src/module/tests.rs | 7 ++---- 5 files changed, 23 insertions(+), 29 deletions(-) diff --git a/crates/wasmi/src/engine/bytecode/utils.rs b/crates/wasmi/src/engine/bytecode/utils.rs index e4bdd4848b..cbacc16c2e 100644 --- a/crates/wasmi/src/engine/bytecode/utils.rs +++ b/crates/wasmi/src/engine/bytecode/utils.rs @@ -1,4 +1,4 @@ -use super::super::super::engine::InstructionIdx; +use super::super::super::engine::Instr; use core::fmt::Display; /// Defines how many stack values are going to be dropped and kept after branching. @@ -72,19 +72,19 @@ impl DropKeep { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Target { /// The destination program counter. - dst_pc: InstructionIdx, + dst_pc: Instr, /// How many values on the stack need to be dropped and kept. drop_keep: DropKeep, } impl Target { /// Creates a new `wasmi` branching target. - pub fn new(dst_pc: InstructionIdx, drop_keep: DropKeep) -> Self { + pub fn new(dst_pc: Instr, drop_keep: DropKeep) -> Self { Self { dst_pc, drop_keep } } /// Returns the destination program counter (as index). - pub fn destination_pc(self) -> InstructionIdx { + pub fn destination_pc(self) -> Instr { self.dst_pc } @@ -93,10 +93,10 @@ impl Target { /// # Panics /// /// If the old destination program counter was not [`InstructionIdx::INVALID`]. - pub fn update_destination_pc(&mut self, new_destination_pc: InstructionIdx) { + pub fn update_destination_pc(&mut self, new_destination_pc: Instr) { assert_eq!( self.destination_pc(), - InstructionIdx::INVALID, + Instr::INVALID, "can only update the destination pc of a target with an invalid \ destination pc but found a valid one: {:?}", self.destination_pc(), diff --git a/crates/wasmi/src/engine/func_builder/inst_builder.rs b/crates/wasmi/src/engine/func_builder/inst_builder.rs index 26462b9c40..db6ac3f89e 100644 --- a/crates/wasmi/src/engine/func_builder/inst_builder.rs +++ b/crates/wasmi/src/engine/func_builder/inst_builder.rs @@ -7,9 +7,9 @@ use core::mem; /// A reference to an instruction of the partially /// constructed function body of the [`InstructionsBuilder`]. #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct InstructionIdx(u32); +pub struct Instr(u32); -impl InstructionIdx { +impl Instr { /// An invalid instruction index. /// /// # Note @@ -58,7 +58,7 @@ enum Label { /// # Note /// /// A fully resolved label no longer required knowledge about its uses. - Resolved(InstructionIdx), + Resolved(Instr), } impl Default for Label { @@ -75,12 +75,9 @@ pub struct LabelIdx(pub(crate) usize); #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Reloc { /// Patch the target of the `br`, `br_eqz` or `br_nez` instruction. - Br { inst_idx: InstructionIdx }, + Br { inst_idx: Instr }, /// Patch the specified target index inside of a Wasm `br_table` instruction. - BrTable { - inst_idx: InstructionIdx, - target_idx: usize, - }, + BrTable { inst_idx: Instr, target_idx: usize }, } /// The relative depth of a Wasm branching target. @@ -120,8 +117,8 @@ impl InstructionsBuilder { } /// Returns the current instruction pointer as index. - pub fn current_pc(&self) -> InstructionIdx { - InstructionIdx::from_usize(self.insts.len()) + pub fn current_pc(&self) -> Instr { + Instr::from_usize(self.insts.len()) } /// Creates a new unresolved label and returns an index to it. @@ -188,7 +185,7 @@ impl InstructionsBuilder { /// /// If resolution fails puts a placeholder into the respective label /// and push the new user for later resolution to take place. - pub fn try_resolve_label(&mut self, label: LabelIdx, reloc_provider: F) -> InstructionIdx + pub fn try_resolve_label(&mut self, label: LabelIdx, reloc_provider: F) -> Instr where F: FnOnce() -> Reloc, { @@ -196,7 +193,7 @@ impl InstructionsBuilder { Label::Resolved(dst_pc) => *dst_pc, Label::Unresolved { uses } => { uses.push(reloc_provider()); - InstructionIdx::INVALID + Instr::INVALID } } } @@ -204,14 +201,14 @@ impl InstructionsBuilder { /// Pushes the internal instruction bytecode to the [`InstructionsBuilder`]. /// /// Returns an [`InstructionIdx`] to refer to the pushed instruction. - pub fn push_inst(&mut self, inst: Instruction) -> InstructionIdx { + pub fn push_inst(&mut self, inst: Instruction) -> Instr { let idx = self.current_pc(); self.insts.push(inst); idx } /// Allows to patch the branch target of branch instructions. - pub fn patch_relocation(&mut self, reloc: Reloc, dst_pc: InstructionIdx) { + pub fn patch_relocation(&mut self, reloc: Reloc, dst_pc: Instr) { match reloc { Reloc::Br { inst_idx } => match &mut self.insts[inst_idx.into_usize()] { Instruction::Br(target) diff --git a/crates/wasmi/src/engine/func_builder/mod.rs b/crates/wasmi/src/engine/func_builder/mod.rs index 51e739b227..99609a6d8d 100644 --- a/crates/wasmi/src/engine/func_builder/mod.rs +++ b/crates/wasmi/src/engine/func_builder/mod.rs @@ -21,7 +21,7 @@ use self::{ }; pub use self::{ error::TranslationError, - inst_builder::{InstructionIdx, InstructionsBuilder, LabelIdx, RelativeDepth, Reloc}, + inst_builder::{Instr, InstructionsBuilder, LabelIdx, RelativeDepth, Reloc}, }; use super::{DropKeep, FuncBody, Instruction, Target}; use crate::{ @@ -183,9 +183,9 @@ impl<'parser> FuncBuilder<'parser> { /// Try to resolve the given label. /// /// In case the label cannot yet be resolved register the [`Reloc`] as its user. - fn try_resolve_label(&mut self, label: LabelIdx, reloc_provider: F) -> InstructionIdx + fn try_resolve_label(&mut self, label: LabelIdx, reloc_provider: F) -> Instr where - F: FnOnce(InstructionIdx) -> Reloc, + F: FnOnce(Instr) -> Reloc, { let pc = self.alloc.inst_builder.current_pc(); self.alloc diff --git a/crates/wasmi/src/engine/mod.rs b/crates/wasmi/src/engine/mod.rs index d847fdde36..e8b3e19ed1 100644 --- a/crates/wasmi/src/engine/mod.rs +++ b/crates/wasmi/src/engine/mod.rs @@ -27,7 +27,7 @@ pub use self::{ func_builder::{ FuncBuilder, FunctionBuilderAllocations, - InstructionIdx, + Instr, LabelIdx, RelativeDepth, Reloc, diff --git a/crates/wasmi/src/module/tests.rs b/crates/wasmi/src/module/tests.rs index bcc37fc489..add1e00601 100644 --- a/crates/wasmi/src/module/tests.rs +++ b/crates/wasmi/src/module/tests.rs @@ -1,6 +1,6 @@ use super::*; use crate::{ - engine::{bytecode::Instruction, DropKeep, InstructionIdx, Target}, + engine::{bytecode::Instruction, DropKeep, Instr, Target}, Engine, }; @@ -294,10 +294,7 @@ fn drop_locals() { macro_rules! target { ( $inst_idx:expr, drop: $drop:expr, keep: $keep:expr ) => { - Target::new( - InstructionIdx::from_usize($inst_idx), - drop_keep($drop, $keep), - ) + Target::new(Instr::from_usize($inst_idx), drop_keep($drop, $keep)) }; } From 704139950fd4b55412b20d5f958dc92b05fabf8b Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 26 Sep 2022 13:10:45 +0200 Subject: [PATCH 02/15] rename LabelIdx -> LabelRef --- .../src/engine/func_builder/control_frame.rs | 34 +++++++++---------- .../src/engine/func_builder/inst_builder.rs | 14 ++++---- crates/wasmi/src/engine/func_builder/mod.rs | 6 ++-- crates/wasmi/src/engine/mod.rs | 2 +- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/crates/wasmi/src/engine/func_builder/control_frame.rs b/crates/wasmi/src/engine/func_builder/control_frame.rs index 7aaac7958c..4917012464 100644 --- a/crates/wasmi/src/engine/func_builder/control_frame.rs +++ b/crates/wasmi/src/engine/func_builder/control_frame.rs @@ -1,4 +1,4 @@ -use crate::{engine::LabelIdx, module::BlockType}; +use crate::{engine::LabelRef, module::BlockType}; /// A Wasm `block` control flow frame. #[derive(Debug, Copy, Clone)] @@ -8,12 +8,12 @@ pub struct BlockControlFrame { /// The value stack height upon entering the [`BlockControlFrame`]. stack_height: u32, /// Label representing the end of the [`BlockControlFrame`]. - end_label: LabelIdx, + end_label: LabelRef, } impl BlockControlFrame { /// Creates a new [`BlockControlFrame`]. - pub fn new(block_type: BlockType, end_label: LabelIdx, stack_height: u32) -> Self { + pub fn new(block_type: BlockType, end_label: LabelRef, stack_height: u32) -> Self { Self { block_type, stack_height, @@ -26,12 +26,12 @@ impl BlockControlFrame { /// # Note /// /// Branches to [`BlockControlFrame`] jump to the end of the frame. - pub fn branch_destination(&self) -> LabelIdx { + pub fn branch_destination(&self) -> LabelRef { self.end_label } /// Returns the label to the end of the [`BlockControlFrame`]. - pub fn end_label(&self) -> LabelIdx { + pub fn end_label(&self) -> LabelRef { self.end_label } @@ -54,12 +54,12 @@ pub struct LoopControlFrame { /// The value stack height upon entering the [`LoopControlFrame`]. stack_height: u32, /// Label representing the head of the [`LoopControlFrame`]. - head_label: LabelIdx, + head_label: LabelRef, } impl LoopControlFrame { /// Creates a new [`LoopControlFrame`]. - pub fn new(block_type: BlockType, head_label: LabelIdx, stack_height: u32) -> Self { + pub fn new(block_type: BlockType, head_label: LabelRef, stack_height: u32) -> Self { Self { block_type, stack_height, @@ -72,7 +72,7 @@ impl LoopControlFrame { /// # Note /// /// Branches to [`LoopControlFrame`] jump to the head of the loop. - pub fn branch_destination(&self) -> LabelIdx { + pub fn branch_destination(&self) -> LabelRef { self.head_label } @@ -95,9 +95,9 @@ pub struct IfControlFrame { /// The value stack height upon entering the [`IfControlFrame`]. stack_height: u32, /// Label representing the end of the [`IfControlFrame`]. - end_label: LabelIdx, + end_label: LabelRef, /// Label representing the optional `else` branch of the [`IfControlFrame`]. - else_label: LabelIdx, + else_label: LabelRef, /// End of `then` branch is reachable. /// /// # Note @@ -116,8 +116,8 @@ impl IfControlFrame { /// Creates a new [`IfControlFrame`]. pub fn new( block_type: BlockType, - end_label: LabelIdx, - else_label: LabelIdx, + end_label: LabelRef, + else_label: LabelRef, stack_height: u32, ) -> Self { assert_ne!( @@ -138,17 +138,17 @@ impl IfControlFrame { /// # Note /// /// Branches to [`IfControlFrame`] jump to the end of the if and else frame. - pub fn branch_destination(&self) -> LabelIdx { + pub fn branch_destination(&self) -> LabelRef { self.end_label } /// Returns the label to the end of the [`IfControlFrame`]. - pub fn end_label(&self) -> LabelIdx { + pub fn end_label(&self) -> LabelRef { self.end_label } /// Returns the label to the optional `else` of the [`IfControlFrame`]. - pub fn else_label(&self) -> LabelIdx { + pub fn else_label(&self) -> LabelRef { self.else_label } @@ -259,7 +259,7 @@ impl ControlFrame { } /// Returns the label for the branch destination of the [`ControlFrame`]. - pub fn branch_destination(&self) -> LabelIdx { + pub fn branch_destination(&self) -> LabelRef { match self { Self::Block(frame) => frame.branch_destination(), Self::Loop(frame) => frame.branch_destination(), @@ -276,7 +276,7 @@ impl ControlFrame { /// All [`ControlFrame`] kinds have it except [`ControlFrame::Loop`]. /// In order to a [`ControlFrame::Loop`] to branch outside it is required /// to be wrapped in another control frame such as [`ControlFrame::Block`]. - pub fn end_label(&self) -> LabelIdx { + pub fn end_label(&self) -> LabelRef { match self { Self::Block(frame) => frame.end_label(), Self::If(frame) => frame.end_label(), diff --git a/crates/wasmi/src/engine/func_builder/inst_builder.rs b/crates/wasmi/src/engine/func_builder/inst_builder.rs index db6ac3f89e..1632a89456 100644 --- a/crates/wasmi/src/engine/func_builder/inst_builder.rs +++ b/crates/wasmi/src/engine/func_builder/inst_builder.rs @@ -69,7 +69,7 @@ impl Default for Label { /// A unique label identifier. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct LabelIdx(pub(crate) usize); +pub struct LabelRef(pub(crate) usize); /// A relocation entry that specifies. #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -122,14 +122,14 @@ impl InstructionsBuilder { } /// Creates a new unresolved label and returns an index to it. - pub fn new_label(&mut self) -> LabelIdx { - let idx = LabelIdx(self.labels.len()); + pub fn new_label(&mut self) -> LabelRef { + let idx = LabelRef(self.labels.len()); self.labels.push(Label::default()); idx } /// Returns `true` if `label` has been resolved. - fn is_resolved(&self, label: LabelIdx) -> bool { + fn is_resolved(&self, label: LabelRef) -> bool { if let Label::Resolved(_) = &self.labels[label.0] { return true; } @@ -145,7 +145,7 @@ impl InstructionsBuilder { /// This is used at a position of the Wasm bytecode where it is clear that /// the given label can be resolved properly. /// This usually takes place when encountering the Wasm `End` operand for example. - pub fn resolve_label_if_unresolved(&mut self, label: LabelIdx) { + pub fn resolve_label_if_unresolved(&mut self, label: LabelRef) { if self.is_resolved(label) { // Nothing to do in this case. return; @@ -164,7 +164,7 @@ impl InstructionsBuilder { /// # Panics /// /// If the label has already been resolved. - pub fn resolve_label(&mut self, label: LabelIdx) { + pub fn resolve_label(&mut self, label: LabelRef) { let dst_pc = self.current_pc(); let old_label = mem::replace(&mut self.labels[label.0], Label::Resolved(dst_pc)); match old_label { @@ -185,7 +185,7 @@ impl InstructionsBuilder { /// /// If resolution fails puts a placeholder into the respective label /// and push the new user for later resolution to take place. - pub fn try_resolve_label(&mut self, label: LabelIdx, reloc_provider: F) -> Instr + pub fn try_resolve_label(&mut self, label: LabelRef, reloc_provider: F) -> Instr where F: FnOnce() -> Reloc, { diff --git a/crates/wasmi/src/engine/func_builder/mod.rs b/crates/wasmi/src/engine/func_builder/mod.rs index 99609a6d8d..d91596ce86 100644 --- a/crates/wasmi/src/engine/func_builder/mod.rs +++ b/crates/wasmi/src/engine/func_builder/mod.rs @@ -21,7 +21,7 @@ use self::{ }; pub use self::{ error::TranslationError, - inst_builder::{Instr, InstructionsBuilder, LabelIdx, RelativeDepth, Reloc}, + inst_builder::{Instr, InstructionsBuilder, LabelRef, RelativeDepth, Reloc}, }; use super::{DropKeep, FuncBody, Instruction, Target}; use crate::{ @@ -183,7 +183,7 @@ impl<'parser> FuncBuilder<'parser> { /// Try to resolve the given label. /// /// In case the label cannot yet be resolved register the [`Reloc`] as its user. - fn try_resolve_label(&mut self, label: LabelIdx, reloc_provider: F) -> Instr + fn try_resolve_label(&mut self, label: LabelRef, reloc_provider: F) -> Instr where F: FnOnce(Instr) -> Reloc, { @@ -356,7 +356,7 @@ impl<'parser> FuncBuilder<'parser> { #[derive(Debug)] pub enum AcquiredTarget { /// The branch jumps to the label. - Branch(LabelIdx, DropKeep), + Branch(LabelRef, DropKeep), /// The branch returns to the caller. /// /// # Note diff --git a/crates/wasmi/src/engine/mod.rs b/crates/wasmi/src/engine/mod.rs index e8b3e19ed1..1023bfa515 100644 --- a/crates/wasmi/src/engine/mod.rs +++ b/crates/wasmi/src/engine/mod.rs @@ -28,7 +28,7 @@ pub use self::{ FuncBuilder, FunctionBuilderAllocations, Instr, - LabelIdx, + LabelRef, RelativeDepth, Reloc, TranslationError, From 559376e0507a30c248d47e3689c7ff8ddd206218 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 26 Sep 2022 13:13:49 +0200 Subject: [PATCH 03/15] rename some label methods --- crates/wasmi/src/engine/func_builder/inst_builder.rs | 6 +++--- crates/wasmi/src/engine/func_builder/mod.rs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/wasmi/src/engine/func_builder/inst_builder.rs b/crates/wasmi/src/engine/func_builder/inst_builder.rs index 1632a89456..12a1d5e73b 100644 --- a/crates/wasmi/src/engine/func_builder/inst_builder.rs +++ b/crates/wasmi/src/engine/func_builder/inst_builder.rs @@ -145,12 +145,12 @@ impl InstructionsBuilder { /// This is used at a position of the Wasm bytecode where it is clear that /// the given label can be resolved properly. /// This usually takes place when encountering the Wasm `End` operand for example. - pub fn resolve_label_if_unresolved(&mut self, label: LabelRef) { + pub fn pin_label_if_unpinned(&mut self, label: LabelRef) { if self.is_resolved(label) { // Nothing to do in this case. return; } - self.resolve_label(label); + self.pin_label(label); } /// Resolve the label at the current instruction position. @@ -164,7 +164,7 @@ impl InstructionsBuilder { /// # Panics /// /// If the label has already been resolved. - pub fn resolve_label(&mut self, label: LabelRef) { + pub fn pin_label(&mut self, label: LabelRef) { let dst_pc = self.current_pc(); let old_label = mem::replace(&mut self.labels[label.0], Label::Resolved(dst_pc)); match old_label { diff --git a/crates/wasmi/src/engine/func_builder/mod.rs b/crates/wasmi/src/engine/func_builder/mod.rs index d91596ce86..f02fd2e3bf 100644 --- a/crates/wasmi/src/engine/func_builder/mod.rs +++ b/crates/wasmi/src/engine/func_builder/mod.rs @@ -444,7 +444,7 @@ impl<'parser> FuncBuilder<'parser> { if self.is_reachable() { let stack_height = self.frame_stack_height(block_type); let header = self.alloc.inst_builder.new_label(); - self.alloc.inst_builder.resolve_label(header); + self.alloc.inst_builder.pin_label(header); self.alloc.control_frames.push_frame(LoopControlFrame::new( block_type, header, @@ -528,7 +528,7 @@ impl<'parser> FuncBuilder<'parser> { self.alloc.inst_builder.push_inst(Instruction::Br(target)); } // Now resolve labels for the instructions of the `else` block - self.alloc.inst_builder.resolve_label(if_frame.else_label()); + self.alloc.inst_builder.pin_label(if_frame.else_label()); // We need to reset the value stack to exactly how it has been // when entering the `if` in the first place so that the `else` // block has the same parameters on top of the stack. @@ -552,12 +552,12 @@ impl<'parser> FuncBuilder<'parser> { // in case there was an `Else` block. self.alloc .inst_builder - .resolve_label_if_unresolved(if_frame.else_label()); + .pin_label_if_unpinned(if_frame.else_label()); } if frame.is_reachable() && !matches!(frame.kind(), ControlFrameKind::Loop) { // At this point we can resolve the `End` labels. // Note that `loop` control frames do not have an `End` label. - self.alloc.inst_builder.resolve_label(frame.end_label()); + self.alloc.inst_builder.pin_label(frame.end_label()); } // These bindings are required because of borrowing issues. let frame_reachable = frame.is_reachable(); From 72a6416e09e5038b13a54278f7adef97b9fc1d52 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 26 Sep 2022 13:37:55 +0200 Subject: [PATCH 04/15] split Instruction into IrInstruction and ExecInstruction We have not yet introduced an actual difference between them in this commit. --- crates/wasmi/src/engine/bytecode/mod.rs | 29 ++- crates/wasmi/src/engine/bytecode/tests.rs | 3 +- crates/wasmi/src/engine/code_map.rs | 12 +- crates/wasmi/src/engine/executor.rs | 25 ++- .../src/engine/func_builder/inst_builder.rs | 202 +++++++++++++++++- crates/wasmi/src/engine/func_builder/mod.rs | 31 ++- crates/wasmi/src/engine/mod.rs | 12 +- crates/wasmi/src/module/tests.rs | 6 +- 8 files changed, 281 insertions(+), 39 deletions(-) diff --git a/crates/wasmi/src/engine/bytecode/mod.rs b/crates/wasmi/src/engine/bytecode/mod.rs index 8d9a9d2642..a44209281f 100644 --- a/crates/wasmi/src/engine/bytecode/mod.rs +++ b/crates/wasmi/src/engine/bytecode/mod.rs @@ -15,8 +15,15 @@ pub use self::utils::{ SignatureIdx, Target, }; +use core::fmt::Debug; use wasmi_core::UntypedValue; +/// Internal types of an [`Instruction`] type. +pub trait InstructionTypes { + /// A branching target. + type Target: Debug + Copy + Clone + PartialEq + Eq; +} + /// The internal `wasmi` bytecode that is stored for Wasm functions. /// /// # Note @@ -25,14 +32,17 @@ use wasmi_core::UntypedValue; /// /// For example the `BrTable` instruction is unrolled into separate instructions /// each representing either the `BrTable` head or one of its branching targets. -#[derive(Copy, Debug, Clone, PartialEq, Eq)] -pub enum Instruction { +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum Instruction +where + T: InstructionTypes, +{ LocalGet { local_depth: LocalDepth }, LocalSet { local_depth: LocalDepth }, LocalTee { local_depth: LocalDepth }, - Br(Target), - BrIfEqz(Target), - BrIfNez(Target), + Br(::Target), + BrIfEqz(::Target), + BrIfNez(::Target), ReturnIfNez(DropKeep), BrTable { len_targets: usize }, Unreachable, @@ -207,11 +217,14 @@ pub enum Instruction { I64TruncSatF64U, } -impl Instruction { +impl Instruction +where + T: InstructionTypes, +{ /// Creates a new `Const` instruction from the given value. - pub fn constant(value: T) -> Self + pub fn constant(value: C) -> Self where - T: Into, + C: Into, { Self::Const(value.into()) } diff --git a/crates/wasmi/src/engine/bytecode/tests.rs b/crates/wasmi/src/engine/bytecode/tests.rs index f1bf0e5617..89911c4645 100644 --- a/crates/wasmi/src/engine/bytecode/tests.rs +++ b/crates/wasmi/src/engine/bytecode/tests.rs @@ -1,8 +1,9 @@ use super::*; +use crate::engine::executor::ExecInstruction; #[test] fn size_of_instruction() { - assert_eq!(core::mem::size_of::(), 16); + assert_eq!(core::mem::size_of::(), 16); assert_eq!(core::mem::size_of::(), 4); assert_eq!(core::mem::size_of::(), 8); } diff --git a/crates/wasmi/src/engine/code_map.rs b/crates/wasmi/src/engine/code_map.rs index 60e43fc9f3..bbe7675df0 100644 --- a/crates/wasmi/src/engine/code_map.rs +++ b/crates/wasmi/src/engine/code_map.rs @@ -1,6 +1,6 @@ //! Datastructure to efficiently store function bodies and their instructions. -use super::{super::Index, Instruction}; +use super::{super::Index, executor::ExecInstruction}; use alloc::vec::Vec; /// A reference to a Wasm function body stored in the [`CodeMap`]. @@ -73,7 +73,7 @@ pub struct CodeMap { /// /// Also this improves efficiency of deallocating the [`CodeMap`] /// and generally improves data locality. - insts: Vec, + insts: Vec, } impl CodeMap { @@ -84,7 +84,7 @@ impl CodeMap { /// instructions. pub fn alloc(&mut self, len_locals: usize, max_stack_height: usize, insts: I) -> FuncBody where - I: IntoIterator, + I: IntoIterator, { let start = self.insts.len(); self.insts.extend(insts); @@ -116,7 +116,7 @@ impl CodeMap { /// The instructions of a resolved [`FuncBody`]. #[derive(Debug, Copy, Clone)] pub struct Instructions<'a> { - insts: &'a [Instruction], + insts: &'a [ExecInstruction], } impl<'a> Instructions<'a> { @@ -126,7 +126,7 @@ impl<'a> Instructions<'a> { /// /// If there is no instruction at the given index. #[cfg(test)] - pub fn get(&self, index: usize) -> Option<&Instruction> { + pub fn get(&self, index: usize) -> Option<&ExecInstruction> { self.insts.get(index) } @@ -136,7 +136,7 @@ impl<'a> Instructions<'a> { /// /// Panics in debug mode if the `pc` is invalid for the [`Instructions`]. #[inline(always)] - pub unsafe fn get_release_unchecked(&self, pc: usize) -> &'a Instruction { + pub unsafe fn get_release_unchecked(&self, pc: usize) -> &'a ExecInstruction { debug_assert!( self.insts.get(pc).is_some(), "unexpectedly missing instruction at index {pc}", diff --git a/crates/wasmi/src/engine/executor.rs b/crates/wasmi/src/engine/executor.rs index f11ae459fd..23134788fb 100644 --- a/crates/wasmi/src/engine/executor.rs +++ b/crates/wasmi/src/engine/executor.rs @@ -1,6 +1,14 @@ use super::{ super::{Memory, Table}, - bytecode::{FuncIdx, GlobalIdx, Instruction, LocalDepth, Offset, SignatureIdx}, + bytecode::{ + FuncIdx, + GlobalIdx, + Instruction, + InstructionTypes, + LocalDepth, + Offset, + SignatureIdx, + }, cache::InstanceCache, code_map::Instructions, stack::ValueStackRef, @@ -20,6 +28,17 @@ use crate::{ use core::cmp; use wasmi_core::{memory_units::Pages, ExtendInto, LittleEndianConvert, UntypedValue, WrapInto}; +/// Base implementer for executable [`InstructionTypes`]. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum ExecInstructionTypes {} + +impl InstructionTypes for ExecInstructionTypes { + type Target = Target; +} + +/// An executable compiled [`Instruction`]. +pub type ExecInstruction = Instruction; + /// Executes the given function `frame`. /// /// # Note @@ -275,9 +294,9 @@ impl<'ctx, 'engine, 'func, HostData> Executor<'ctx, 'engine, 'func, HostData> { } } - /// Returns the [`Instruction`] at the current program counter. + /// Returns the [`ExecInstruction`] at the current program counter. #[inline(always)] - fn instr(&self) -> &'engine Instruction { + fn instr(&self) -> &'engine ExecInstruction { // # Safety // // Properly constructed `wasmi` bytecode can never produce invalid `pc`. diff --git a/crates/wasmi/src/engine/func_builder/inst_builder.rs b/crates/wasmi/src/engine/func_builder/inst_builder.rs index 12a1d5e73b..f31f5b6dbc 100644 --- a/crates/wasmi/src/engine/func_builder/inst_builder.rs +++ b/crates/wasmi/src/engine/func_builder/inst_builder.rs @@ -1,9 +1,11 @@ //! Abstractions to build up instructions forming Wasm function bodies. -use crate::engine::{Engine, FuncBody, Instruction}; +use crate::engine::{executor::ExecInstruction, Engine, FuncBody, Instruction}; use alloc::vec::Vec; use core::mem; +use super::IrInstruction; + /// A reference to an instruction of the partially /// constructed function body of the [`InstructionsBuilder`]. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -104,7 +106,7 @@ impl RelativeDepth { #[derive(Debug, Default)] pub struct InstructionsBuilder { /// The instructions of the partially constructed function body. - insts: Vec, + insts: Vec, /// All labels and their uses. labels: Vec