From 0668d9328ad57100103d6b59f40de513659e1c6b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 12 Dec 2022 16:12:08 -0800 Subject: [Wasm GC] Fix GlobalStructInference on unrefined globals (#5338) If a global's type is not fully refined, then when --gsi replaces a reference with a global.get, we end up with a type that might not be good enough. For example, if the type is any then it is not a subtype of eq and we can't do ref.eq on it, which this pass requires. We also can't just do struct.get on it if it is a too-distant parent or such. --- src/passes/GlobalStructInference.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/passes/GlobalStructInference.cpp b/src/passes/GlobalStructInference.cpp index 938350960..50eddfd98 100644 --- a/src/passes/GlobalStructInference.cpp +++ b/src/passes/GlobalStructInference.cpp @@ -123,6 +123,16 @@ struct GlobalStructInference : public Pass { auto type = global->init->type.getHeapType(); + // The global's declared type must match the init's type. If not, say if + // we had a global declared as type |any| but that contains (ref $A), then + // that is not something we can optimize, as ref.eq on a global.get of + // that global will not validate. (This should not be a problem after + // GlobalSubtyping runs, which will specialize the type of the global.) + if (global->type != global->init->type) { + unoptimizable.insert(type); + continue; + } + // We cannot optimize mutable globals. if (global->mutable_) { unoptimizable.insert(type); @@ -197,14 +207,22 @@ struct GlobalStructInference : public Pass { return; } - auto iter = parent.typeGlobals.find(type.getHeapType()); + // We must ignore the case of a non-struct heap type, that is, a bottom + // type (which is all that is left after we've already ruled out + // unreachable). + auto heapType = type.getHeapType(); + auto iter = parent.typeGlobals.find(heapType); if (iter == parent.typeGlobals.end()) { return; } + // This cannot be a bottom type as we found it in the typeGlobals map, + // which only contains types of struct.news. + assert(heapType.isStruct()); + // The field must be immutable. auto fieldIndex = curr->index; - auto& field = type.getHeapType().getStruct().fields[fieldIndex]; + auto& field = heapType.getStruct().fields[fieldIndex]; if (field.mutable_ == Mutable) { return; } -- cgit v1.2.3