summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2024-07-11 16:36:13 -0700
committerGitHub <noreply@github.com>2024-07-11 16:36:13 -0700
commit22c28bd5a108f9bdacd1b60468e312903bcdf451 (patch)
treea44677277b4b6e215836697946a7e394472cbe0f /src
parent363edc7fc9117824615502e02bf2fb2a05eb9c15 (diff)
downloadbinaryen-22c28bd5a108f9bdacd1b60468e312903bcdf451.tar.gz
binaryen-22c28bd5a108f9bdacd1b60468e312903bcdf451.tar.bz2
binaryen-22c28bd5a108f9bdacd1b60468e312903bcdf451.zip
Memory64Lowering: Handle -1 return value from memory.grow (#6733)
This edge case make the lowering a little more tricky.
Diffstat (limited to 'src')
-rw-r--r--src/passes/Memory64Lowering.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/passes/Memory64Lowering.cpp b/src/passes/Memory64Lowering.cpp
index c1ce3dd91..879858b71 100644
--- a/src/passes/Memory64Lowering.cpp
+++ b/src/passes/Memory64Lowering.cpp
@@ -79,9 +79,32 @@ struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {
if (memory->is64()) {
wrapAddress64(curr->delta, curr->memory);
auto* size = static_cast<Expression*>(curr);
- extendAddress64(size, curr->memory);
+ // MemoryGrow returns -1 in case of failure. We cannot just use
+ // extend_32_u in this case so we handle it as follows:
+ //
+ // (if (result i64)
+ // (i32.eq (i32.const -1) (local.tee $tmp (memory.grow X)))
+ // (then
+ // (i64.const -1)
+ // )
+ // (else
+ // (i32.extend_32_u (local.get $tmp))
+ // )
+ // )
+ Builder builder(module);
+ auto tmp = builder.addVar(getFunction(), Type::i32);
+ Expression* isMinusOne =
+ builder.makeBinary(EqInt32,
+ builder.makeConst(int32_t(-1)),
+ builder.makeLocalTee(tmp, size, Type::i32));
+ auto* newSize = builder.makeLocalGet(tmp, Type::i32);
+ builder.makeUnary(UnaryOp::ExtendUInt32, newSize);
+ Expression* ifExp =
+ builder.makeIf(isMinusOne,
+ builder.makeConst(int64_t(-1)),
+ builder.makeUnary(UnaryOp::ExtendUInt32, newSize));
curr->type = Type::i32;
- replaceCurrent(size);
+ replaceCurrent(ifExp);
}
}