2222#include " ir/find_all.h"
2323#include " ir/lubs.h"
2424#include " ir/module-utils.h"
25+ #include " ir/public-type-validator.h"
2526#include " ir/utils.h"
2627#include " pass.h"
2728#include " wasm-type.h"
@@ -75,13 +76,17 @@ struct GlobalRefining : public Pass {
7576 // fields in subtypes - the types must match exactly, or else a write in
7677 // one place could store a type considered in valid in another place).
7778 std::unordered_set<Name> unoptimizable;
78- for (auto * global : ExportUtils::getExportedGlobals (*module )) {
79+ auto exportedGlobalsVec = ExportUtils::getExportedGlobals (*module );
80+ std::unordered_set<Global*> exportedGlobals (exportedGlobalsVec.begin (),
81+ exportedGlobalsVec.end ());
82+ for (auto * global : exportedGlobalsVec) {
7983 if (getPassOptions ().closedWorld || global->mutable_ ) {
8084 unoptimizable.insert (global->name );
8185 }
8286 }
8387
8488 bool optimized = false ;
89+ PublicTypeValidator publicTypeValidator (module ->features );
8590
8691 for (auto & global : module ->globals ) {
8792 if (global->imported () || unoptimizable.count (global->name )) {
@@ -102,12 +107,20 @@ struct GlobalRefining : public Pass {
102107
103108 auto oldType = global->type ;
104109 auto newType = lub.getLUB ();
105- if (newType != oldType) {
106- // We found an improvement!
107- assert (Type::isSubType (newType, oldType));
108- global->type = newType;
109- optimized = true ;
110+ if (newType == oldType) {
111+ continue ;
110112 }
113+
114+ // Do not make invalid types public.
115+ if (exportedGlobals.count (global.get ()) &&
116+ !publicTypeValidator.isValidPublicType (newType)) {
117+ continue ;
118+ }
119+
120+ // We found an improvement!
121+ assert (Type::isSubType (newType, oldType));
122+ global->type = newType;
123+ optimized = true ;
111124 }
112125
113126 if (!optimized) {
0 commit comments