@@ -1485,16 +1485,32 @@ Function* TranslateToFuzzReader::addFunction() {
14851485 auto allocation = std::make_unique<Function>();
14861486 auto * func = allocation.get ();
14871487 func->name = Names::getValidFunctionName (wasm, " func" );
1488- Index numParams = upToSquared (fuzzParams->MAX_PARAMS );
1489- std::vector<Type> params;
1490- params.reserve (numParams);
1491- for (Index i = 0 ; i < numParams; i++) {
1492- auto type = getSingleConcreteType ();
1493- params.push_back (type);
1488+
1489+ // Pick params and results. There may be an interesting heap type we can use.
1490+ std::optional<HeapType> funcType;
1491+ auto & funcTypes = interestingHeapSubTypes[HeapTypes::func];
1492+ if (!funcTypes.empty ()) {
1493+ auto type = pick (funcTypes);
1494+ if (type.getSignature ().params .size () < (size_t )fuzzParams->MAX_PARAMS ) {
1495+ // This is suitable for us.
1496+ funcType = type;
1497+ }
14941498 }
1495- auto paramType = Type (params);
1496- auto resultType = getControlFlowType ();
1497- func->type = Signature (paramType, resultType);
1499+ if (!funcType) {
1500+ // Generate a new type on the fly.
1501+ Index numParams = upToSquared (fuzzParams->MAX_PARAMS );
1502+ std::vector<Type> params;
1503+ params.reserve (numParams);
1504+ for (Index i = 0 ; i < numParams; i++) {
1505+ auto type = getSingleConcreteType ();
1506+ params.push_back (type);
1507+ }
1508+ auto paramType = Type (params);
1509+ auto resultType = getControlFlowType ();
1510+ funcType = Signature (paramType, resultType);
1511+ }
1512+ func->type = *funcType;
1513+
14981514 Index numVars = upToSquared (fuzzParams->MAX_VARS );
14991515 for (Index i = 0 ; i < numVars; i++) {
15001516 auto type = getConcreteType ();
@@ -1524,6 +1540,8 @@ Function* TranslateToFuzzReader::addFunction() {
15241540 // at least one, though, to keep each testcase interesting. Avoid non-
15251541 // nullable params, as those cannot be constructed by the fuzzer on the
15261542 // outside.
1543+ auto paramType = func->getParams ();
1544+ auto resultType = func->getResults ();
15271545 bool validExportParams =
15281546 std::all_of (paramType.begin (), paramType.end (), [&](Type t) {
15291547 return t.isDefaultable () && isValidPublicType (t);
0 commit comments