[WIP] ReFinalize GlobalGet in initializers after GlobalRefining When GlobalRefining refines the type of a global, it updates the type of corresponding GlobalGet expressions, then runs ReFinalize to propagate the refined types. However, it only performed these updates in function bodies, leaving stale types on GlobalGet expressions in constant initializers. This bug was not easily caught because the validator did not check that `GlobalGet` types actually match the types of the corresponding globals. Fix the validator to check the types of `GlobalGet` expressions and fix GlobalRefining to properly update constant initializers. Fixes #6565.
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index d44c75c..8d6fdfc 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp
@@ -1013,9 +1013,12 @@ if (!info.validateGlobally) { return; } - shouldBeTrue(getModule()->getGlobalOrNull(curr->name), - curr, - "global.get name must be valid"); + auto* global = getModule()->getGlobalOrNull(curr->name); + if (!shouldBeTrue(global, curr, "global.get name must be valid")) { + return; + } + shouldBeEqual( + global->type, curr->type, curr, "global.get type must match global type"); } void FunctionValidator::visitGlobalSet(GlobalSet* curr) {
diff --git a/test/lit/passes/global-refining.wast b/test/lit/passes/global-refining.wast index 8f0b3c2..ada0b50 100644 --- a/test/lit/passes/global-refining.wast +++ b/test/lit/passes/global-refining.wast
@@ -193,3 +193,9 @@ (nop) ) ) + +;; We can refine globals that are used in other global initializers as well. +(module + (global $refine-me (anyref) (ref.i31 (i32.const 0))) + (global $get (anyref) (global.get $refine-me)) +)