@@ -246,11 +246,8 @@ void TranslateToFuzzReader::setupHeapTypes() {
246246
247247 // For GC, also generate random types.
248248 if (wasm.features .hasGC ()) {
249- // Do not generate shared types until the fuzzer can be updated to handle
250- // them.
251- auto features = wasm.features - FeatureSet::SharedEverything;
252249 auto generator =
253- HeapTypeGenerator::create (random, features, upTo (MAX_NEW_GC_TYPES));
250+ HeapTypeGenerator::create (random, wasm. features , upTo (MAX_NEW_GC_TYPES));
254251 auto result = generator.builder .build ();
255252 if (auto * err = result.getError ()) {
256253 Fatal () << " Failed to build heap types: " << err->reason << " at index "
@@ -288,10 +285,16 @@ void TranslateToFuzzReader::setupHeapTypes() {
288285 }
289286 // Basic types must be handled directly, since subTypes doesn't look at
290287 // those.
288+ auto share = type.getShared ();
289+ auto struct_ = HeapTypes::struct_.getBasic (share);
290+ auto array = HeapTypes::array.getBasic (share);
291+ auto eq = HeapTypes::eq.getBasic (share);
292+ auto any = HeapTypes::any.getBasic (share);
293+ auto func = HeapTypes::func.getBasic (share);
291294 if (type.isStruct ()) {
292- interestingHeapSubTypes[HeapType:: struct_].push_back (type);
293- interestingHeapSubTypes[HeapType:: eq].push_back (type);
294- interestingHeapSubTypes[HeapType:: any].push_back (type);
295+ interestingHeapSubTypes[struct_].push_back (type);
296+ interestingHeapSubTypes[eq].push_back (type);
297+ interestingHeapSubTypes[any].push_back (type);
295298
296299 // Note the mutable fields.
297300 auto & fields = type.getStruct ().fields ;
@@ -301,15 +304,15 @@ void TranslateToFuzzReader::setupHeapTypes() {
301304 }
302305 }
303306 } else if (type.isArray ()) {
304- interestingHeapSubTypes[HeapType:: array].push_back (type);
305- interestingHeapSubTypes[HeapType:: eq].push_back (type);
306- interestingHeapSubTypes[HeapType:: any].push_back (type);
307+ interestingHeapSubTypes[array].push_back (type);
308+ interestingHeapSubTypes[eq].push_back (type);
309+ interestingHeapSubTypes[any].push_back (type);
307310
308311 if (type.getArray ().element .mutable_ ) {
309312 mutableArrays.push_back (type);
310313 }
311314 } else if (type.isSignature ()) {
312- interestingHeapSubTypes[HeapType:: func].push_back (type);
315+ interestingHeapSubTypes[func].push_back (type);
313316 }
314317 }
315318
@@ -2468,11 +2471,13 @@ Literal TranslateToFuzzReader::makeLiteral(Type type) {
24682471
24692472Expression* TranslateToFuzzReader::makeRefFuncConst (Type type) {
24702473 auto heapType = type.getHeapType ();
2474+ auto share = heapType.getShared ();
24712475 if (heapType.isBasic ()) {
24722476 assert (heapType.getBasic (Unshared) == HeapType::func);
24732477 // With high probability, use the last created function if possible.
24742478 // Otherwise, continue on to select some other function.
2475- if (funcContext && !oneIn (4 )) {
2479+ if (funcContext && funcContext->func ->type .getShared () == share &&
2480+ !oneIn (4 )) {
24762481 auto * target = funcContext->func ;
24772482 return builder.makeRefFunc (target->name , target->type );
24782483 }
@@ -2496,7 +2501,7 @@ Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) {
24962501 // here).
24972502 if ((type.isNullable () && oneIn (2 )) ||
24982503 (type.isNonNullable () && oneIn (16 ) && funcContext)) {
2499- Expression* ret = builder.makeRefNull (HeapType ::nofunc);
2504+ Expression* ret = builder.makeRefNull (HeapTypes ::nofunc. getBasic (share) );
25002505 if (!type.isNullable ()) {
25012506 assert (funcContext);
25022507 ret = builder.makeRefAs (RefAsNonNull, ret);
@@ -2511,7 +2516,10 @@ Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) {
25112516 if (heapType.isBasic ()) {
25122517 // We need a specific signature type to create a function. Pick an arbitrary
25132518 // signature if we only had generic 'func' here.
2514- heapType = Signature (Type::none, Type::none);
2519+ TypeBuilder builder (1 );
2520+ builder[0 ] = Signature (Type::none, Type::none);
2521+ builder[0 ].setShared (share);
2522+ heapType = (*builder.build ())[0 ];
25152523 }
25162524 auto * body = heapType.getSignature ().results == Type::none
25172525 ? (Expression*)builder.makeNop ()
@@ -2553,10 +2561,10 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
25532561 auto heapType = type.getHeapType ();
25542562 assert (heapType.isBasic ());
25552563 assert (wasm.features .hasReferenceTypes ());
2556- assert (!heapType. isShared () && " TODO: handle shared types " );
2564+ auto share = heapType. getShared ( );
25572565 switch (heapType.getBasic (Unshared)) {
25582566 case HeapType::ext: {
2559- auto null = builder.makeRefNull (HeapType ::ext);
2567+ auto null = builder.makeRefNull (HeapTypes ::ext. getBasic (share) );
25602568 // TODO: support actual non-nullable externrefs via imported globals or
25612569 // similar.
25622570 if (!type.isNullable ()) {
@@ -2575,12 +2583,16 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
25752583 // Choose a subtype we can materialize a constant for. We cannot
25762584 // materialize non-nullable refs to func or i31 in global contexts.
25772585 Nullability nullability = getSubType (type.getNullability ());
2578- auto subtype = pick (FeatureOptions<HeapType>()
2579- .add (FeatureSet::ReferenceTypes | FeatureSet::GC,
2580- HeapType::i31,
2581- HeapType::struct_,
2582- HeapType::array)
2583- .add (FeatureSet::Strings, HeapType::string));
2586+ auto subtypeOpts = FeatureOptions<HeapType>().add (
2587+ FeatureSet::ReferenceTypes | FeatureSet::GC,
2588+ HeapType::i31,
2589+ HeapType::struct_,
2590+ HeapType::array);
2591+ if (share == Unshared) {
2592+ // Shared strings not yet supported.
2593+ subtypeOpts.add (FeatureSet::Strings, HeapType::string);
2594+ }
2595+ auto subtype = pick (subtypeOpts).getBasic (share);
25842596 return makeConst (Type (subtype, nullability));
25852597 }
25862598 case HeapType::eq: {
@@ -2589,7 +2601,7 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
25892601 // a subtype of anyref, but we cannot create constants of it, except
25902602 // for null.
25912603 assert (type.isNullable ());
2592- return builder.makeRefNull (HeapType ::none);
2604+ return builder.makeRefNull (HeapTypes ::none. getBasic (share) );
25932605 }
25942606 auto nullability = getSubType (type.getNullability ());
25952607 // ref.i31 is not allowed in initializer expressions.
@@ -2605,14 +2617,14 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
26052617 subtype = HeapType::array;
26062618 break ;
26072619 }
2608- return makeConst (Type (subtype, nullability));
2620+ return makeConst (Type (subtype. getBasic (share) , nullability));
26092621 }
26102622 case HeapType::i31: {
26112623 assert (wasm.features .hasGC ());
26122624 if (type.isNullable () && oneIn (4 )) {
2613- return builder.makeRefNull (HeapType ::none);
2625+ return builder.makeRefNull (HeapTypes ::none. getBasic (share) );
26142626 }
2615- return builder.makeRefI31 (makeConst (Type::i32 ));
2627+ return builder.makeRefI31 (makeConst (Type::i32 ), share );
26162628 }
26172629 case HeapType::struct_: {
26182630 assert (wasm.features .hasGC ());
@@ -2621,15 +2633,29 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
26212633 // Use a local static to avoid the expense of canonicalizing a new type
26222634 // every time.
26232635 static HeapType trivialStruct = HeapType (Struct ());
2624- return builder.makeStructNew (trivialStruct, std::vector<Expression*>{});
2636+ static HeapType sharedTrivialStruct = []() {
2637+ TypeBuilder builder (1 );
2638+ builder[0 ] = Struct{};
2639+ builder[0 ].setShared ();
2640+ return (*builder.build ())[0 ];
2641+ }();
2642+ auto ht = share == Shared ? sharedTrivialStruct : trivialStruct;
2643+ return builder.makeStructNew (ht, std::vector<Expression*>{});
26252644 }
26262645 case HeapType::array: {
26272646 static HeapType trivialArray =
26282647 HeapType (Array (Field (Field::PackedType::i8 , Immutable)));
2629- return builder.makeArrayNewFixed (trivialArray, {});
2648+ static HeapType sharedTrivialArray = []() {
2649+ TypeBuilder builder (1 );
2650+ builder[0 ] = Array (Field (Field::PackedType::i8 , Immutable));
2651+ builder[0 ].setShared ();
2652+ return (*builder.build ())[0 ];
2653+ }();
2654+ auto ht = share == Shared ? sharedTrivialArray : trivialArray;
2655+ return builder.makeArrayNewFixed (ht, {});
26302656 }
26312657 case HeapType::exn: {
2632- auto null = builder.makeRefNull (HeapType ::exn);
2658+ auto null = builder.makeRefNull (HeapTypes ::exn. getBasic (share) );
26332659 if (!type.isNullable ()) {
26342660 assert (funcContext);
26352661 return builder.makeRefAs (RefAsNonNull, null);
@@ -2638,6 +2664,7 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
26382664 }
26392665 case HeapType::string: {
26402666 // In non-function contexts all we can do is string.const.
2667+ assert (share == Unshared && " shared strings not supported" );
26412668 if (!funcContext) {
26422669 return makeStringConst ();
26432670 }
@@ -2671,7 +2698,7 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
26712698 case HeapType::nofunc:
26722699 case HeapType::nocont:
26732700 case HeapType::noexn: {
2674- auto null = builder.makeRefNull (heapType);
2701+ auto null = builder.makeRefNull (heapType. getBasic (share) );
26752702 if (!type.isNullable ()) {
26762703 assert (funcContext);
26772704 return builder.makeRefAs (RefAsNonNull, null);
@@ -4231,48 +4258,56 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) {
42314258 return type;
42324259 }
42334260 if (type.isBasic () && oneIn (2 )) {
4234- assert (!type. isShared () && " TODO: handle shared types " );
4261+ auto share = type. getShared ( );
42354262 switch (type.getBasic (Unshared)) {
42364263 case HeapType::func:
42374264 // TODO: Typed function references.
42384265 return pick (FeatureOptions<HeapType>()
42394266 .add (FeatureSet::ReferenceTypes, HeapType::func)
4240- .add (FeatureSet::GC, HeapType::nofunc));
4267+ .add (FeatureSet::GC, HeapType::nofunc))
4268+ .getBasic (share);
42414269 case HeapType::cont:
4242- return pick (HeapType ::cont, HeapType ::nocont);
4270+ return pick (HeapTypes ::cont, HeapTypes ::nocont). getBasic (share );
42434271 case HeapType::ext:
42444272 return pick (FeatureOptions<HeapType>()
42454273 .add (FeatureSet::ReferenceTypes, HeapType::ext)
4246- .add (FeatureSet::GC, HeapType::noext));
4247- case HeapType::any:
4274+ .add (FeatureSet::GC, HeapType::noext))
4275+ .getBasic (share);
4276+ case HeapType::any: {
42484277 assert (wasm.features .hasReferenceTypes ());
42494278 assert (wasm.features .hasGC ());
4250- return pick (FeatureOptions<HeapType>()
4251- .add (FeatureSet::GC,
4252- HeapType::any,
4253- HeapType::eq,
4254- HeapType::i31,
4255- HeapType::struct_,
4256- HeapType::array,
4257- HeapType::none)
4258- .add (FeatureSet::Strings, HeapType::string));
4279+ auto options = FeatureOptions<HeapType>().add (FeatureSet::GC,
4280+ HeapType::any,
4281+ HeapType::eq,
4282+ HeapType::i31,
4283+ HeapType::struct_,
4284+ HeapType::array,
4285+ HeapType::none);
4286+ if (share == Unshared) {
4287+ // Shared strings not yet supported.
4288+ options.add (FeatureSet::Strings, HeapType::string);
4289+ }
4290+ return pick (options).getBasic (share);
4291+ }
42594292 case HeapType::eq:
42604293 assert (wasm.features .hasReferenceTypes ());
42614294 assert (wasm.features .hasGC ());
4262- return pick (HeapType::eq,
4263- HeapType::i31,
4264- HeapType::struct_,
4265- HeapType::array,
4266- HeapType::none);
4295+ return pick (HeapTypes::eq,
4296+ HeapTypes::i31,
4297+ HeapTypes::struct_,
4298+ HeapTypes::array,
4299+ HeapTypes::none)
4300+ .getBasic (share);
42674301 case HeapType::i31:
4268- return pick (HeapType ::i31, HeapType ::none);
4302+ return pick (HeapTypes ::i31, HeapTypes ::none). getBasic (share );
42694303 case HeapType::struct_:
4270- return pick (HeapType ::struct_, HeapType ::none);
4304+ return pick (HeapTypes ::struct_, HeapTypes ::none). getBasic (share );
42714305 case HeapType::array:
4272- return pick (HeapType ::array, HeapType ::none);
4306+ return pick (HeapTypes ::array, HeapTypes ::none). getBasic (share );
42734307 case HeapType::exn:
4274- return HeapType ::exn;
4308+ return HeapTypes ::exn. getBasic (share) ;
42754309 case HeapType::string:
4310+ assert (share == Unshared);
42764311 return HeapType::string;
42774312 case HeapType::none:
42784313 case HeapType::noext:
0 commit comments