Skip to content

Commit

Permalink
feat: block stack, make cargofmt a bit more sane
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <[email protected]>
  • Loading branch information
explodingcamera committed Dec 5, 2023
1 parent 15c7ec4 commit ef4dbf2
Show file tree
Hide file tree
Showing 15 changed files with 288 additions and 329 deletions.
10 changes: 2 additions & 8 deletions crates/cli/src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ fn main() -> Result<()> {
_ => log::LevelFilter::Info,
};

pretty_env_logger::formatted_builder()
.filter_level(level)
.init();
pretty_env_logger::formatted_builder().filter_level(level).init();

let cwd = std::env::current_dir()?;

Expand All @@ -84,11 +82,7 @@ fn main() -> Result<()> {
tinywasm::Module::parse_bytes(&wasm)?
}
#[cfg(not(feature = "wat"))]
true => {
return Err(color_eyre::eyre::eyre!(
"wat support is not enabled in this build"
))
}
true => return Err(color_eyre::eyre::eyre!("wat support is not enabled in this build")),
false => tinywasm::Module::parse_file(path)?,
};

Expand Down
394 changes: 193 additions & 201 deletions crates/parser/src/conversion.rs

Large diffs are not rendered by default.

8 changes: 3 additions & 5 deletions crates/parser/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ impl Debug for ParseError {
write!(f, "error parsing module: {} at offset {}", message, offset)
}
Self::InvalidEncoding(encoding) => write!(f, "invalid encoding: {:?}", encoding),
Self::InvalidLocalCount { expected, actual } => write!(
f,
"invalid local count: expected {}, actual {}",
expected, actual
),
Self::InvalidLocalCount { expected, actual } => {
write!(f, "invalid local count: expected {}, actual {}", expected, actual)
}
Self::EndNotReached => write!(f, "end of module not reached"),
Self::Other(message) => write!(f, "unknown error: {}", message),
}
Expand Down
16 changes: 6 additions & 10 deletions crates/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,10 @@ impl Parser {
}

