diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/parser/src/module.rs | 2 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/interpreter/mod.rs | 3 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/stack/blocks.rs | 5 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/stack/call_stack.rs | 29 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/stack/value_stack.rs | 4 | ||||
| -rw-r--r-- | crates/types/src/instructions.rs | 6 | ||||
| -rw-r--r-- | crates/types/src/lib.rs | 12 |
7 files changed, 24 insertions, 37 deletions
diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index e0fb0cc..5bc6a7e 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -5,7 +5,7 @@ use core::fmt::Debug; use tinywasm_types::{Data, Element, Export, FuncType, Global, Import, Instruction, MemoryType, TableType, ValType}; use wasmparser::{Payload, Validator}; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] pub struct CodeSection { pub locals: Box<[ValType]>, pub body: Box<[Instruction]>, diff --git a/crates/tinywasm/src/runtime/interpreter/mod.rs b/crates/tinywasm/src/runtime/interpreter/mod.rs index 80fb3f9..285ba8d 100644 --- a/crates/tinywasm/src/runtime/interpreter/mod.rs +++ b/crates/tinywasm/src/runtime/interpreter/mod.rs @@ -115,6 +115,7 @@ macro_rules! break_to { /// Run a single step of the interpreter /// A seperate function is used so later, we can more easily implement /// a step-by-step debugger (using generators once they're stable?) +// TODO: perf: don't push then pop the call frame, just pass it via ExecResult::Call instead #[inline(always)] // this improves performance by more than 20% in some cases fn exec_one( cf: &mut CallFrame, @@ -611,7 +612,7 @@ fn exec_one( let elem_idx = module.resolve_elem_addr(*elem_index); let elem = store.get_elem(elem_idx as usize)?; - if elem.kind != ElementKind::Passive { + if let ElementKind::Passive = elem.kind { return Err(Trap::TableOutOfBounds { offset: 0, len: 0, max: 0 }.into()); } diff --git a/crates/tinywasm/src/runtime/stack/blocks.rs b/crates/tinywasm/src/runtime/stack/blocks.rs index 76252b5..ab2d28c 100644 --- a/crates/tinywasm/src/runtime/stack/blocks.rs +++ b/crates/tinywasm/src/runtime/stack/blocks.rs @@ -19,11 +19,6 @@ impl Labels { #[inline] /// get the label at the given index, where 0 is the top of the stack pub(crate) fn get_relative_to_top(&self, index: usize) -> Option<&LabelFrame> { - let len = self.0.len(); - if index >= len { - return None; - } - self.0.get(self.0.len() - index - 1) } diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs index b19e332..46c745a 100644 --- a/crates/tinywasm/src/runtime/stack/call_stack.rs +++ b/crates/tinywasm/src/runtime/stack/call_stack.rs @@ -3,52 +3,45 @@ use crate::{ runtime::{BlockType, RawWasmValue}, Error, FunctionInstance, Result, Trap, }; +use alloc::vec; use alloc::{boxed::Box, rc::Rc, vec::Vec}; use tinywasm_types::{ValType, WasmValue}; use super::{blocks::Labels, LabelFrame}; // minimum call stack size -const CALL_STACK_SIZE: usize = 128; +const CALL_STACK_SIZE: usize = 256; const CALL_STACK_MAX_SIZE: usize = 1024; #[derive(Debug)] pub(crate) struct CallStack { stack: Vec<CallFrame>, - top: usize, } impl Default for CallStack { fn default() -> Self { - Self { stack: Vec::with_capacity(CALL_STACK_SIZE), top: 0 } + Self { stack: Vec::with_capacity(CALL_STACK_SIZE) } } } impl CallStack { + #[inline] pub(crate) fn is_empty(&self) -> bool { - self.top == 0 + self.stack.is_empty() } + #[inline] pub(crate) fn pop(&mut self) -> Result<CallFrame> { - assert!(self.top <= self.stack.len()); - if self.top == 0 { - return Err(Error::CallStackEmpty); - } - - self.top -= 1; - Ok(self.stack.pop().unwrap()) + self.stack.pop().ok_or_else(|| Error::CallStackEmpty) } #[inline] pub(crate) fn push(&mut self, call_frame: CallFrame) -> Result<()> { - assert!(self.top <= self.stack.len(), "stack is too small"); - log::debug!("stack size: {}", self.stack.len()); if self.stack.len() >= CALL_STACK_MAX_SIZE { return Err(Trap::CallStackOverflow.into()); } - self.top += 1; self.stack.push(call_frame); Ok(()) } @@ -79,7 +72,6 @@ impl CallFrame { /// Break to a block at the given index (relative to the current frame) /// Returns `None` if there is no block at the given index (e.g. if we need to return, this is handled by the caller) pub(crate) fn break_to(&mut self, break_to_relative: u32, value_stack: &mut super::ValueStack) -> Option<()> { - log::debug!("break_to_relative: {}", break_to_relative); let break_to = self.labels.get_relative_to_top(break_to_relative as usize)?; // instr_ptr points to the label instruction, but the next step @@ -111,14 +103,15 @@ impl CallFrame { Some(()) } + // TOOD: perf: this function is pretty hot + // Especially the two `extend` calls pub(crate) fn new_raw( func_instance_ptr: Rc<FunctionInstance>, params: &[RawWasmValue], local_types: Vec<ValType>, ) -> Self { - let mut locals = Vec::with_capacity(local_types.len() + params.len()); - locals.extend(params.iter().cloned()); - locals.extend(local_types.iter().map(|_| RawWasmValue::default())); + let mut locals = vec![RawWasmValue::default(); local_types.len() + params.len()]; + locals[..params.len()].copy_from_slice(params); Self { instr_ptr: 0, diff --git a/crates/tinywasm/src/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs index d36373b..e1c3107 100644 --- a/crates/tinywasm/src/runtime/stack/value_stack.rs +++ b/crates/tinywasm/src/runtime/stack/value_stack.rs @@ -98,9 +98,7 @@ impl ValueStack { } pub(crate) fn break_to(&mut self, new_stack_size: usize, result_count: usize) { - let len = self.stack.len(); - self.stack.copy_within((len - result_count)..len, new_stack_size); - self.stack.truncate(new_stack_size + result_count); + self.stack.drain(new_stack_size..(self.stack.len() - result_count)); } #[inline] diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index d5de50a..ba13979 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -10,7 +10,7 @@ pub enum BlockArgs { } /// Represents a memory immediate in a WebAssembly memory instruction. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone)] pub struct MemoryArg { pub mem_addr: MemAddr, pub align: u8, @@ -23,7 +23,7 @@ type BrTableLen = usize; type EndOffset = usize; type ElseOffset = usize; -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy)] pub enum ConstInstruction { I32Const(i32), I64Const(i64), @@ -46,7 +46,7 @@ pub enum ConstInstruction { /// This makes it easier to implement the label stack (we call it BlockFrameStack) iteratively. /// /// See <https://webassembly.github.io/spec/core/binary/instructions.html> -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy)] pub enum Instruction { // Custom Instructions BrLabel(LabelAddr), diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 3729e1a..9af8e11 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -71,7 +71,7 @@ pub struct TinyWasmModule { /// A WebAssembly value. /// /// See <https://webassembly.github.io/spec/core/syntax/types.html#value-types> -#[derive(Clone, PartialEq, Copy)] +#[derive(Clone, Copy)] pub enum WasmValue { // Num types /// A 32-bit integer. @@ -253,7 +253,7 @@ impl WasmValue { } /// Type of a WebAssembly value. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ValType { /// A 32-bit integer. I32, @@ -380,13 +380,13 @@ pub struct Global { pub init: ConstInstruction, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct GlobalType { pub mutable: bool, pub ty: ValType, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone)] pub struct TableType { pub element_type: ValType, pub size_initial: u32, @@ -406,7 +406,7 @@ impl TableType { #[derive(Debug, Clone)] /// Represents a memory's type. -#[derive(Copy, PartialEq, Eq, Hash)] +#[derive(Copy)] pub struct MemoryType { pub arch: MemoryArch, pub page_count_initial: u64, @@ -480,7 +480,7 @@ pub struct Element { pub ty: ValType, } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy)] pub enum ElementKind { Passive, Active { table: TableAddr, offset: ConstInstruction }, |
