summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/cli/src/load.rs2
-rw-r--r--crates/parser/src/visit.rs3
-rw-r--r--crates/tinywasm/tests/wasm-custom/compression-control-flow.wast43
3 files changed, 46 insertions, 2 deletions
diff --git a/crates/cli/src/load.rs b/crates/cli/src/load.rs
index 7e6fc09..9f7c616 100644
--- a/crates/cli/src/load.rs
+++ b/crates/cli/src/load.rs
@@ -73,7 +73,7 @@ fn load_module_from_bytes(input: &str, bytes: &[u8]) -> Result<LoadedModule> {
#[cfg(not(feature = "wat"))]
if input != "-" && has_extension(input, "wat") {
- bail!("wat support is not enabled in this build")
+ bail!("wat support is not enabled in this build");
}
#[cfg(feature = "wat")]
diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs
index cb13387..dae9ff2 100644
--- a/crates/parser/src/visit.rs
+++ b/crates/parser/src/visit.rs
@@ -1017,7 +1017,8 @@ impl FunctionBuilder<'_> {
/// Emits the stack-shaping instruction required by a branch.
fn emit_dropkeep(&mut self, base: ValueCounts, keep: ValueCounts) {
- if base.is_empty() && keep.is_empty() {
+ let target = ValueCounts { c32: base.c32 + keep.c32, c64: base.c64 + keep.c64, c128: base.c128 + keep.c128 };
+ if self.lane_counts == target {
return;
}
self.instructions.push(Instruction::DropKeep((base, keep).into()));
diff --git a/crates/tinywasm/tests/wasm-custom/compression-control-flow.wast b/crates/tinywasm/tests/wasm-custom/compression-control-flow.wast
new file mode 100644
index 0000000..5cd56dc
--- /dev/null
+++ b/crates/tinywasm/tests/wasm-custom/compression-control-flow.wast
@@ -0,0 +1,43 @@
+(module
+ ;; Reduced from miniz_oxide's Huffman-table builder, which reached a bounds
+ ;; panic during compression. Branches to empty targets skipped DropKeep, so
+ ;; a stale operand remained on the stack and corrupted a later loop.
+ (func (export "branch-drops-retained") (result i32)
+ (local $iteration i32)
+ (local $count i32)
+ (local $result i32)
+ block $done
+ loop $outer
+ block $scan-done
+ i32.const 7
+ i32.const 20
+ local.get $iteration
+ select
+ local.get $iteration
+ i32.eqz
+ if
+ br $scan-done
+ end
+ i32.const 2
+ local.set $count
+ loop $inner
+ local.get $count
+ i32.const 1
+ i32.sub
+ local.tee $count
+ br_if $inner
+ end
+ local.set $result
+ br $done
+ end
+ local.get $iteration
+ i32.const 1
+ i32.add
+ local.set $iteration
+ br $outer
+ end
+ end
+ local.get $result)
+)
+
+(assert_return (invoke "branch-drops-retained") (i32.const 7))