Skip to content

Commit 3b4856e

Browse files
authored
[Stack Switching] Add some tests (#7818)
This adds all the rest of the spec test, only skipping `switch` and full `cont.bind`, which we are leaving for later. Also add a ctor-eval test to show we can fully precompute continuations there.
1 parent 79b76ca commit 3b4856e

File tree

2 files changed

+195
-0
lines changed

2 files changed

+195
-0
lines changed

test/lit/ctor-eval/cont.wast

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
2+
;; RUN: foreach %s %t wasm-ctor-eval --ctors=test --kept-exports=test --quiet -all -S -o - | filecheck %s
3+
4+
;; Test that we can precompute continuations.
5+
6+
(module
7+
(type $f (func))
8+
(type $k (cont $f))
9+
10+
(tag $more)
11+
12+
(global $g (mut i32) (i32.const 0))
13+
14+
(func $run (param $k (ref $k))
15+
;; Run a coroutine, continuing to resume it until it is complete.
16+
;; start
17+
(loop $loop
18+
(block $on (result (ref $k))
19+
(resume $k (on $more $on)
20+
(local.get $k)
21+
)
22+
;; stop
23+
(return)
24+
)
25+
;; continue
26+
(local.set $k)
27+
(br $loop)
28+
)
29+
(unreachable)
30+
)
31+
32+
(func $cont
33+
;; increment the global three times, around suspends.
34+
(global.set $g (i32.add (global.get $g) (i32.const 1)))
35+
(suspend $more)
36+
(global.set $g (i32.add (global.get $g) (i32.const 1)))
37+
(suspend $more)
38+
(global.set $g (i32.add (global.get $g) (i32.const 1)))
39+
)
40+
41+
(func $test (export "test") (result i32)
42+
;; All of this can be computed, leaving a return of 3.
43+
(call $run
44+
(cont.new $k (ref.func $cont))
45+
)
46+
(global.get $g)
47+
)
48+
)
49+
;; CHECK: (type $0 (func (result i32)))
50+
51+
;; CHECK: (export "test" (func $test_3))
52+
53+
;; CHECK: (func $test_3 (type $0) (result i32)
54+
;; CHECK-NEXT: (i32.const 3)
55+
;; CHECK-NEXT: )

test/spec/cont.wast

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,3 +726,143 @@
726726
)
727727
(assert_return (invoke "main") (i32.const 10))
728728

729+
;; Syntax: check unfolded forms
730+
(module
731+
(type $ft (func))
732+
(type $ct (cont $ft))
733+
(rec
734+
(type $ft2 (func (param (ref null $ct2))))
735+
(type $ct2 (cont $ft2)))
736+
737+
(tag $yield (param i32))
738+
(tag $swap)
739+
740+
;; Check cont.new
741+
(func (result (ref $ct))
742+
ref.null $ft
743+
block (param (ref null $ft)) (result (ref $ct))
744+
cont.new $ct
745+
end
746+
)
747+
;; Check cont.bind
748+
(func (param (ref $ct)) (result (ref $ct))
749+
local.get 0
750+
block (param (ref $ct)) (result (ref $ct))
751+
cont.bind $ct $ct
752+
end
753+
)
754+
;; Check suspend
755+
(func
756+
block
757+
suspend $swap
758+
end
759+
)
760+
;; Check resume
761+
(func (param $k (ref $ct)) (result i32)
762+
(local.get $k)
763+
block $on_yield (param (ref $ct)) (result i32 (ref $ct))
764+
resume $ct (on $yield $on_yield)
765+
i32.const 42
766+
return
767+
end
768+
local.set $k
769+
)
770+
;; Check resume_throw
771+
(func (param $k (ref $ct)) (result i32)
772+
block $on_yield (result i32 (ref $ct))
773+
i32.const 42
774+
local.get $k
775+
resume_throw $ct $yield
776+
i32.const 42
777+
return
778+
end
779+
local.set $k
780+
)
781+
;; Check switch
782+
(func (param $k (ref $ct2))
783+
local.get $k
784+
block (param (ref $ct2)) (result (ref null $ct2))
785+
switch $ct2 $swap
786+
end
787+
drop
788+
)
789+
)
790+
791+
;; Syntax: check instructions in tail position in unfolded form
792+
(module
793+
(type $ft (func))
794+
(type $ct (cont $ft))
795+
(rec
796+
(type $ft2 (func (param (ref null $ct2))))
797+
(type $ct2 (cont $ft2)))
798+
799+
(tag $yield (param i32))
800+
(tag $swap)
801+
802+
;; Check cont.new
803+
(func (result (ref $ct))
804+
ref.null $ft
805+
cont.new $ct
806+
)
807+
;; Check cont.bind
808+
(func (param (ref $ct)) (result (ref $ct))
809+
local.get 0
810+
cont.bind $ct $ct
811+
)
812+
813+
;; Check resume
814+
(func (;2;) (param $k (ref $ct))
815+
local.get $k
816+
resume $ct
817+
)
818+
;; Check resume_throw
819+
(func (param $k (ref $ct))
820+
i32.const 42
821+
local.get $k
822+
resume_throw $ct $yield
823+
)
824+
;; Check switch
825+
(func (param $k (ref $ct2)) (result (ref null $ct2))
826+
local.get $k
827+
switch $ct2 $swap
828+
)
829+
;; Check suspend
830+
(func
831+
suspend $swap
832+
)
833+
)
834+
835+
(module
836+
(type $ft0 (func))
837+
(type $ct0 (cont $ft0))
838+
839+
(type $ft1 (func (param (ref $ct0))))
840+
(type $ct1 (cont $ft1))
841+
842+
(tag $t)
843+
844+
(func $f
845+
(cont.new $ct1 (ref.func $g))
846+
(switch $ct1 $t)
847+
)
848+
(elem declare func $f)
849+
850+
(func $g (param (ref $ct0)))
851+
(elem declare func $g)
852+
853+
(func $entry
854+
(cont.new $ct0 (ref.func $f))
855+
(resume $ct0 (on $t switch))
856+
)
857+
)
858+
859+
(assert_invalid
860+
(module
861+
(rec
862+
(type $ft (func (param (ref $ct))))
863+
(type $ct (cont $ft)))
864+
(tag $t (param i32))
865+
866+
(func (param $k (ref $ct))
867+
(switch $ct $t)))
868+
"type mismatch in switch tag")

0 commit comments

Comments
 (0)