From 8ab74ee88f47aedc98dc9e390d0225c8a2db2e59 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 12 Feb 2025 13:44:31 -0800 Subject: [PATCH] fix --- src/tools/fuzzing.h | 3 +++ src/tools/fuzzing/fuzzing.cpp | 24 +++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 82a9f86b0a4..a3985cab09b 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -200,6 +200,9 @@ class TranslateToFuzzReader { Index numAddedFunctions = 0; + // The name of an empty tag. + Name trivialTag; + // RAII helper for managing the state used to create a single function. struct FunctionCreationContext { TranslateToFuzzReader& parent; diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index c853e37f790..e7820fc6f61 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -4825,10 +4825,28 @@ Expression* TranslateToFuzzReader::makeI31Get(Type type) { Expression* TranslateToFuzzReader::makeThrow(Type type) { assert(type == Type::unreachable); - if (wasm.tags.empty()) { - addTag(); + Tag* tag; + if (trivialNesting) { + // We are nested under a makeTrivial call, so only emit something trivial. + // Get (or create) a trivial tag, so we have no operands (and will not call + // make(), below). Otherwise, we might recurse very deeply if we threw a + // tag that contains an exnref (for which we may end up creating yet another + // throw in a try). + if (!trivialTag) { + auto newTag = builder.makeTag(Names::getValidTagName(wasm, "tag$"), + Signature(Type::none, Type::none)); + tag = wasm.addTag(std::move(newTag)); + trivialTag = tag->name; + } else { + tag = wasm.getTag(trivialTag); + } + } else { + // Get a random tag, adding a random one if necessary. + if (wasm.tags.empty()) { + addTag(); + } + tag = pick(wasm.tags).get(); } - auto* tag = pick(wasm.tags).get(); auto tagType = tag->params(); std::vector operands; for (auto t : tagType) {