Skip to content

Commit

Permalink
truncate redundant values when exiting a block
Browse files Browse the repository at this point in the history
  • Loading branch information
butterunderflow committed Oct 14, 2024
1 parent eda37f1 commit ff51ba1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 4 deletions.
20 changes: 20 additions & 0 deletions benchmarks/wasm/block.wat
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,27 @@
end
i32.add
)
(func $test_poly_br (result i32)
i32.const -30
i32.const 0 ;; unused
i32.const 0 ;; unused
i32.const 0 ;; unused
block (param i32 i32 i32) (result i32 i32)
i32.const 0 ;; truncated
i32.const 10000 ;; truncated
i32.const 10
i32.const 20
br 0
i32.add
end
i32.add
i32.add ;; add value -30 and 30
;; i32.add
;; We can't use i32.add instruction here, because the overflowed value has been truncted
;; when block exited.
)
(export "real_main" (func $real_main))
(export "test_loop_input" (func $test_loop_input))
(export "test_if_input" (func $test_if_input))
(export "test_poly_br" (func $test_poly_br))
)
9 changes: 5 additions & 4 deletions src/main/scala/wasm/MiniWasm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -265,18 +265,19 @@ object Evaluator {
case Block(ty, inner) =>
val (inputs, restStack) = stack.splitAt(ty.inps.size)
val restK: Cont[Ans] = (retStack) =>
eval(rest, retStack ++ restStack, frame, kont, trail, ret)
eval(rest, retStack.take(ty.out.size) ++ restStack, frame, kont, trail, ret)
eval(inner, inputs, frame, restK, restK :: trail, ret + 1)
case Loop(ty, inner) =>
// We construct two continuations, one for the break (to the begining of the loop),
// and one for fall-through to the next instruction following the syntactic structure
// of the program.
val (inputs, restStack) = stack.splitAt(ty.inps.size)
val restK: Cont[Ans] = (retStack) => eval(rest, retStack ++ restStack, frame, kont, trail, ret)
val restK: Cont[Ans] = (retStack) =>
eval(rest, retStack.take(ty.out.size) ++ restStack, frame, kont, trail, ret)

def loop(retStack: List[Value]): Ans = {
val k: Cont[Ans] = (retStack) => loop(retStack) // k is just same as loop
eval(inner, retStack, frame, restK, k :: trail, ret + 1)
eval(inner, retStack.take(ty.inps.size), frame, restK, k :: trail, ret + 1)
}

loop(inputs)
Expand All @@ -285,7 +286,7 @@ object Evaluator {
val inner = if (cond != 0) thn else els
val (inputs, restStack) = newStack.splitAt(ty.inps.size)
val restK: Cont[Ans] = (retStack) =>
eval(rest, retStack ++ restStack, frame, kont, trail, ret)
eval(rest, retStack.take(ty.out.size) ++ restStack, frame, kont, trail, ret)
eval(inner, inputs, frame, restK, restK :: trail, ret + 1)
case Br(label) =>
trail(label)(stack)
Expand Down
3 changes: 3 additions & 0 deletions src/test/scala/genwasym/TestEval.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class TestEval extends FunSuite {
test("input_block.if") {
testFile("./benchmarks/wasm/block.wat", Some("$test_if_input"), Some(25))
}
test("input_block.poly_br") {
testFile("./benchmarks/wasm/block.wat", Some("$test_poly_br"), Some(0))
}

// FIXME:
//test("tribonacci-ret") { testFile("./benchmarks/wasm/tribonacci_ret.wat", None, Some(504)) }
Expand Down

0 comments on commit ff51ba1

Please sign in to comment.