Skip to content

Commit adf76cf

Browse files
dvdvgtb-studios
andauthored
JS runtime: Extract RESUME function (#708)
Co-authored-by: Jonathan Brachthäuser <[email protected]>
1 parent 85bd688 commit adf76cf

File tree

4 files changed

+24
-15
lines changed

4 files changed

+24
-15
lines changed

effekt/shared/src/main/scala/effekt/cps/Transformer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ object Transformer {
138138
case core.Stmt.Resume(cont, body) =>
139139
val ks2 = Id("ks")
140140
val k2 = Id("k")
141-
val thunk: BlockLit = Block.BlockLit(Nil, Nil, ks2, k2, transform(body, ks2, Continuation.Dynamic(k2)))
142-
App(Block.BlockVar(cont.id), Nil, List(thunk), MetaCont(ks), k.reify)
141+
Resume(cont.id, Block.BlockLit(Nil, Nil, ks2, k2, transform(body, ks2, Continuation.Dynamic(k2))),
142+
MetaCont(ks), k.reify)
143143

144144
case core.Stmt.Hole() => Hole()
145145

effekt/shared/src/main/scala/effekt/cps/Tree.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ enum Stmt extends Tree {
139139
// shift(p, { (resume, ks, k) => STMT }, ks, k)
140140
case Shift(prompt: Id, body: BlockLit, ks: MetaCont, k: Cont)
141141

142+
// resume(r, (ks, k) => STMT, ks, k)
143+
case Resume(resumption: Id, body: BlockLit, ks: MetaCont, k: Cont)
144+
142145
// Others
143146
case Hole()
144147
}
@@ -219,6 +222,7 @@ object Variables {
219222

220223
case Stmt.Reset(prog, ks, k) => free(prog) ++ free(ks) ++ free(k)
221224
case Stmt.Shift(prompt, body, ks, k) => block(prompt) ++ free(body) ++ free(ks) ++ free(k)
225+
case Stmt.Resume(r, body, ks, k) => block(r) ++ free(body) ++ free(ks) ++ free(k)
222226
case Stmt.Hole() => empty
223227
}
224228

effekt/shared/src/main/scala/effekt/generator/js/TransformerCps.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ object TransformerCps extends Transformer {
1414
val RUN_TOPLEVEL = Variable(JSName("RUN_TOPLEVEL"))
1515
val RESET = Variable(JSName("RESET"))
1616
val SHIFT = Variable(JSName("SHIFT"))
17+
val RESUME = Variable(JSName("RESUME"))
1718
val THUNK = Variable(JSName("THUNK"))
1819
val DEALLOC = Variable(JSName("DEALLOC"))
1920
val TRAMPOLINE = Variable(JSName("TRAMPOLINE"))
@@ -257,6 +258,9 @@ object TransformerCps extends Transformer {
257258
case cps.Stmt.Shift(prompt, body, ks, k) =>
258259
pure(js.Return(Call(SHIFT, nameRef(prompt), noThunking { toJS(body) }, toJS(ks), toJS(k))))
259260

261+
case cps.Stmt.Resume(r, b, ks2, k2) =>
262+
pure(js.Return(js.Call(RESUME, nameRef(r), toJS(b), toJS(ks2), toJS(k2))))
263+
260264
case cps.Stmt.Hole() =>
261265
pure(js.Return($effekt.call("hole")))
262266
}

libraries/js/effekt_runtime.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,23 @@ function SHIFT(p, body, ks, k) {
113113
cont = { stack: meta.stack, prompt: meta.prompt, backup: meta.arena.backup(), rest: cont }
114114
meta = meta.rest
115115

116-
function resumeComp(c, ks, k) {
117-
let meta = { stack: k, prompt: ks.prompt, arena: ks.arena, rest: ks.rest }
118-
let toRewind = cont
119-
while (!!toRewind) {
120-
meta = { stack: toRewind.stack, prompt: toRewind.prompt, arena: toRewind.backup(), rest: meta }
121-
toRewind = toRewind.rest
122-
}
116+
const k1 = meta.stack
117+
meta.stack = null
118+
return body(cont, meta, k1)
119+
}
123120

124-
const k2 = meta.stack // TODO instead copy meta here, like elsewhere?
125-
meta.stack = null
126-
return () => c(meta, k2)
121+
// Rewind stack `cont` back onto `k` :: `ks` and resume with c
122+
function RESUME(cont, c, ks, k) {
123+
let meta = { stack: k, prompt: ks.prompt, arena: ks.arena, rest: ks.rest }
124+
let toRewind = cont
125+
while (!!toRewind) {
126+
meta = { stack: toRewind.stack, prompt: toRewind.prompt, arena: toRewind.backup(), rest: meta }
127+
toRewind = toRewind.rest
127128
}
128129

129-
let k1 = meta.stack
130+
const k1 = meta.stack // TODO instead copy meta here, like elsewhere?
130131
meta.stack = null
131-
return body(resumeComp, meta, k1)
132+
return () => c(meta, k1)
132133
}
133134

134135
function RUN_TOPLEVEL(comp) {
@@ -210,4 +211,4 @@ $effekt.run = RUN
210211
*
211212
* If a runtime is available, use `$effekt.run`, instead.
212213
*/
213-
$effekt.runToplevel = RUN_TOPLEVEL
214+
$effekt.runToplevel = RUN_TOPLEVEL

0 commit comments

Comments
 (0)