@@ -176,9 +176,10 @@ void TranslateToFuzzReader::build() {
176176 setupGlobals ();
177177 if (wasm.features .hasExceptionHandling ()) {
178178 setupTags ();
179+ addImportThrowingSupport ();
179180 }
180- modifyInitialFunctions ();
181181 addImportLoggingSupport ();
182+ modifyInitialFunctions ();
182183 // keep adding functions until we run out of input
183184 while (!random.finished ()) {
184185 auto * func = addFunction ();
@@ -583,16 +584,31 @@ void TranslateToFuzzReader::addHangLimitSupport() {
583584
584585void TranslateToFuzzReader::addImportLoggingSupport () {
585586 for (auto type : loggableTypes) {
586- auto * func = new Function;
587- Name name = std::string (" log-" ) + type.toString ();
588- func->name = name;
587+ auto func = std::make_unique<Function>();
588+ Name baseName = std::string (" log-" ) + type.toString ();
589+ func->name = Names::getValidFunctionName (wasm, baseName);
590+ logImportNames[type] = func->name ;
589591 func->module = " fuzzing-support" ;
590- func->base = name ;
592+ func->base = baseName ;
591593 func->type = Signature (type, Type::none);
592- wasm.addFunction (func);
594+ wasm.addFunction (std::move ( func) );
593595 }
594596}
595597
598+ void TranslateToFuzzReader::addImportThrowingSupport () {
599+ // Throw some kind of exception from JS.
600+ // TODO: Send an index, which is which exported wasm Tag we should throw, or
601+ // something not exported if out of bounds. First we must also export
602+ // tags sometimes.
603+ throwImportName = Names::getValidFunctionName (wasm, " throw" );
604+ auto func = std::make_unique<Function>();
605+ func->name = throwImportName;
606+ func->module = " fuzzing-support" ;
607+ func->base = " throw" ;
608+ func->type = Signature (Type::none, Type::none);
609+ wasm.addFunction (std::move (func));
610+ }
611+
596612void TranslateToFuzzReader::addHashMemorySupport () {
597613 // Add memory hasher helper (for the hash, see hash.h). The function looks
598614 // like:
@@ -692,21 +708,30 @@ Expression* TranslateToFuzzReader::makeHangLimitCheck() {
692708 builder.makeConst (int32_t (1 )))));
693709}
694710
695- Expression* TranslateToFuzzReader::makeLogging () {
711+ Expression* TranslateToFuzzReader::makeImportLogging () {
696712 auto type = getLoggableType ();
697- return builder.makeCall (
698- std::string (" log-" ) + type.toString (), {make (type)}, Type::none);
713+ return builder.makeCall (logImportNames[type], {make (type)}, Type::none);
714+ }
715+
716+ Expression* TranslateToFuzzReader::makeImportThrowing (Type type) {
717+ // We throw from the import, so this call appears to be none and not
718+ // unreachable.
719+ assert (type == Type::none);
720+
721+ // TODO: This and makeThrow should probably be rare, as they halt the program.
722+ return builder.makeCall (throwImportName, {}, Type::none);
699723}
700724
701725Expression* TranslateToFuzzReader::makeMemoryHashLogging () {
702726 auto * hash = builder.makeCall (std::string (" hashMemory" ), {}, Type::i32 );
703- return builder.makeCall (std::string ( " log- i32" ) , {hash}, Type::none);
727+ return builder.makeCall (logImportNames[Type:: i32 ] , {hash}, Type::none);
704728}
705729
706730// TODO: return std::unique_ptr<Function>
707731Function* TranslateToFuzzReader::addFunction () {
708732 LOGGING_PERCENT = upToSquared (100 );
709- auto * func = new Function;
733+ auto allocation = std::make_unique<Function>();
734+ auto * func = allocation.get ();
710735 func->name = Names::getValidFunctionName (wasm, " func" );
711736 FunctionCreationContext context (*this , func);
712737 assert (funcContext->typeLocals .empty ());
@@ -765,7 +790,7 @@ Function* TranslateToFuzzReader::addFunction() {
765790 }
766791
767792 // Add hang limit checks after all other operations on the function body.
768- wasm.addFunction (func );
793+ wasm.addFunction (std::move (allocation) );
769794 // Export some functions, but not all (to allow inlining etc.). Try to export
770795 // at least one, though, to keep each testcase interesting. Only functions
771796 // with valid params and returns can be exported because the trap fuzzer
@@ -1215,10 +1240,13 @@ void TranslateToFuzzReader::modifyInitialFunctions() {
12151240 // the end (currently that is not needed atm, but it might in the future).
12161241 for (Index i = 0 ; i < wasm.functions .size (); i++) {
12171242 auto * func = wasm.functions [i].get ();
1243+ // We can't allow extra imports, as the fuzzing infrastructure wouldn't
1244+ // know what to provide. Keep only our own fuzzer imports.
1245+ if (func->imported () && func->module == " fuzzing-support" ) {
1246+ continue ;
1247+ }
12181248 FunctionCreationContext context (*this , func);
12191249 if (func->imported ()) {
1220- // We can't allow extra imports, as the fuzzing infrastructure wouldn't
1221- // know what to provide.
12221250 func->module = func->base = Name ();
12231251 func->body = make (func->getResults ());
12241252 }
@@ -1261,10 +1289,9 @@ void TranslateToFuzzReader::dropToLog(Function* func) {
12611289
12621290 void visitDrop (Drop* curr) {
12631291 if (parent.isLoggableType (curr->value ->type ) && parent.oneIn (2 )) {
1264- replaceCurrent (parent.builder .makeCall (std::string (" log-" ) +
1265- curr->value ->type .toString (),
1266- {curr->value },
1267- Type::none));
1292+ auto target = parent.logImportNames [curr->value ->type ];
1293+ replaceCurrent (
1294+ parent.builder .makeCall (target, {curr->value }, Type::none));
12681295 }
12691296 }
12701297 };
@@ -1430,7 +1457,7 @@ Expression* TranslateToFuzzReader::_makenone() {
14301457 auto choice = upTo (100 );
14311458 if (choice < LOGGING_PERCENT) {
14321459 if (choice < LOGGING_PERCENT / 2 ) {
1433- return makeLogging ();
1460+ return makeImportLogging ();
14341461 } else {
14351462 return makeMemoryHashLogging ();
14361463 }
@@ -1455,6 +1482,7 @@ Expression* TranslateToFuzzReader::_makenone() {
14551482 .add (FeatureSet::Atomics, &Self::makeAtomic)
14561483 .add (FeatureSet::ExceptionHandling, &Self::makeTry)
14571484 .add (FeatureSet::ExceptionHandling, &Self::makeTryTable)
1485+ .add (FeatureSet::ExceptionHandling, &Self::makeImportThrowing)
14581486 .add (FeatureSet::ReferenceTypes | FeatureSet::GC, &Self::makeCallRef)
14591487 .add (FeatureSet::ReferenceTypes | FeatureSet::GC, &Self::makeStructSet)
14601488 .add (FeatureSet::ReferenceTypes | FeatureSet::GC, &Self::makeArraySet)
0 commit comments