From 6299471584ce74d365526e33ed0a662bd2ee3490 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 28 Jan 2021 22:09:31 +0000 Subject: [GC] Add br_on_func/data/i31 (#3525) This expands the existing BrOnCast into BrOn that can also handle the func/data/i31 variants. This is not as elegant as RefIs / RefAs in that BrOnCast has an extra rtt field, but I think it is still the best option. We already have optional fields on Break (the value and condition), so making rtt optional is not odd. And it allows us to share all the behavior of br_on_* which aside from the cast or the check itself, is identical - returning the value if the branch is not taken, etc. --- src/wasm/wasm-binary.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'src/wasm/wasm-binary.cpp') diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 4a82c84a9..64a40f2ca 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3019,7 +3019,7 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { if (maybeVisitRefCast(curr, opcode)) { break; } - if (maybeVisitBrOnCast(curr, opcode)) { + if (maybeVisitBrOn(curr, opcode)) { break; } if (maybeVisitRttCanon(curr, opcode)) { @@ -5825,17 +5825,31 @@ bool WasmBinaryBuilder::maybeVisitRefCast(Expression*& out, uint32_t code) { return true; } -bool WasmBinaryBuilder::maybeVisitBrOnCast(Expression*& out, uint32_t code) { - if (code != BinaryConsts::BrOnCast) { - return false; +bool WasmBinaryBuilder::maybeVisitBrOn(Expression*& out, uint32_t code) { + BrOnOp op; + switch (code) { + case BinaryConsts::BrOnCast: + op = BrOnCast; + break; + case BinaryConsts::BrOnFunc: + op = BrOnFunc; + break; + case BinaryConsts::BrOnData: + op = BrOnData; + break; + case BinaryConsts::BrOnI31: + op = BrOnI31; + break; + default: + return false; } auto name = getBreakTarget(getU32LEB()).name; - auto* rtt = popNonVoidExpression(); - if (!rtt->type.isRtt()) { - throwError("bad rtt for br_on_cast"); + Expression* rtt = nullptr; + if (op == BrOnCast) { + rtt = popNonVoidExpression(); } auto* ref = popNonVoidExpression(); - out = Builder(wasm).makeBrOnCast(name, ref, rtt); + out = Builder(wasm).makeBrOn(op, name, ref, rtt); return true; } -- cgit v1.2.3