diff options
author | Alon Zakai <azakai@google.com> | 2021-03-25 12:27:31 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-25 12:27:31 -0700 |
commit | a7b7cab1cbbdbf5ba93c6808e3e6c16e296a3535 (patch) | |
tree | 70ef57727a0620c357c4539177523250342a03ba /src/wasm/wasm-binary.cpp | |
parent | 00990c372522398a12d09d7dbed48c1a10d57657 (diff) | |
download | binaryen-a7b7cab1cbbdbf5ba93c6808e3e6c16e296a3535.tar.gz binaryen-a7b7cab1cbbdbf5ba93c6808e3e6c16e296a3535.tar.bz2 binaryen-a7b7cab1cbbdbf5ba93c6808e3e6c16e296a3535.zip |
Fix binary reading of tuples containing non-nullable types (#3734)
We must write them to a tuple with nullable types, then fix that up when
reading. This is similar to what we do in handleNonNullableLocals, except
that it operates on the entire tuple type, so it can't share that code.
This fixes a regression from #3710 that was harder to notice by the fuzzer
until now.
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 5bd368e17..5425c1551 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2516,14 +2516,30 @@ void WasmBinaryBuilder::skipUnreachableCode() { } void WasmBinaryBuilder::pushExpression(Expression* curr) { - if (curr->type.isTuple()) { + auto type = curr->type; + if (type.isTuple()) { // Store tuple to local and push individual extracted values Builder builder(wasm); - Index tuple = builder.addVar(currFunction, curr->type); + // Non-nullable types require special handling as they cannot be stored to + // a local. + std::vector<Type> nullableTypes; + for (auto t : type) { + if (t.isRef() && !t.isNullable()) { + t = Type(t.getHeapType(), Nullable); + } + nullableTypes.push_back(t); + } + auto nullableType = Type(Tuple(nullableTypes)); + Index tuple = builder.addVar(currFunction, nullableType); expressionStack.push_back(builder.makeLocalSet(tuple, curr)); - for (Index i = 0; i < curr->type.size(); ++i) { - expressionStack.push_back( - builder.makeTupleExtract(builder.makeLocalGet(tuple, curr->type), i)); + for (Index i = 0; i < nullableType.size(); ++i) { + Expression* value = + builder.makeTupleExtract(builder.makeLocalGet(tuple, nullableType), i); + if (nullableType[i] != type[i]) { + // We modified this to be nullable; undo that. + value = builder.makeRefAs(RefAsNonNull, value); + } + expressionStack.push_back(value); } } else { expressionStack.push_back(curr); |