diff options
author | Alon Zakai <azakai@google.com> | 2022-12-12 16:12:08 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-12 16:12:08 -0800 |
commit | 0668d9328ad57100103d6b59f40de513659e1c6b (patch) | |
tree | 0b0c59d5340034a151369e96906a45e1ecf1421f /src | |
parent | 6c0d8f7bb674da1cf22499873f6fe87e45f3be64 (diff) | |
download | binaryen-0668d9328ad57100103d6b59f40de513659e1c6b.tar.gz binaryen-0668d9328ad57100103d6b59f40de513659e1c6b.tar.bz2 binaryen-0668d9328ad57100103d6b59f40de513659e1c6b.zip |
[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.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/GlobalStructInference.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
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; } |