Skip to content

Commit 5010b4e

Browse files
authored
Parsing stack switching instructions in unfolded form. (#100)
This patch fixes problems with parsing the stack switching instructions when they appear in unfolded form.
1 parent 86c3eb7 commit 5010b4e

File tree

2 files changed

+112
-6
lines changed

2 files changed

+112
-6
lines changed

interpreter/text/parser.mly

+5-5
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ instr_list :
590590
| instr1 instr_list { fun c -> $1 c @ $2 c }
591591
| select_instr_instr_list { $1 }
592592
| call_instr_instr_list { $1 }
593-
| resume_instr_instr { fun c -> let e, es = $1 c in e :: es }
593+
| resume_instr_instr_list { $1 }
594594

595595
instr1 :
596596
| plain_instr { fun c -> [$1 c @@ $sloc] }
@@ -768,25 +768,25 @@ call_instr_results_instr_list :
768768
| instr_list
769769
{ fun c -> [], $1 c }
770770

771-
resume_instr_instr :
771+
resume_instr_instr_list :
772772
| RESUME var resume_instr_handler_instr
773773
{ let loc1 = $loc($1) in
774774
fun c ->
775775
let x = $2 c type_ in
776-
let hs, es = $3 c in resume x hs @@ loc1, es }
776+
let hs, es = $3 c in (resume x hs @@ loc1) :: es }
777777
| RESUME_THROW var var resume_instr_handler_instr
778778
{ let loc1 = $loc($1) in
779779
fun c ->
780780
let x = $2 c type_ in
781781
let tag = $3 c tag in
782-
let hs, es = $4 c in resume_throw x tag hs @@ loc1, es }
782+
let hs, es = $4 c in (resume_throw x tag hs @@ loc1) :: es }
783783

784784
resume_instr_handler_instr :
785785
| LPAR ON var var RPAR resume_instr_handler_instr
786786
{ fun c -> let hs, es = $6 c in ($3 c tag, OnLabel ($4 c label)) :: hs, es }
787787
| LPAR ON var SWITCH RPAR resume_instr_handler_instr
788788
{ fun c -> let hs, es = $6 c in ($3 c tag, OnSwitch) :: hs, es }
789-
| instr1
789+
| instr_list
790790
{ fun c -> [], $1 c }
791791

792792
block_instr :

test/core/stack-switching/cont.wast

+107-1
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,112 @@
927927
)
928928
(assert_return (invoke "main") (i32.const 10))
929929

930+
;; Syntax: check unfolded forms
931+
(module
932+
(type $ft (func))
933+
(type $ct (cont $ft))
934+
(rec
935+
(type $ft2 (func (param (ref null $ct2))))
936+
(type $ct2 (cont $ft2)))
937+
938+
(tag $yield (param i32))
939+
(tag $swap)
940+
941+
;; Check cont.new
942+
(func (result (ref $ct))
943+
ref.null $ft
944+
block (param (ref null $ft)) (result (ref $ct))
945+
cont.new $ct
946+
end
947+
)
948+
;; Check cont.bind
949+
(func (param (ref $ct)) (result (ref $ct))
950+
local.get 0
951+
block (param (ref $ct)) (result (ref $ct))
952+
cont.bind $ct $ct
953+
end
954+
)
955+
;; Check suspend
956+
(func
957+
block
958+
suspend $swap
959+
end
960+
)
961+
;; Check resume
962+
(func (param $k (ref $ct)) (result i32)
963+
(local.get $k)
964+
block $on_yield (param (ref $ct)) (result i32 (ref $ct))
965+
resume $ct (on $yield $on_yield)
966+
i32.const 42
967+
return
968+
end
969+
local.set $k
970+
)
971+
;; Check resume_throw
972+
(func (param $k (ref $ct)) (result i32)
973+
block $on_yield (result i32 (ref $ct))
974+
i32.const 42
975+
local.get $k
976+
resume_throw $ct $yield
977+
i32.const 42
978+
return
979+
end
980+
local.set $k
981+
)
982+
;; Check switch
983+
(func (param $k (ref $ct2))
984+
local.get $k
985+
block (param (ref $ct2)) (result (ref null $ct2))
986+
switch $ct2 $swap
987+
end
988+
drop
989+
)
990+
)
991+
992+
;; Syntax: check instructions in tail position in unfolded form
993+
(module
994+
(type $ft (func))
995+
(type $ct (cont $ft))
996+
(rec
997+
(type $ft2 (func (param (ref null $ct2))))
998+
(type $ct2 (cont $ft2)))
999+
1000+
(tag $yield (param i32))
1001+
(tag $swap)
1002+
1003+
;; Check cont.new
1004+
(func (result (ref $ct))
1005+
ref.null $ft
1006+
cont.new $ct
1007+
)
1008+
;; Check cont.bind
1009+
(func (param (ref $ct)) (result (ref $ct))
1010+
local.get 0
1011+
cont.bind $ct $ct
1012+
)
1013+
1014+
;; Check resume
1015+
(func (;2;) (param $k (ref $ct))
1016+
local.get $k
1017+
resume $ct
1018+
)
1019+
;; Check resume_throw
1020+
(func (param $k (ref $ct))
1021+
i32.const 42
1022+
local.get $k
1023+
resume_throw $ct $yield
1024+
)
1025+
;; Check switch
1026+
(func (param $k (ref $ct2)) (result (ref null $ct2))
1027+
local.get $k
1028+
switch $ct2 $swap
1029+
)
1030+
;; Check suspend
1031+
(func
1032+
suspend $swap
1033+
)
1034+
)
1035+
9301036
(module
9311037
(type $ft0 (func))
9321038
(type $ct0 (cont $ft0))
@@ -960,4 +1066,4 @@
9601066

9611067
(func (param $k (ref $ct))
9621068
(switch $ct $t)))
963-
"type mismatch in switch tag")
1069+
"type mismatch in switch tag")

0 commit comments

Comments
 (0)