Skip to content

Commit 5b4f1cf

Browse files
authored
Resume with only one tag (#70)
- Extend `ContV` with `k: (Stack, Cont[A], MCont[A], Handler[A]) => A`
1 parent 4865eab commit 5b4f1cf

18 files changed

+617
-66
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(module definition binary
2+
"\00\61\73\6d\01\00\00\00\01\8e\80\80\80\00\04\60"
3+
"\00\01\7f\5d\00\60\01\7f\01\7f\5d\02\03\83\80\80"
4+
"\80\00\02\02\02\07\88\80\80\80\00\01\04\6d\61\69"
5+
"\6e\00\01\09\85\80\80\80\00\01\03\00\01\00\0a\a0"
6+
"\80\80\80\00\02\87\80\80\80\00\00\20\00\41\2c\6a"
7+
"\0b\8e\80\80\80\00\00\20\00\d2\00\e0\03\e1\03\01"
8+
"\e3\01\00\0b"
9+
)
10+
(module instance)
11+
(assert_return (invoke "main" (i32.const 0x16)) (i32.const 0x42))
12+
(assert_return (invoke "main" (i32.const 0xffff_fe44)) (i32.const 0xffff_fe70))
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
(module
2+
(type $f1 (func (result i32)))
3+
(type $c1 (cont $f1))
4+
5+
(type $f2 (func (param i32) (result i32)))
6+
(type $c2 (cont $f2))
7+
8+
(func $add44 (param i32) (result i32) (i32.add (local.get 0) (i32.const 44)))
9+
(elem declare func $add44)
10+
11+
(func (export "main") (param i32) (result i32)
12+
(resume $c1
13+
(cont.bind $c2 $c1
14+
(local.get 0)
15+
(cont.new $c2 (ref.func $add44))))
16+
)
17+
)
18+
19+
(assert_return (invoke "main" (i32.const 22)) (i32.const 66))
20+
(assert_return (invoke "main" (i32.const -444)) (i32.const -400))
21+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
(module
2+
(type (;0;) (func (param i32) (result i32)))
3+
(type (;1;) (cont 0))
4+
(type (;2;) (func (param i32 i32) (result i32)))
5+
(type (;3;) (cont 2))
6+
(type (;4;) (func (param i32)))
7+
(type (;5;) (func))
8+
(import "spectest" "print_i32" (func (;0;) (type 4)))
9+
(export "main" (func 3))
10+
(start 3)
11+
(elem (;0;) declare func 1)
12+
(func (;1;) (type 2) (param i32 i32) (result i32)
13+
local.get 0
14+
local.get 1
15+
i32.sub
16+
)
17+
(func (;2;) (type 2) (param i32 i32) (result i32)
18+
local.get 1
19+
local.get 0
20+
ref.func 1
21+
cont.new 3
22+
cont.bind 3 1
23+
resume 1
24+
)
25+
(func (;3;) (type 5)
26+
i32.const 22
27+
i32.const 44
28+
call 2
29+
call 0
30+
)
31+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
(module definition binary
2+
"\00\61\73\6d\01\00\00\00\01\90\80\80\80\00\04\60"
3+
"\01\7f\01\7f\5d\00\60\02\7f\7f\01\7f\5d\02\03\83"
4+
"\80\80\80\00\02\02\02\07\88\80\80\80\00\01\04\6d"
5+
"\61\69\6e\00\01\09\85\80\80\80\00\01\03\00\01\00"
6+
"\0a\a2\80\80\80\00\02\87\80\80\80\00\00\20\00\20"
7+
"\01\6b\0b\90\80\80\80\00\00\20\01\20\00\d2\00\e0"
8+
"\03\e1\03\01\e3\01\00\0b"
9+
)
10+
(module instance)
11+
(assert_return
12+
(invoke "main" (i32.const 0x16) (i32.const 0x2c))
13+
(i32.const 0xffff_ffea)
14+
)
15+
(assert_return
16+
(invoke "main" (i32.const 0xffff_fe44) (i32.const 0x6f))
17+
(i32.const 0xffff_fdd5)
18+
)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
(module
2+
;; (type $f1 (func (result i32)))
3+
;; (type $c1 (cont $f1))
4+
5+
(type $f2 (func (param i32) (result i32)))
6+
(type $c2 (cont $f2))
7+
8+
(type $f3 (func (param i32 i32) (result i32)))
9+
(type $c3 (cont $f3))
10+
11+
(func $sub (param i32 i32) (result i32) (i32.sub (local.get 0) (local.get 1)))
12+
(elem declare func $sub)
13+
14+
(func (export "main") (param i32 i32) (result i32)
15+
(resume $c2
16+
(local.get 1)
17+
(cont.bind $c3 $c2
18+
(local.get 0)
19+
(cont.new $c3 (ref.func $sub))))
20+
)
21+
)
22+
23+
;; (assert_return (invoke "main" (i32.const 22) (i32.const 44)) (i32.const -22))
24+
;; (assert_return (invoke "main" (i32.const -444) (i32.const 111)) (i32.const -555))
25+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
(module
2+
(type (;0;) (func (param i32)))
3+
(type (;1;) (cont 0))
4+
(type (;2;) (func (result i32)))
5+
(type (;3;) (func))
6+
(import "spectest" "print_i32" (func (;0;) (type 0)))
7+
(tag (;0;) (type 2) (result i32))
8+
(export "_start" (func 2))
9+
(start 2)
10+
(elem (;0;) declare func 1)
11+
(func (;1;) (type 0) (param i32)
12+
local.get 0
13+
call 0
14+
suspend 0
15+
call 0
16+
)
17+
(func (;2;) (type 3)
18+
(local i32 (ref 1))
19+
ref.func 1
20+
cont.new 1
21+
local.set 1
22+
i32.const 10
23+
local.set 0
24+
block ;; label = @1
25+
block (result (ref 1)) ;; label = @2
26+
local.get 0
27+
local.get 1
28+
resume 1 (on 0 0 (;@2;))
29+
i32.const -2
30+
call 0
31+
br 1 (;@1;)
32+
end
33+
local.set 1
34+
local.get 0
35+
i32.const 1
36+
i32.add
37+
local.set 0
38+
block ;; label = @2
39+
block (result (ref 1)) ;; label = @3
40+
local.get 0
41+
local.get 1
42+
resume 1 (on 0 0 (;@3;))
43+
i32.const 42
44+
call 0
45+
br 1 (;@2;)
46+
end
47+
i32.const 111
48+
call 0
49+
drop
50+
end
51+
end
52+
)
53+
)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
(module
2+
(import "spectest" "print_i32" (func $print_i32 (param i32)))
3+
(type $task (func (param i32)))
4+
(type $cont (cont $task))
5+
6+
(tag $yield (result i32))
7+
8+
(func $task1 (param $x i32)
9+
(call $print_i32 (local.get $x))
10+
(suspend $yield) ;; DH: levaes a continuation on the stack, jump to the tag $yield
11+
;; when come back, the stack should contains a i32 value, since the return type of $yield is i32
12+
(call $print_i32)
13+
)
14+
15+
(func $main (export "_start")
16+
(local $i i32)
17+
(local $k (ref $cont))
18+
(local.set $k (cont.new $cont (ref.func $task1)))
19+
(local.set $i (i32.const 10))
20+
(block $h
21+
(block $on_yield (result (ref $cont))
22+
(resume $cont
23+
(on $yield $on_yield)
24+
(local.get $i)
25+
(local.get $k)
26+
)
27+
(call $print_i32 (i32.const -2))
28+
(br $h))
29+
;; $on_yield lands here, with the continuation on the stack
30+
(local.set $k)
31+
(local.set $i (i32.add (local.get $i) (i32.const 1)))
32+
(block $h
33+
(block $on_yield2 (result (ref $cont))
34+
(resume $cont
35+
(on $yield $on_yield2)
36+
(local.get $i)
37+
(local.get $k)
38+
)
39+
(call $print_i32 (i32.const 42))
40+
(br $h)
41+
)
42+
;; $on_yield2 lands here, with the continuation on the stack
43+
(call $print_i32 (i32.const 111))
44+
drop
45+
)
46+
)
47+
)
48+
49+
(elem declare func $task1)
50+
51+
(start $main)
52+
)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
(module
2+
(type (;0;) (func))
3+
(type (;1;) (cont 0))
4+
(type (;2;) (func (param i32)))
5+
(type (;3;) (func (result i32 (ref 1))))
6+
(import "spectest" "print_i32" (func (;0;) (type 2)))
7+
(tag (;0;) (type 2) (param i32))
8+
(start 2)
9+
(elem (;0;) declare func 1)
10+
(func (;1;) (type 0)
11+
(local i32)
12+
i32.const 100
13+
local.set 0
14+
loop ;; label = @1
15+
local.get 0
16+
suspend 0
17+
local.get 0
18+
i32.const 1
19+
i32.sub
20+
local.tee 0
21+
br_if 0 (;@1;)
22+
end
23+
)
24+
(func (;2;) (type 0)
25+
(local (ref 1))
26+
ref.func 1
27+
cont.new 1
28+
local.set 0
29+
loop ;; label = @1
30+
block (result i32 (ref 1)) ;; label = @2
31+
local.get 0
32+
resume 1 (on 0 0 (;@2;)) ;; wasmfx ref interpreter has a bug on this, you can add a bracket around `resume ..` to get around
33+
i32.const 42
34+
call 0
35+
br 2 (;@2;)
36+
end
37+
local.set 0
38+
call 0
39+
br 0 (;@1;)
40+
end
41+
)
42+
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
(module
2+
(type (;0;) (func))
3+
(type (;1;) (cont 0))
4+
(type (;2;) (func (param i32)))
5+
(import "spectest" "print_i32" (func (;0;) (type 2)))
6+
(tag (;0;) (type 0))
7+
(export "_start" (func 3))
8+
(start 3)
9+
;; (elem (;0;) declare func 1 2)
10+
(func (;1;) (type 0)
11+
suspend 0
12+
)
13+
(func (;2;) (type 0)
14+
block ;; label = @1
15+
block (result (ref 1)) ;; label = @2
16+
ref.func 1
17+
cont.new 1
18+
resume 1 (on 0 0 (;@2;))
19+
br 1 (;@1;)
20+
end
21+
drop
22+
i32.const 0
23+
call 0
24+
end
25+
)
26+
(func (;3;) (type 0)
27+
block ;; label = @1
28+
block (result (ref 1)) ;; label = @2
29+
ref.func 2
30+
cont.new 1
31+
resume 1 (on 0 0 (;@2;))
32+
br 1 (;@1;)
33+
end
34+
drop
35+
i32.const 1
36+
call 0
37+
end
38+
)
39+
)

benchmarks/wasm/wasmfx/resume2.wat

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(module
2+
(type $f1 (func (result i32)))
3+
(type $c1 (cont $f1))
4+
(func $f42 (result i32) (i32.const 42))
5+
(elem declare func $f42)
6+
(func (export "main") (result i32)
7+
(resume $c1 (cont.new $c1 (ref.func $f42)))
8+
)
9+
)

0 commit comments

Comments
 (0)