From ffdae24a98ecc3f559c3bb02dcdfd79764f971db Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 7 Sep 2021 12:34:22 -0700 Subject: Show a clear error on asyncify+references. (#4125) Helps #3739 --- src/passes/Asyncify.cpp | 15 ++++++++++++--- src/wasm-type.h | 6 ++++++ src/wasm/wasm-type.cpp | 13 +++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp index dc2ebd4d4..5b96d6e86 100644 --- a/src/passes/Asyncify.cpp +++ b/src/passes/Asyncify.cpp @@ -1302,7 +1302,7 @@ private: if (!relevantLiveLocals.count(i)) { continue; } - total += func->getLocalType(i).getByteSize(); + total += getByteSize(func->getLocalType(i)); } auto* block = builder->makeBlock(); block->list.push_back(builder->makeIncStackPos(-total)); @@ -1317,7 +1317,7 @@ private: auto localType = func->getLocalType(i); SmallVector loads; for (const auto& type : localType) { - auto size = type.getByteSize(); + auto size = getByteSize(type); assert(size % STACK_ALIGN == 0); // TODO: higher alignment? loads.push_back( @@ -1361,7 +1361,7 @@ private: auto localType = func->getLocalType(i); size_t j = 0; for (const auto& type : localType) { - auto size = type.getByteSize(); + auto size = getByteSize(type); Expression* localGet = builder->makeLocalGet(i, localType); if (localType.size() > 1) { localGet = builder->makeTupleExtract(localGet, j); @@ -1395,6 +1395,15 @@ private: Type::i32), builder->makeIncStackPos(4)); } + + unsigned getByteSize(Type type) { + if (!type.hasByteSize()) { + Fatal() << "Asyncify does not yet support non-number types, like " + "references (see " + "https://github.com/WebAssembly/binaryen/issues/3739)"; + } + return type.getByteSize(); + } }; } // anonymous namespace diff --git a/src/wasm-type.h b/src/wasm-type.h index 43a93b4aa..48dbaf61b 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -195,6 +195,12 @@ public: // Returns the type size in bytes. Only single types are supported. unsigned getByteSize() const; + // Returns whether the type has a size in bytes. This is the same as whether + // it can be stored in linear memory. Things like references do not have this + // property, while numbers do. Tuples may or may not depending on their + // contents. + unsigned hasByteSize() const; + // Reinterpret an integer type to a float type with the same size and vice // versa. Only single integer and float types are supported. Type reinterpret() const; diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 34d7e942f..e86843f10 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -922,6 +922,19 @@ unsigned Type::getByteSize() const { return getSingleByteSize(*this); } +unsigned Type::hasByteSize() const { + auto hasSingleByteSize = [](Type t) { return t.isNumber(); }; + if (isTuple()) { + for (const auto& t : *this) { + if (!hasSingleByteSize(t)) { + return false; + } + } + return true; + } + return hasSingleByteSize(*this); +} + Type Type::reinterpret() const { assert(!isTuple() && "Unexpected tuple type"); switch ((*begin()).getBasic()) { -- cgit v1.2.3