Skip to content

Commit 3c9c6f3

Browse files
authored
SignatureRefining: Do not refine results of functions used in continuations (#8675)
This can break with `cont.bind`, see testcase.
1 parent d1ee405 commit 3c9c6f3

2 files changed

Lines changed: 51 additions & 4 deletions

File tree

src/passes/SignatureRefining.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,12 @@ struct SignatureRefining : public Pass {
168168
false;
169169
}
170170

171-
// Continuations must not have params refined, because we do not update
172-
// their users (e.g. cont.bind, resume) with new types.
173-
// TODO: support refining continuations
171+
// Continuations must not have params or results refined, because we do not
172+
// update their users (e.g. cont.bind, resume) with new types.
174173
if (module->features.hasStackSwitching()) {
175174
for (auto type : ModuleUtils::collectHeapTypes(*module)) {
176175
if (type.isContinuation()) {
177-
allInfo[type.getContinuation().type].canModifyParams = false;
176+
allInfo[type.getContinuation().type].canModify = false;
178177
}
179178
}
180179
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
2+
;; RUN: wasm-opt %s --signature-refining -all -S -o - | filecheck %s
3+
4+
;; cont.bind places restrictions on signature refining.
5+
(module
6+
(rec
7+
;; CHECK: (rec
8+
;; CHECK-NEXT: (type $A (func (result (ref null $cont-A))))
9+
(type $A (func (result (ref null $cont-A))))
10+
11+
;; CHECK: (type $B (func (result (ref null $cont-A))))
12+
(type $B (func (result (ref null $cont-A))))
13+
14+
;; CHECK: (type $cont-A (cont $A))
15+
(type $cont-A (cont $A))
16+
17+
;; CHECK: (type $cont-B (cont $B))
18+
(type $cont-B (cont $B))
19+
)
20+
21+
;; CHECK: (elem declare func $0)
22+
23+
;; CHECK: (func $1 (type $A) (result (ref null $cont-A))
24+
;; CHECK-NEXT: (cont.bind $cont-B $cont-A
25+
;; CHECK-NEXT: (cont.new $cont-B
26+
;; CHECK-NEXT: (ref.func $0)
27+
;; CHECK-NEXT: )
28+
;; CHECK-NEXT: )
29+
;; CHECK-NEXT: )
30+
(func $1 (type $A) (result (ref null $cont-A))
31+
;; cont.bind requires that the continuation type's results match, so we
32+
;; cannot refine the type $A: if we make it return an exact result, we would
33+
;; be binding a continuation that returns an inexact result to an exact one.
34+
(cont.bind $cont-B $cont-A
35+
(cont.new $cont-B
36+
(ref.func $0)
37+
)
38+
)
39+
)
40+
41+
;; CHECK: (func $0 (type $B) (result (ref null $cont-A))
42+
;; CHECK-NEXT: (unreachable)
43+
;; CHECK-NEXT: )
44+
(func $0 (type $B) (result (ref null $cont-A))
45+
(unreachable)
46+
)
47+
)
48+

0 commit comments

Comments
 (0)