Skip to content

Commit 85c606b

Browse files
authored
[Continuations] Trap on suspending through JS, don't throw a JS exception (#8419)
We should not be able to catch such an error. This now matches V8's behavior. Fixes #8416
1 parent cc866c7 commit 85c606b

File tree

5 files changed

+66
-6
lines changed

5 files changed

+66
-6
lines changed

src/tools/execution-results.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,10 @@ struct LoggingExternalInterface : public ShellExternalInterface {
341341

342342
// Call the function.
343343
auto flow = doCall(arguments);
344-
// Suspending through JS is not valid.
344+
// Suspending through JS is not valid. This traps - it does not throw a
345+
// catchable JS exception.
345346
if (flow.suspendTag) {
346-
throwJSException();
347+
trap("suspend through JS");
347348
}
348349
return flow.values;
349350
}

test/lit/exec/cont_export.wast

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
;; CHECK: [fuzz-exec] calling call-call-export
2626
;; CHECK-NEXT: [LoggingExternalInterface logging 10]
27-
;; CHECK-NEXT: [exception thrown: imported-js-tag externref(0)]
27+
;; CHECK-NEXT: [trap suspend through JS]
2828
(func $call-call-export (export "call-call-export")
2929
;; Call suspend as an export. We cannot suspend through JS, so we throw.
3030
(call $call-export
@@ -35,7 +35,7 @@
3535

3636
;; CHECK: [fuzz-exec] calling handled
3737
;; CHECK-NEXT: [LoggingExternalInterface logging 10]
38-
;; CHECK-NEXT: [exception thrown: imported-js-tag externref(0)]
38+
;; CHECK-NEXT: [trap suspend through JS]
3939
(func $handled (export "handled")
4040
;; As above, but inside a continuation, so it would be handled - if we could
4141
;; suspend though JS. But we can't, so we throw.

test/lit/exec/cont_export_throw.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
)
2323

2424
;; CHECK: [fuzz-exec] calling handled
25-
;; CHECK-NEXT: [exception thrown: imported-js-tag externref(0)]
25+
;; CHECK-NEXT: [trap suspend through JS]
2626
(func $handled (export "handled")
2727
(drop
2828
(block $block (result (ref $cont))

test/lit/exec/cont_many_unhandled_2.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
)
3636

3737
;; CHECK: [fuzz-exec] calling call-suspend
38-
;; CHECK-NEXT: [exception thrown: unhandled suspend]
38+
;; CHECK-NEXT: [trap suspend through JS]
3939
(func $call-suspend (export "call-suspend")
4040
(drop
4141
(call $call-export-catch

test/lit/exec/cont_through_js.wast

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
;; $test will try to suspend through JS. That traps. If it threw a JS exception
6+
;; instead, we would catch that exception and continue onwards, hitting an
7+
;; invalid internal state.
8+
9+
(module
10+
(type $f (func))
11+
(type $k (cont $f))
12+
13+
(import "fuzzing-support" "call-export" (func $call-export (param i32 i32)))
14+
(import "fuzzing-support" "call-export-catch" (func $call-export-catch (param i32) (result i32)))
15+
16+
(tag $e)
17+
18+
;; CHECK: [fuzz-exec] calling suspend
19+
;; CHECK-NEXT: [exception thrown: unhandled suspend]
20+
(func $suspend (export "suspend")
21+
(suspend $e)
22+
)
23+
24+
;; CHECK: [fuzz-exec] calling handle
25+
;; CHECK-NEXT: [trap suspend through JS]
26+
(func $handle (export "handle")
27+
(drop
28+
(block $block (result (ref $k))
29+
(resume $k (on $e $block)
30+
(cont.new $k
31+
(ref.func $suspend-after-host-frame)
32+
)
33+
)
34+
(return)
35+
)
36+
)
37+
)
38+
39+
(func $suspend-after-host-frame (type $f)
40+
(call $call-export
41+
(i32.const 0) ;; "suspend"
42+
(i32.const 0)
43+
)
44+
)
45+
46+
;; CHECK: [fuzz-exec] calling test
47+
;; CHECK-NEXT: [trap suspend through JS]
48+
(func $test (export "test")
49+
(drop
50+
(call $call-export-catch
51+
(i32.const 1) ;; "handle"
52+
)
53+
)
54+
(call $call-export
55+
(i32.const 0) ;; "suspend"
56+
(i32.const 1) ;; rethrow exceptions
57+
)
58+
)
59+
)

0 commit comments

Comments
 (0)