#[cfg(feature = "std")]
pub fn parse_module_file(
&self,
path: impl AsRef<crate::std::path::Path> + Clone,
) -> Result<TinyWasmModule> {
pub fn parse_module_file(&self, path: impl AsRef<crate::std::path::Path> + Clone) -> Result<TinyWasmModule> {
use alloc::format;
let f = crate::std::fs::File::open(path.clone()).map_err(|e| {
ParseError::Other(format!("Error opening file {:?}: {}", path.as_ref(), e))
})?;
let f = crate::std::fs::File::open(path.clone())
.map_err(|e| ParseError::Other(format!("Error opening file {:?}: {}", path.as_ref(), e)))?;

let mut reader = crate::std::io::BufReader::new(f);
self.parse_module_stream(&mut reader)
Expand All @@ -66,9 +62,9 @@ impl Parser {
wasmparser::Chunk::NeedMoreData(hint) => {
let len = buffer.len();
buffer.extend((0..hint).map(|_| 0u8));
let read_bytes = stream.read(&mut buffer[len..]).map_err(|e| {
ParseError::Other(format!("Error reading from stream: {}", e))
})?;
let read_bytes = stream
.read(&mut buffer[len..])
.map_err(|e| ParseError::Other(format!("Error reading from stream: {}", e)))?;
buffer.truncate(len + read_bytes);
eof = read_bytes == 0;
}
Expand Down
22 changes: 5 additions & 17 deletions crates/parser/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,12 @@ impl ModuleReader {
use wasmparser::Payload::*;

match payload {
Version {
num,
encoding,
range,
} => {
Version { num, encoding, range } => {
validator.version(num, encoding, &range)?;
self.version = Some(num);
match encoding {
wasmparser::Encoding::Module => {}
wasmparser::Encoding::Component => {
return Err(ParseError::InvalidEncoding(encoding))
}
wasmparser::Encoding::Component => return Err(ParseError::InvalidEncoding(encoding)),
}
}
StartSection { func, range } => {
Expand All @@ -88,10 +82,7 @@ impl ModuleReader {
FunctionSection(reader) => {
debug!("Found function section");
validator.function_section(&reader)?;
self.function_section = reader
.into_iter()
.map(|f| Ok(f?))
.collect::<Result<Vec<_>>>()?;
self.function_section = reader.into_iter().map(|f| Ok(f?)).collect::<Result<Vec<_>>>()?;
}
TableSection(_reader) => {
return Err(ParseError::UnsupportedSection("Table section".into()));
Expand Down Expand Up @@ -135,8 +126,7 @@ impl ModuleReader {
debug!("Found code section entry");
validator.code_section_entry(&function)?;

self.code_section
.push(conversion::convert_module_code(function)?);
self.code_section.push(conversion::convert_module_code(function)?);
}
ImportSection(_reader) => {
return Err(ParseError::UnsupportedSection("Import section".into()));
Expand Down Expand Up @@ -166,9 +156,7 @@ impl ModuleReader {
debug!("Found custom section");
debug!("Skipping custom section: {:?}", reader.name());
}
UnknownSection { .. } => {
return Err(ParseError::UnsupportedSection("Unknown section".into()))
}
UnknownSection { .. } => return Err(ParseError::UnsupportedSection("Unknown section".into())),
section => {
return Err(ParseError::UnsupportedSection(format!(
"Unsupported section: {:?}",
Expand Down
2 changes: 2 additions & 0 deletions crates/tinywasm/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub enum Error {

FuncDidNotReturn,
StackUnderflow,
BlockStackUnderflow,
CallStackEmpty,

InvalidStore,
Expand All @@ -22,6 +23,7 @@ impl Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::FuncDidNotReturn => write!(f, "function did not return"),
Self::BlockStackUnderflow => write!(f, "block stack underflow"),
Self::StackUnderflow => write!(f, "stack underflow"),
Self::ParseError(err) => write!(f, "error parsing module: {:?}", err),
Self::UnsupportedFeature(feature) => write!(f, "unsupported feature: {}", feature),
Expand Down
2 changes: 1 addition & 1 deletion crates/tinywasm/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl FuncHandle {
Ok(res
.iter()
.zip(func_ty.results.iter())
.map(|(v, ty)| v.into_typed(*ty))
.map(|(v, ty)| v.attach_type(*ty))
.collect())
}
}
Expand Down
32 changes: 23 additions & 9 deletions crates/tinywasm/src/runtime/executer.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
use super::{Runtime, Stack};
use crate::{Error, Result};
use alloc::vec;
use log::debug;
use tinywasm_types::Instruction;

enum BlockMarker {
Top,
Loop,
If,
Else,
Block,
}

impl<const CHECK_TYPES: bool> Runtime<CHECK_TYPES> {
pub(crate) fn exec(
&self,
stack: &mut Stack,
instrs: core::slice::Iter<Instruction>,
) -> Result<()> {
pub(crate) fn exec(&self, stack: &mut Stack, instrs: core::slice::Iter<Instruction>) -> Result<()> {
let call_frame = stack.call_stack.top_mut()?;
let mut blocks = vec![BlockMarker::Top];

for instr in instrs {
use tinywasm_types::Instruction::*;
match instr {
End => {
let block = blocks.pop().ok_or(Error::BlockStackUnderflow)?;

use BlockMarker::*;
match block {
Top => return Ok(()),
Block => todo!(),
Loop => todo!(),
If => todo!(),
Else => todo!(),
}
}
LocalGet(local_index) => {
let val = call_frame.get_local(*local_index as usize);
debug!("local: {:#?}", val);
Expand Down Expand Up @@ -52,10 +70,6 @@ impl<const CHECK_TYPES: bool> Runtime<CHECK_TYPES> {
let b: i32 = b.into();
stack.values.push((a - b).into());
}
End => {
debug!("stack: {:?}", stack);
return Ok(());
}
_ => todo!(),
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/tinywasm/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod stack;
mod value;

pub use stack::*;
pub use value::UntypedWasmValue;
pub(crate) use value::RawWasmValue;

/// A WebAssembly Runtime.
/// See https://webassembly.github.io/spec/core/exec/runtime.html
Expand Down
10 changes: 5 additions & 5 deletions crates/tinywasm/src/runtime/stack/call_stack.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{runtime::UntypedWasmValue, Error, Result};
use crate::{runtime::RawWasmValue, Error, Result};
use alloc::{boxed::Box, vec::Vec};
use tinywasm_types::{ValType, WasmValue};

Expand Down Expand Up @@ -51,14 +51,14 @@ pub struct CallFrame<const CHECK: bool> {
pub instr_ptr: usize,
pub func_ptr: usize,

pub locals: Box<[UntypedWasmValue]>,
pub locals: Box<[RawWasmValue]>,
pub local_count: usize,
}

impl<const CHECK: bool> CallFrame<CHECK> {
pub fn new(func_ptr: usize, params: &[WasmValue], local_types: Vec<ValType>) -> Self {
let mut locals = Vec::with_capacity(local_types.len() + params.len());
locals.extend(params.iter().map(|v| UntypedWasmValue::from(*v)));
locals.extend(params.iter().map(|v| RawWasmValue::from(*v)));

Self {
instr_ptr: 0,
Expand All @@ -69,7 +69,7 @@ impl<const CHECK: bool> CallFrame<CHECK> {
}

#[inline]
pub(crate) fn set_local(&mut self, local_index: usize, value: UntypedWasmValue) {
pub(crate) fn set_local(&mut self, local_index: usize, value: RawWasmValue) {
if local_index >= self.local_count {
panic!("Invalid local index");
}
Expand All @@ -78,7 +78,7 @@ impl<const CHECK: bool> CallFrame<CHECK> {
}

#[inline]
pub(crate) fn get_local(&self, local_index: usize) -> UntypedWasmValue {
pub(crate) fn get_local(&self, local_index: usize) -> RawWasmValue {
if local_index >= self.local_count {
panic!("Invalid local index");
}
Expand Down
19 changes: 8 additions & 11 deletions crates/tinywasm/src/runtime/stack/value_stack.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::{runtime::UntypedWasmValue, Error, Result};
use crate::{runtime::RawWasmValue, Error, Result};
use alloc::vec::Vec;

// minimum stack size
pub const STACK_SIZE: usize = 1024;

#[derive(Debug)]
pub struct ValueStack {
stack: Vec<UntypedWasmValue>,
stack: Vec<RawWasmValue>,
top: usize,
}

Expand All @@ -21,28 +21,25 @@ impl Default for ValueStack {

impl ValueStack {
#[inline]
pub(crate) fn _extend(
&mut self,
values: impl IntoIterator<Item = UntypedWasmValue> + ExactSizeIterator,
) {
pub(crate) fn _extend(&mut self, values: impl IntoIterator<Item = RawWasmValue> + ExactSizeIterator) {
self.top += values.len();
self.stack.extend(values);
}

#[inline]
pub(crate) fn push(&mut self, value: UntypedWasmValue) {
pub(crate) fn push(&mut self, value: RawWasmValue) {
self.top += 1;
self.stack.push(value);
}

#[inline]
pub(crate) fn pop(&mut self) -> Option<UntypedWasmValue> {
pub(crate) fn pop(&mut self) -> Option<RawWasmValue> {
self.top -= 1;
self.stack.pop()
}

#[inline]
pub(crate) fn pop_n(&mut self, n: usize) -> Result<Vec<UntypedWasmValue>> {
pub(crate) fn pop_n(&mut self, n: usize) -> Result<Vec<RawWasmValue>> {
if self.top < n {
return Err(Error::StackUnderflow);
}
Expand All @@ -52,12 +49,12 @@ impl ValueStack {
}

#[inline]
pub(crate) fn pop_n_const<const N: usize>(&mut self) -> Result<[UntypedWasmValue; N]> {
pub(crate) fn pop_n_const<const N: usize>(&mut self) -> Result<[RawWasmValue; N]> {
if self.top < N {
return Err(Error::StackUnderflow);
}
self.top -= N;
let mut res = [UntypedWasmValue::default(); N];
let mut res = [RawWasmValue::default(); N];
for i in res.iter_mut().rev() {
*i = self.stack.pop().ok_or(Error::InvalidStore)?;
}
Expand Down
Loading

0 comments on commit ef4dbf2

Please sign in to comment.