summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-10-18 10:32:34 -0700
committerGitHub <noreply@github.com>2024-10-18 10:32:34 -0700
commit0b882b9e60f05db9e56f0c35cfbb38eb87619a76 (patch)
tree081627403ef93daefe1538da40a4e892edb760f4
parent795cf2895f713e8b05924e2a1e24a4d2de3ebcf5 (diff)
downloadbinaryen-0b882b9e60f05db9e56f0c35cfbb38eb87619a76.tar.gz
binaryen-0b882b9e60f05db9e56f0c35cfbb38eb87619a76.tar.bz2
binaryen-0b882b9e60f05db9e56f0c35cfbb38eb87619a76.zip
[GC] Ignore public types in SignatureRefining (#7022)
Similar to #7017 and #7018
-rw-r--r--src/passes/SignatureRefining.cpp17
-rw-r--r--test/lit/passes/signature-refining.wast40
2 files changed, 45 insertions, 12 deletions
diff --git a/src/passes/SignatureRefining.cpp b/src/passes/SignatureRefining.cpp
index ae124dc79..db71c167a 100644
--- a/src/passes/SignatureRefining.cpp
+++ b/src/passes/SignatureRefining.cpp
@@ -147,18 +147,11 @@ struct SignatureRefining : public Pass {
}
}
- // We cannot alter the signature of an exported function, as the outside may
- // notice us doing so. For example, if we turn a parameter from nullable
- // into non-nullable then callers sending a null will break. Put another
- // way, we need to see all callers to refine types, and for exports we
- // cannot do so.
- // TODO If a function type is passed we should also mark the types used
- // there, etc., recursively. For now this code just handles the top-
- // level type, which is enough to keep the fuzzer from erroring. More
- // generally, we need to decide about adding a "closed-world" flag of
- // some kind.
- for (auto* exportedFunc : ExportUtils::getExportedFunctions(*module)) {
- allInfo[exportedFunc->type].canModify = false;
+ // Find the public types, which we must not modify.
+ for (auto type : ModuleUtils::getPublicHeapTypes(*module)) {
+ if (type.isFunction()) {
+ allInfo[type].canModify = false;
+ }
}
// For now, do not optimize types that have subtypes. When we modify such a
diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast
index 7a5020e29..f6f889408 100644
--- a/test/lit/passes/signature-refining.wast
+++ b/test/lit/passes/signature-refining.wast
@@ -1119,3 +1119,43 @@
;; (see tests above for how we handle refining of return values).
)
)
+
+;; Visibility: The type we'd like to refine, $sig, is in a rec group with a
+;; public type, so do not optimize.
+(module
+ (rec
+ ;; CHECK: (rec
+ ;; CHECK-NEXT: (type $sig (sub (func (param anyref))))
+ (type $sig (sub (func (param anyref))))
+
+ ;; CHECK: (type $struct (struct))
+ (type $struct (struct))
+ )
+
+ ;; Export a global with $struct to make it public.
+ ;; CHECK: (type $2 (func))
+
+ ;; CHECK: (global $struct (ref $struct) (struct.new_default $struct))
+ (global $struct (ref $struct) (struct.new $struct))
+
+ ;; CHECK: (export "struct" (global $struct))
+ (export "struct" (global $struct))
+
+ ;; CHECK: (func $func (type $sig) (param $x anyref)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $func (type $sig) (param $x anyref)
+ )
+
+ ;; CHECK: (func $caller (type $2)
+ ;; CHECK-NEXT: (call $func
+ ;; CHECK-NEXT: (struct.new_default $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $caller
+ (call $func
+ (struct.new $struct)
+ )
+ )
+)
+