@@ -352,6 +352,7 @@ void TranslateToFuzzReader::build() {
352352 setupHeapTypes ();
353353 setupTables ();
354354 setupGlobals ();
355+ useImportedGlobals ();
355356 if (wasm.features .hasExceptionHandling ()) {
356357 setupTags ();
357358 addImportThrowingSupport ();
@@ -366,7 +367,7 @@ void TranslateToFuzzReader::build() {
366367 // First, modify initial functions. That includes removing imports. Then,
367368 // use the imported module, which are function imports that we allow.
368369 modifyInitialFunctions ();
369- useImportedModule ();
370+ useImportedFunctions ();
370371
371372 processFunctions ();
372373 if (fuzzParams->HANG_LIMIT > 0 ) {
@@ -625,6 +626,20 @@ void TranslateToFuzzReader::setupTables() {
625626 }
626627}
627628
629+ void TranslateToFuzzReader::useGlobalLater (Global* global) {
630+ auto type = global->type ;
631+ auto name = global->name ;
632+ globalsByType[type].push_back (name);
633+ if (global->mutable_ ) {
634+ mutableGlobalsByType[type].push_back (name);
635+ } else {
636+ immutableGlobalsByType[type].push_back (name);
637+ if (global->imported ()) {
638+ importedImmutableGlobalsByType[type].push_back (name);
639+ }
640+ }
641+ }
642+
628643void TranslateToFuzzReader::setupGlobals () {
629644 // If there were initial wasm contents, there may be imported globals. That
630645 // would be a problem in the fuzzer harness as we'd error if we do not
@@ -651,20 +666,6 @@ void TranslateToFuzzReader::setupGlobals() {
651666 }
652667 }
653668
654- auto useGlobalLater = [&](Global* global) {
655- auto type = global->type ;
656- auto name = global->name ;
657- globalsByType[type].push_back (name);
658- if (global->mutable_ ) {
659- mutableGlobalsByType[type].push_back (name);
660- } else {
661- immutableGlobalsByType[type].push_back (name);
662- if (global->imported ()) {
663- importedImmutableGlobalsByType[type].push_back (name);
664- }
665- }
666- };
667-
668669 // Randomly assign some globals from initial content to be ignored for the
669670 // fuzzer to use. Such globals will only be used from initial content. This is
670671 // important to preserve some real-world patterns, like the "once" pattern in
@@ -712,9 +713,23 @@ void TranslateToFuzzReader::setupGlobals() {
712713 type = getMVPType ();
713714 init = makeConst (type);
714715 }
715- auto global = builder. makeGlobal (
716- Names::getValidGlobalName (wasm, " global$ " ) , type, init, mutability);
716+ auto name = Names::getValidGlobalName (wasm, " global$ " );
717+ auto global = builder. makeGlobal (name , type, init, mutability);
717718 useGlobalLater (wasm.addGlobal (std::move (global)));
719+
720+ // Export some globals, where we can.
721+ if (preserveImportsAndExports || type.isTuple () ||
722+ !isValidPublicType (type)) {
723+ continue ;
724+ }
725+ if (mutability == Builder::Mutable && !wasm.features .hasMutableGlobals ()) {
726+ continue ;
727+ }
728+ if (oneIn (2 )) {
729+ auto exportName = Names::getValidExportName (wasm, name);
730+ wasm.addExport (
731+ Builder::makeExport (exportName, name, ExternalKind::Global));
732+ }
718733 }
719734}
720735
@@ -1185,23 +1200,26 @@ void TranslateToFuzzReader::addHashMemorySupport() {
11851200 }
11861201}
11871202
1188- void TranslateToFuzzReader::useImportedModule () {
1203+ void TranslateToFuzzReader::setImportedModule (std::string importedModuleName) {
1204+ importedModule.emplace ();
1205+
1206+ importedModule->features = FeatureSet::All;
1207+ ModuleReader ().read (importedModuleName, *importedModule);
1208+ }
1209+
1210+ void TranslateToFuzzReader::useImportedFunctions () {
11891211 if (!importedModule) {
11901212 return ;
11911213 }
11921214
1193- Module imported;
1194- imported.features = FeatureSet::All;
1195- ModuleReader ().read (*importedModule, imported);
1196-
11971215 // Add some of the module's exported functions as imports, at a random rate.
11981216 auto rate = upTo (100 );
1199- for (auto & exp : imported. exports ) {
1217+ for (auto & exp : importedModule-> exports ) {
12001218 if (exp->kind != ExternalKind::Function || upTo (100 ) > rate) {
12011219 continue ;
12021220 }
12031221
1204- auto * func = imported. getFunction (*exp->getInternalName ());
1222+ auto * func = importedModule-> getFunction (*exp->getInternalName ());
12051223 auto name =
12061224 Names::getValidFunctionName (wasm, " primary_" + exp->name .toString ());
12071225 // We can import it as its own type, or any (declared) supertype.
@@ -1213,12 +1231,45 @@ void TranslateToFuzzReader::useImportedModule() {
12131231 wasm.addFunction (std::move (import ));
12141232 }
12151233
1216- // TODO: All other imports: globals, memories, tables, etc. We must, as we do
1234+ // TODO: All other imports: memories, tables, etc. We must, as we do
12171235 // with functions, take care to run this *after* the removal of those
12181236 // imports (as normally we remove them all, as the fuzzer harness will
12191237 // not provide them, but an imported module is the exception).
12201238}
12211239
1240+ void TranslateToFuzzReader::useImportedGlobals () {
1241+ if (!importedModule) {
1242+ return ;
1243+ }
1244+
1245+ // Add some of the module's exported globals as imports, at a random rate.
1246+ auto rate = upTo (100 );
1247+ for (auto & exp : importedModule->exports ) {
1248+ if (exp->kind != ExternalKind::Global || upTo (100 ) > rate) {
1249+ continue ;
1250+ }
1251+
1252+ auto * global = importedModule->getGlobal (*exp->getInternalName ());
1253+ auto name =
1254+ Names::getValidGlobalName (wasm, " primary_" + exp->name .toString ());
1255+ // We can import it as its own type, or if immutable, any (declared)
1256+ // supertype.
1257+ Type type;
1258+ Builder::Mutability mutability;
1259+ if (global->mutable_ ) {
1260+ mutability = Builder::Mutable;
1261+ type = global->type ;
1262+ } else {
1263+ mutability = Builder::Immutable;
1264+ type = getSuperType (global->type );
1265+ }
1266+ auto import = builder.makeGlobal (name, type, nullptr , mutability);
1267+ import ->module = " primary" ;
1268+ import ->base = exp->name ;
1269+ useGlobalLater (wasm.addGlobal (std::move (import )));
1270+ }
1271+ }
1272+
12221273TranslateToFuzzReader::FunctionCreationContext::FunctionCreationContext (
12231274 TranslateToFuzzReader& parent, Function* func)
12241275 : parent(parent), func(func) {
@@ -5846,6 +5897,9 @@ HeapType TranslateToFuzzReader::getSuperType(HeapType type) {
58465897}
58475898
58485899Type TranslateToFuzzReader::getSuperType (Type type) {
5900+ if (!type.isRef ()) {
5901+ return type;
5902+ }
58495903 auto heapType = getSuperType (type.getHeapType ());
58505904 auto nullability = getSuperType (type.getNullability ());
58515905 auto superType = Type (heapType, nullability);
0 commit comments