Skip to content

Commit

Permalink
fix: breaking in loops
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
  • Loading branch information
explodingcamera committed Jan 22, 2024
1 parent f59963d commit 85deebc
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 44 deletions.
44 changes: 23 additions & 21 deletions crates/tinywasm/src/runtime/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,25 +198,8 @@ fn exec_one(
}

If(args, else_offset, end_offset) => {
if stack.values.pop_t::<i32>()? == 0 {
if let Some(else_offset) = else_offset {
log::debug!("entering else at {}", cf.instr_ptr + *else_offset);
cf.enter_label(
LabelFrame {
instr_ptr: cf.instr_ptr + *else_offset,
end_instr_ptr: cf.instr_ptr + *end_offset,
stack_ptr: stack.values.len(), // - params,
args: crate::LabelArgs::new(*args, module)?,
ty: BlockType::Else,
},
&mut stack.values,
);
cf.instr_ptr += *else_offset;
} else {
log::info!("skipping if");
cf.instr_ptr += *end_offset
}
} else {
// truthy value is on the top of the stack, so enter the then block
if stack.values.pop_t::<i32>()? != 0 {
log::trace!("entering then");
cf.enter_label(
LabelFrame {
Expand All @@ -227,7 +210,26 @@ fn exec_one(
ty: BlockType::If,
},
&mut stack.values,
)
);
return Ok(ExecResult::Ok);
}

// falsy value is on the top of the stack
if let Some(else_offset) = else_offset {
log::debug!("entering else at {}", cf.instr_ptr + *else_offset);
cf.enter_label(
LabelFrame {
instr_ptr: cf.instr_ptr + *else_offset,
end_instr_ptr: cf.instr_ptr + *end_offset,
stack_ptr: stack.values.len(), // - params,
args: crate::LabelArgs::new(*args, module)?,
ty: BlockType::Else,
},
&mut stack.values,
);
cf.instr_ptr += *else_offset;
} else {
cf.instr_ptr += *end_offset;
}
}

Expand Down Expand Up @@ -285,7 +287,7 @@ fn exec_one(

Br(v) => break_to!(cf, stack, v),
BrIf(v) => {
if stack.values.pop_t::<i32>()? > 0 {
if stack.values.pop_t::<i32>()? != 0 {
break_to!(cf, stack, v);
}
}
Expand Down
1 change: 0 additions & 1 deletion crates/tinywasm/src/runtime/executor/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ macro_rules! impl_wasm_float_ops {
impl WasmFloatOps for $t {
// https://webassembly.github.io/spec/core/exec/numerics.html#op-fnearest
fn wasm_nearest(self) -> Self {
log::info!("wasm_nearest: {}", self);
match self {
x if x.is_nan() => x,
x if x.is_infinite() || x == 0.0 => x,
Expand Down
11 changes: 9 additions & 2 deletions crates/tinywasm/src/runtime/stack/call_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,28 @@ impl CallFrame {
/// Returns `None` if there is no block at the given index (e.g. if we need to return, this is handled by the caller)
#[inline]
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)?;
value_stack.break_to(break_to.stack_ptr, break_to.args.results);

// instr_ptr points to the label instruction, but the next step
// will increment it by 1 since we're changing the "current" instr_ptr
match break_to.ty {
BlockType::Loop => {
// this is a loop, so we want to jump back to the start of the loop
// We also want to push the params to the stack
value_stack.break_to(break_to.stack_ptr, break_to.args.params);

self.instr_ptr = break_to.instr_ptr;

// we also want to trim the label stack to the loop (but not including the loop)
self.labels.truncate(self.labels.len() - break_to_relative as usize);
}
BlockType::Block | BlockType::If | BlockType::Else => {
// this is a block, so we want to jump to the next instruction after the block ends (the inst_ptr will be incremented by 1 before the next instruction is executed)
// this is a block, so we want to jump to the next instruction after the block ends
// We also want to push the block's results to the stack
value_stack.break_to(break_to.stack_ptr, break_to.args.results);

// (the inst_ptr will be incremented by 1 before the next instruction is executed)
self.instr_ptr = break_to.end_instr_ptr;

// we also want to trim the label stack, including the block
Expand Down
1 change: 1 addition & 0 deletions crates/tinywasm/src/runtime/stack/value_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl ValueStack {
}

pub(crate) fn break_to(&mut self, new_stack_size: usize, result_count: usize) {
assert!(self.top >= result_count);
self.stack.copy_within((self.top - result_count)..self.top, new_stack_size);
self.top = new_stack_size + result_count;
self.stack.truncate(self.top);
Expand Down
2 changes: 1 addition & 1 deletion crates/tinywasm/tests/generated/mvp.csv

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions crates/tinywasm/tests/generated/progress-mvp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 1 addition & 6 deletions crates/tinywasm/tests/test-mvp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,11 @@ fn test_mvp() -> Result<()> {

TestSuite::set_log_level(log::LevelFilter::Off);
test_suite.run_spec_group(wasm_testsuite::MVP_TESTS)?;

test_suite.save_csv("./tests/generated/mvp.csv", env!("CARGO_PKG_VERSION"))?;

if test_suite.failed() {
println!();
Err(eyre!(format!(
"{}:\n{:#?}",
"failed one or more tests".red().bold(),
test_suite,
)))
Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,)))
} else {
println!("\n\npassed all tests:\n{:#?}", test_suite);
Ok(())
Expand Down
14 changes: 3 additions & 11 deletions crates/tinywasm/tests/test-wast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ fn main() -> Result<()> {
let cwd = std::env::current_dir()?;

// if current dir is crates/tinywasm, then we want to go up 2 levels
let mut wast_file = if cwd.ends_with("crates/tinywasm") {
PathBuf::from("../../")
} else {
PathBuf::from("./")
};
let mut wast_file = if cwd.ends_with("crates/tinywasm") { PathBuf::from("../../") } else { PathBuf::from("./") };

wast_file.push(&args[2]);
let wast_file = cwd.join(wast_file);
Expand All @@ -34,7 +30,7 @@ fn main() -> Result<()> {
}

fn test_wast(wast_file: &str) -> Result<()> {
TestSuite::set_log_level(log::LevelFilter::Info);
TestSuite::set_log_level(log::LevelFilter::Debug);

let args = std::env::args().collect::<Vec<_>>();
println!("args: {:?}", args);
Expand All @@ -48,11 +44,7 @@ fn test_wast(wast_file: &str) -> Result<()> {
println!();
test_suite.print_errors();
println!();
Err(eyre!(format!(
"{}:\n{:#?}",
"failed one or more tests".red().bold(),
test_suite,
)))
Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,)))
} else {
println!("\n\npassed all tests:\n{:#?}", test_suite);
Ok(())
Expand Down

0 comments on commit 85deebc

Please sign in to comment.