From a7b7cab1cbbdbf5ba93c6808e3e6c16e296a3535 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 25 Mar 2021 12:27:31 -0700 Subject: 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. --- src/wasm/wasm-binary.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'src/wasm/wasm-binary.cpp') 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 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); -- cgit v1.2.3