Skip to content

Commit 8dca624

Browse files
authored
[Stack Switching] Fix all the execution-results.h places missing a clear of the continuation store (#7828)
1 parent 7f75140 commit 8dca624

3 files changed

Lines changed: 60 additions & 1 deletion

File tree

scripts/test/fuzzing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
'gufa-cont.wast',
118118
'cont_many_unhandled.wast',
119119
'cont_export.wast',
120+
'cont_export_throw.wast',
120121
# TODO: fix split_wast() on tricky escaping situations like a string ending
121122
# in \\" (the " is not escaped - there is an escaped \ before it)
122123
'string-lifting-section.wast',

src/tools/execution-results.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,26 +472,30 @@ struct ExecutionResults {
472472
if (!param.isDefaultable()) {
473473
std::cout << "[trap fuzzer can only send defaultable parameters to "
474474
"exports]\n";
475+
instance.clearContinuationStore();
475476
return Trap{};
476477
}
477478
arguments.push_back(Literal::makeZero(param));
478479
}
479480
auto flow = instance.callFunction(func->name, arguments);
480-
if (flow.suspendTag) { // TODO: support stack switching here
481+
if (flow.suspendTag) {
481482
std::cout << "[exception thrown: unhandled suspend]" << std::endl;
482483
instance.clearContinuationStore();
483484
return Exception{};
484485
}
485486
return flow.values;
486487
} catch (const TrapException&) {
488+
instance.clearContinuationStore();
487489
return Trap{};
488490
} catch (const WasmException& e) {
491+
instance.clearContinuationStore();
489492
std::cout << "[exception thrown: " << e << "]" << std::endl;
490493
return Exception{};
491494
} catch (const HostLimitException&) {
492495
// This should be ignored and not compared with, as optimizations can
493496
// change whether a host limit is reached.
494497
ignore = true;
498+
instance.clearContinuationStore();
495499
return {};
496500
}
497501
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited.
2+
3+
;; RUN: foreach %s %t wasm-opt -all --fuzz-exec-before -q -o /dev/null 2>&1 | filecheck %s
4+
5+
;; Three exports, one which suspends, the second resumes but ends up throwing,
6+
;; and another suspend. This is a regression test for a bug where the global
7+
;; state of continuations got into a confused state at the last export, and
8+
;; asserted.
9+
10+
(module
11+
(type $none (func))
12+
(type $cont (cont $none))
13+
14+
(import "fuzzing-support" "call-export" (func $call-export (param i32 i32)))
15+
16+
(tag $tag (type $none))
17+
18+
;; CHECK: [fuzz-exec] calling suspend
19+
;; CHECK-NEXT: [exception thrown: unhandled suspend]
20+
(func $suspend (export "suspend")
21+
(suspend $tag)
22+
)
23+
24+
;; CHECK: [fuzz-exec] calling handled
25+
;; CHECK-NEXT: [exception thrown: __private externref]
26+
(func $handled (export "handled")
27+
(drop
28+
(block $block (result (ref $cont))
29+
(resume $cont (on $tag $block)
30+
(cont.new $cont
31+
(ref.func $cont)
32+
)
33+
)
34+
(unreachable)
35+
)
36+
)
37+
)
38+
39+
;; CHECK: [fuzz-exec] calling suspend2
40+
;; CHECK-NEXT: [exception thrown: unhandled suspend]
41+
(func $suspend2 (export "suspend2")
42+
(suspend $tag)
43+
)
44+
45+
(func $cont
46+
;; This calls $suspend through an export, which traps as we cannot suspend
47+
;; through JS.
48+
(call $call-export
49+
(i32.const 0)
50+
(i32.const 0)
51+
)
52+
)
53+
)
54+

0 commit comments

Comments
 (0)