The core extensions presented here depend on features from the typed function references and exception handling proposals.
cont <typeidx> is a new form of defined type
(cont $ft) ok iff $ft ok and $ft = [t1*] -> [t2*]cont.new <typeidx> creates a new continuation
cont.new $ct : [(ref null? $ft)] -> [(ref $ct)]
$ct = cont $ftcont.bind <typeidx> binds a continuation to (partial) arguments
cont.bind $ct : [t3* (ref null? $ct')] -> [(ref $ct)]
$ct = cont $ft
$ft = [t1*] -> [t2*]
$ct' = cont $ft'
$ft' = [t3* t1'*] -> [t2'*]
[t1'*] -> [t2'*] <: [t1*] -> [t2*]
suspend suspends the current continuation
suspend $t : [t1*] -> [t2*]
tag $t : [t1*] -> [t2*]resume (tag <tagidx> <labelidx>)* resumes a continuation
resume (tag $e $l)* : [t1* (ref null? $ct)] -> [t2*]
$ct = cont $ft$ft = [t1*] -> [t2*](tag $t : [te1*] -> [te2*])*(label $l : [te1'* (ref null? $ct')])*([te1*] <: [te1'*])*($ct' = cont $ft')*([te2*] -> [t2*] <: $ft')*resume_throw aborts a continuation
resume_throw $e : [te* (ref null? $ct)] -> [t2*]
exception $e : [te*]$ct = cont $ft$ft = [t1*] -> [t2*]barrier <instr>* end blocks suspension
barrier $l bt instr* end : [t1*] -> [t2*]
bt = [t1*] -> [t2*]instr* : [t1*] -> [t2*] with labels extended with [t2*]S ::= {..., tags <taginst>*}taginst ::= {type <tagtype>}conts for allocated continuations
S ::= {..., conts <cont>?*}cont ::= (E : n)(ref.cont a) represents a continuation value,
where a is a continuation address indexing into
the store's conts component
ref.cont a : [] -> [(ref $ct)]
S.conts[a] = epsilon \/ S.conts[a] = (E : n)$ct = cont $ft$ft = [t1^n] -> [t2*](handle{(<tagaddr> <labelidx>)*}?
<instr>* end) represents an active handler (or a
barrier when no handler list is present)
(handle{(a $l)*}? instr* end) : [t1*] -> [t2*]
instr* : [t1*] -> [t2*](S.tags[a].type = [te1*] -> [te2*])*(label $l : [te1'* (ref null? $ct')])*([te1*] <: [te1'*])*($ct' = cont $ft')*([te2*] -> [t2*] <: $ft')*
H^ea ::=
_
val* H^ea instr*
label_n{instr*} H^ea end
frame_n{F} H^ea end
catch{...} H^ea end
handle{(ea' $l)*} H^ea end (iff ea notin ea'*)
S; F; (ref.null t) (cont.new $ct) --> S; F; trapS; F; (ref.func fa) (cont.new $ct) --> S'; F; (ref.cont |S.conts|)
S' = S with conts += (E : n)E = _ (invoke fa)$ct = cont $ft$ft = [t1^n] -> [t2*]S; F; (ref.null t) (cont.bind $ct) --> S; F; trapS; F; (ref.cont ca) (cont.bind $ct) --> S'; F; trap
S.conts[ca] = epsilonS; F; v^n (ref.cont ca) (cont.bind $ct) --> S'; F; (ref.const |S.conts|)
S.conts[ca] = (E' : n')$ct = cont $ft$ft = [t1'*] -> [t2'*]n = n' - |t1'*|S' = S with conts[ca] = epsilon with conts += (E : |t1'*|)E = E'[v^n _]S; F; (ref.null t) (resume (tag $e $l)*) --> S; F; trapS; F; (ref.cont ca) (resume (tag $e $l)*) --> S; F; trap
S.conts[ca] = epsilonS; F; v^n (ref.cont ca) (resume (tag $e $l)*) --> S'; F; handle{(ea $l)*} E[v^n] end
S.conts[ca] = (E : n)(ea = F.tags[$e])*S' = S with conts[ca] = epsilonS; F; (ref.null t) (resume_throw $e) --> S; F; trapS; F; (ref.cont ca) (resume_throw $e) --> S; F; trap
S.conts[ca] = epsilonS; F; v^m (ref.cont ca) (resume_throw $e) --> S'; F; E[v^m (throw $e)]
S.conts[ca] = (E : n)S.tags[F.tags[$e]].type = [t1^m] -> [t2*]S' = S with conts[ca] = epsilonS; F; (barrier bt instr* end) --> S; F; handle instr* endS; F; (handle{(e $l)*}? v* end) --> S; F; v*S; F; (handle H^ea[(suspend $e)] end) --> S; F; trap
ea = F.tags[$e]S; F; (handle{(ea1 $l1)* (ea $l) (ea2 $l2)*} H^ea[v^n (suspend $e)] end) --> S'; F; v^n (ref.cont |S.conts|) (br $l)
ea notin ea1*ea = F.tags[$e]S.tags[ea].type = [t1^n] -> [t2^m]S' = S with conts += (H^ea : m)