From bf6b06a4ed80d1dd6a781abba713da9bfb631ea8 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 6 May 2026 07:58:39 -0700 Subject: [PATCH 1/2] fix --- src/passes/SignatureRefining.cpp | 7 ++--- test/lit/passes/signature-refining-cont.wast | 31 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 test/lit/passes/signature-refining-cont.wast diff --git a/src/passes/SignatureRefining.cpp b/src/passes/SignatureRefining.cpp index 792aedd9d5c..c1d72bc8d77 100644 --- a/src/passes/SignatureRefining.cpp +++ b/src/passes/SignatureRefining.cpp @@ -168,13 +168,12 @@ struct SignatureRefining : public Pass { false; } - // Continuations must not have params refined, because we do not update - // their users (e.g. cont.bind, resume) with new types. - // TODO: support refining continuations + // Continuations must not have params or results refined, because we do not + // update their users (e.g. cont.bind, resume) with new types. if (module->features.hasStackSwitching()) { for (auto type : ModuleUtils::collectHeapTypes(*module)) { if (type.isContinuation()) { - allInfo[type.getContinuation().type].canModifyParams = false; + allInfo[type.getContinuation().type].canModify = false; } } } diff --git a/test/lit/passes/signature-refining-cont.wast b/test/lit/passes/signature-refining-cont.wast new file mode 100644 index 00000000000..c99ecd8da58 --- /dev/null +++ b/test/lit/passes/signature-refining-cont.wast @@ -0,0 +1,31 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-opt %s --signature-refining -all -S -o - | filecheck %s + +;; cont.bind places restrictions on signature refining. +(module + (rec + (type $A (func (result (ref null $cont-A)))) + + (type $B (func (result (ref null $cont-A)))) + + (type $cont-A (cont $A)) + + (type $cont-B (cont $B)) + ) + + (func $1 (type $A) (result (ref null $cont-A)) + ;; cont.bind requires that the continuation type's results match, so we + ;; cannot refine the type $A: if we make it return an exact result, we would + ;; be binding a continuation that returns an inexact result to an exact one. + (cont.bind $cont-B $cont-A + (cont.new $cont-B + (ref.func $0) + ) + ) + ) + + (func $0 (type $B) (result (ref null $cont-A)) + (unreachable) + ) +) + From 0eb92eeb84ec5b1b05da9bc8a9dfa55a89a8b374 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 6 May 2026 07:59:26 -0700 Subject: [PATCH 2/2] test --- test/lit/passes/signature-refining-cont.wast | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/lit/passes/signature-refining-cont.wast b/test/lit/passes/signature-refining-cont.wast index c99ecd8da58..060dba2026e 100644 --- a/test/lit/passes/signature-refining-cont.wast +++ b/test/lit/passes/signature-refining-cont.wast @@ -4,15 +4,29 @@ ;; cont.bind places restrictions on signature refining. (module (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (func (result (ref null $cont-A)))) (type $A (func (result (ref null $cont-A)))) + ;; CHECK: (type $B (func (result (ref null $cont-A)))) (type $B (func (result (ref null $cont-A)))) + ;; CHECK: (type $cont-A (cont $A)) (type $cont-A (cont $A)) + ;; CHECK: (type $cont-B (cont $B)) (type $cont-B (cont $B)) ) + ;; CHECK: (elem declare func $0) + + ;; CHECK: (func $1 (type $A) (result (ref null $cont-A)) + ;; CHECK-NEXT: (cont.bind $cont-B $cont-A + ;; CHECK-NEXT: (cont.new $cont-B + ;; CHECK-NEXT: (ref.func $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $1 (type $A) (result (ref null $cont-A)) ;; cont.bind requires that the continuation type's results match, so we ;; cannot refine the type $A: if we make it return an exact result, we would @@ -24,6 +38,9 @@ ) ) + ;; CHECK: (func $0 (type $B) (result (ref null $cont-A)) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) (func $0 (type $B) (result (ref null $cont-A)) (unreachable) )