Skip to content

Commit 7567bdd

Browse files
committed
fix tail call mismutation
1 parent 81e6fa8 commit 7567bdd

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

src/tools/fuzzing/fuzzing.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,6 +2428,12 @@ void TranslateToFuzzReader::mutateJSBoundary() {
24282428
if (getModule()->getFunction(curr->target)->imported()) {
24292429
map[curr->target].callImports.push_back(curr);
24302430
}
2431+
2432+
// Return calls add a dependency similar to references: we cannot refine
2433+
// the callee without coordination with the caller.
2434+
if (curr->isReturn) {
2435+
map[curr->target].reffed = true;
2436+
}
24312437
}
24322438

24332439
void visitRefFunc(RefFunc* curr) { map[curr->func].reffed = true; }

test/unit/input/fuzz.wat

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,25 @@
4545
(func $export-reffed (export "export-reffed") (param $0 i32) (param $1 anyref) (result eqref)
4646
(struct.new $A)
4747
)
48+
49+
;; An export without a ref.func but that has a tail call, which also prevents
50+
;; us from refining its results. The called function and the caller both
51+
;; return nullref initially, and each might be refined to a conflicting type,
52+
;; if we are not careful here.
53+
54+
(func $tail-called (export "tail-called") (result nullref)
55+
(ref.null $A)
56+
)
57+
58+
(func $tail-caller (export "tail-caller") (param $x i32) (result nullref)
59+
(if
60+
(local.get $x)
61+
(then
62+
(return
63+
(ref.null $B)
64+
)
65+
)
66+
)
67+
(return_call $tail-called)
68+
)
4869
)

0 commit comments

Comments
 (0)