summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-10-17 12:49:43 -0700
committerGitHub <noreply@github.com>2024-10-17 12:49:43 -0700
commit6566329fecd36c8cd8e2ab29f89dafde0d2e9304 (patch)
tree87e722eb17ab96e3dfe2ac865b53e6bede8bb61d /src
parentfd86eadb591576b82b0b564f95952b131979e91a (diff)
downloadbinaryen-6566329fecd36c8cd8e2ab29f89dafde0d2e9304.tar.gz
binaryen-6566329fecd36c8cd8e2ab29f89dafde0d2e9304.tar.bz2
binaryen-6566329fecd36c8cd8e2ab29f89dafde0d2e9304.zip
[EH][GC] Send a non-nullable exnref from TryTable (#7013)
When EH+GC are enabled then wasm has non-nullable types, and the sent exnref should be non-nullable. In BinaryenIR we use the non- nullable type all the time, which we also do for function references and other things; we lower it if GC is not enabled to a nullable type for the binary format (see `WasmBinaryWriter::writeType`, to which comments were added in this PR). That is, this PR makes us handle exnref the same as those other types. A new test verifies that behavior. Various existing tests are updated because ReFinalize will now use the more refined type, so this is an optimization. It is also a bugfix as in #6987 we started to emit the refined form in the fuzzer, and this PR makes us handle it properly in validation and ReFinalization.
Diffstat (limited to 'src')
-rw-r--r--src/wasm/wasm-binary.cpp8
-rw-r--r--src/wasm/wasm-validator.cpp2
-rw-r--r--src/wasm/wasm.cpp6
3 files changed, 11 insertions, 5 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 920baf944..bc7ec8ac8 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1544,9 +1544,9 @@ void WasmBinaryWriter::writeInlineBuffer(const char* data, size_t size) {
void WasmBinaryWriter::writeType(Type type) {
if (type.isRef()) {
- // The only reference types allowed without GC are funcref and externref. We
- // internally use more refined versions of those types, but we cannot emit
- // those more refined types.
+ // The only reference types allowed without GC are funcref, externref, and
+ // exnref. We internally use more refined versions of those types, but we
+ // cannot emit those without GC.
if (!wasm->features.hasGC()) {
auto ht = type.getHeapType();
if (ht.isMaybeShared(HeapType::string)) {
@@ -1555,6 +1555,8 @@ void WasmBinaryWriter::writeType(Type type) {
// string, the stringref feature must be enabled.
type = Type(HeapTypes::string.getBasic(ht.getShared()), Nullable);
} else {
+ // Only the top type (func, extern, exn) is available, and only the
+ // nullable version.
type = Type(type.getHeapType().getTop(), Nullable);
}
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index a86187fa7..0184e3284 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -2658,7 +2658,7 @@ void FunctionValidator::visitTryTable(TryTable* curr) {
"the number of catch tags and sent types do not match");
const char* invalidSentTypeMsg = "invalid catch sent type information";
- Type exnref = Type(HeapType::exn, Nullable);
+ Type exnref = Type(HeapType::exn, NonNullable);
for (Index i = 0; i < curr->catchTags.size(); i++) {
auto sentType = curr->sentTypes[i];
size_t tagTypeSize;
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 0245fc01e..4150af5b4 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -933,7 +933,11 @@ static void populateTryTableSentTypes(TryTable* curr, Module* wasm) {
return;
}
curr->sentTypes.clear();
- Type exnref = Type(HeapType::exn, Nullable);
+ // We always use the refined non-nullable type in our IR, which is what the
+ // wasm spec defines when GC is enabled (=== non-nullable types are allowed).
+ // If GC is not enabled then we emit a nullable type in the binary format in
+ // WasmBinaryWriter::writeType.
+ Type exnref = Type(HeapType::exn, NonNullable);
for (Index i = 0; i < curr->catchTags.size(); i++) {
auto tagName = curr->catchTags[i];
std::vector<Type> sentType;