From 27da43c460ef363fd0615cd57833c7b1657dcaf6 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 1 Oct 2025 13:12:13 -0700 Subject: [PATCH 1/2] work --- src/tools/fuzzing/fuzzing.cpp | 36 ++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 6954d8cf029..79bb0e4a589 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -1485,16 +1485,32 @@ Function* TranslateToFuzzReader::addFunction() { auto allocation = std::make_unique(); auto* func = allocation.get(); func->name = Names::getValidFunctionName(wasm, "func"); - Index numParams = upToSquared(fuzzParams->MAX_PARAMS); - std::vector params; - params.reserve(numParams); - for (Index i = 0; i < numParams; i++) { - auto type = getSingleConcreteType(); - params.push_back(type); + + // Pick params and results. There may be an interesting heap type we can use. + std::optional funcType; + auto& funcTypes = interestingHeapSubTypes[HeapTypes::func]; + if (!funcTypes.empty()) { + auto type = pick(funcTypes); + if (type.getSignature().params.size() < (size_t)fuzzParams->MAX_PARAMS) { + // This is suitable for us. + funcType = type; + } } - auto paramType = Type(params); - auto resultType = getControlFlowType(); - func->type = Signature(paramType, resultType); + if (!funcType) { + // Generate a new type on the fly. + Index numParams = upToSquared(fuzzParams->MAX_PARAMS); + std::vector params; + params.reserve(numParams); + for (Index i = 0; i < numParams; i++) { + auto type = getSingleConcreteType(); + params.push_back(type); + } + auto paramType = Type(params); + auto resultType = getControlFlowType(); + funcType = Signature(paramType, resultType); + } + func->type = *funcType; + Index numVars = upToSquared(fuzzParams->MAX_VARS); for (Index i = 0; i < numVars; i++) { auto type = getConcreteType(); @@ -1524,6 +1540,8 @@ Function* TranslateToFuzzReader::addFunction() { // at least one, though, to keep each testcase interesting. Avoid non- // nullable params, as those cannot be constructed by the fuzzer on the // outside. + auto paramType = func->getParams(); + auto resultType = func->getResults(); bool validExportParams = std::all_of(paramType.begin(), paramType.end(), [&](Type t) { return t.isDefaultable() && isValidPublicType(t); From 4b9f93263226af9bc80988ed0f6373dd0da7246d Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 1 Oct 2025 13:15:41 -0700 Subject: [PATCH 2/2] more --- src/tools/fuzzing/fuzzing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 79bb0e4a589..0b90180d12e 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -1489,7 +1489,7 @@ Function* TranslateToFuzzReader::addFunction() { // Pick params and results. There may be an interesting heap type we can use. std::optional funcType; auto& funcTypes = interestingHeapSubTypes[HeapTypes::func]; - if (!funcTypes.empty()) { + if (!funcTypes.empty() && oneIn(2)) { auto type = pick(funcTypes); if (type.getSignature().params.size() < (size_t)fuzzParams->MAX_PARAMS) { // This is suitable for us.