summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-03-25 12:27:31 -0700
committerGitHub <noreply@github.com>2021-03-25 12:27:31 -0700
commita7b7cab1cbbdbf5ba93c6808e3e6c16e296a3535 (patch)
tree70ef57727a0620c357c4539177523250342a03ba /src/wasm/wasm-binary.cpp
parent00990c372522398a12d09d7dbed48c1a10d57657 (diff)
downloadbinaryen-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.cpp26
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);