From 39fda77da51f83b200fc63bbfbc4dd2ccbfc2388 Mon Sep 17 00:00:00 2001 From: Thomas Lively <7121787+tlively@users.noreply.github.com> Date: Wed, 18 Mar 2020 10:09:14 -0700 Subject: [PATCH] Emit unreachable tuple.make properly (#2701) We previously thought unreachable `tuple.make` instructions did not require special unreachable handling, but consider the following wast: ``` (module (func $foo (tuple.make (unreachable) (i32.const 42) ) ) ) ``` This validates because the only expression in the body is unreachable, but when it is emitted as a binary it becomes ``` unreachable i32.const 42 ``` This does not validate because it ends with an i32, but the function expected an empty stack at the end. The fix is to emit an extra `unreachable` after unreachable `tuple.make` instructions. Unfortunately it is impossible to write a test for this right now because the binary parser silently drops the `i32.const 42`, making the function valid again. --- src/wasm-stack.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wasm-stack.h b/src/wasm-stack.h index 8662e783598..e00fde5eb58 100644 --- a/src/wasm-stack.h +++ b/src/wasm-stack.h @@ -809,8 +809,10 @@ void BinaryenIRWriter::visitTupleMake(TupleMake* curr) { for (auto* operand : curr->operands) { visit(operand); } - // No need to handle unreachable since we don't actually emit an instruction emit(curr); + if (curr->type == Type::unreachable) { + emitUnreachable(); + } } template