@@ -29,21 +29,17 @@ object HandlerLowering:
29
29
30
30
private case class LinkState (res : Path , cls : Path , uid : StateId )
31
31
32
- // shouldUnwrapRet: whether the current block should unwrap the runtime.Return if it encounter one
33
32
// isTopLevel:
34
33
// whether the current block is the top level block, as we do not emit code for continuation class on the top level
35
34
// since we cannot return an effect signature on the top level (we are not in a function so return statement are invalid)
36
35
// and we do not have any `return` statement in the top level block so we do not need the `runtime.Return` workarounds.
37
- // isHandler: whether the current block is the body of handler method
38
36
// contName: the name of the continuation class
39
37
// ctorThis: the path to `this` in the constructor, this is used to insert `return this;` at the end of constructor.
40
38
// linkAndHandle:
41
39
// a function that takes a LinkState and returns a block that links the continuation class and handles the effect
42
40
// this is a convenience function which initializes the continuation class in function context or throw an error in top level
43
41
private case class HandlerCtx (
44
- shouldUnwrapRet : Bool ,
45
42
isTopLevel : Bool ,
46
- isHandlerMtd : Bool ,
47
43
isHandlerBody : Bool ,
48
44
contName : Str ,
49
45
ctorThis : Option [Path ],
@@ -59,27 +55,25 @@ class HandlerPaths(using Elaborator.State):
59
55
val effectSigPath : Path = runtimePath.selN(Tree .Ident (" EffectSig" )).selN(Tree .Ident (" class" ))
60
56
val effectSigSym : ClassSymbol = State .effectSigSymbol
61
57
val contClsPath : Path = runtimePath.selN(Tree .Ident (" FunctionContFrame" )).selN(Tree .Ident (" class" ))
62
- val retClsPath : Path = runtimePath.selN(Tree .Ident (" Return" )).selN(Tree .Ident (" class" ))
63
- val retClsSym : ClassSymbol = State .returnClsSymbol
64
58
val mkEffectPath : Path = runtimePath.selN(Tree .Ident (" mkEffect" ))
65
59
val handleBlockImplPath : Path = runtimePath.selN(Tree .Ident (" handleBlockImpl" ))
66
60
val stackDelayClsPath : Path = runtimePath.selN(Tree .Ident (" StackDelay" ))
67
61
68
62
def isHandlerClsPath (p : Path ) =
69
- (p eq contClsPath) || (p eq stackDelayClsPath) || (p eq effectSigPath) || (p eq retClsPath)
63
+ (p eq contClsPath) || (p eq stackDelayClsPath) || (p eq effectSigPath)
70
64
71
65
class HandlerLowering (paths : HandlerPaths )(using TL , Raise , Elaborator .State , Elaborator .Ctx ):
72
66
73
67
private def funcLikeHandlerCtx (ctorThis : Option [Path ], isHandlerMtd : Bool , nme : Str ) =
74
- HandlerCtx (! isHandlerMtd, false , isHandlerMtd , false , nme, ctorThis, state =>
68
+ HandlerCtx (false , false , nme, ctorThis, state =>
75
69
blockBuilder
76
70
.assignFieldN(state.res.contTrace.last, nextIdent, Instantiate (
77
71
state.cls.selN(Tree .Ident (" class" )),
78
72
Value .Lit (Tree .IntLit (state.uid)) :: Nil ))
79
73
.assignFieldN(state.res.contTrace, lastIdent, state.res.contTrace.last.next)
80
74
.ret(state.res))
81
75
private def functionHandlerCtx (nme : Str ) = funcLikeHandlerCtx(N , false , nme)
82
- private def topLevelCtx (nme : Str ) = HandlerCtx (false , true , false , false , nme, N , _ => rtThrowMsg(" Unhandled effects" ))
76
+ private def topLevelCtx (nme : Str ) = HandlerCtx (true , false , nme, N , _ => rtThrowMsg(" Unhandled effects" ))
83
77
private def ctorCtx (ctorThis : Path , nme : Str ) = funcLikeHandlerCtx(S (ctorThis), false , nme)
84
78
private def handlerMtdCtx (nme : Str ) = funcLikeHandlerCtx(N , true , nme)
85
79
private def handlerCtx (using HandlerCtx ): HandlerCtx = summon
@@ -116,25 +110,25 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
116
110
def apply (res : Local , uid : StateId ) =
117
111
Assign (res, PureCall (Value .Ref (returnContSymbol), List (Value .Lit (Tree .IntLit (uid)))), End (" " ))
118
112
def unapply (blk : Block ) = blk match
119
- case Assign (res, PureCall (Value .Ref (`returnContSymbol`), List (Value .Lit (Tree .IntLit (uid)))), _) =>
113
+ case Assign (res, PureCall (Value .Ref (`returnContSymbol`), List (Value .Lit (Tree .IntLit (uid)))), _) =>
120
114
Some (res, uid)
121
115
case _ => None
122
116
123
117
// placeholder for effectful Results, such as Call, Instantiate and anything else that could
124
118
// return a continuation
125
119
object ResultPlaceholder :
126
120
private val callSymbol = freshTmp(" resultPlaceholder" )
127
- def apply (res : Local , uid : StateId , canRet : Bool , r : Result , rest : Block ) =
121
+ def apply (res : Local , uid : StateId , r : Result , rest : Block ) =
128
122
Assign (
129
123
res,
130
- PureCall (Value .Ref (callSymbol), List (Value .Lit (Tree .IntLit (uid)), Value . Lit ( Tree . BoolLit (canRet)) )),
124
+ PureCall (Value .Ref (callSymbol), List (Value .Lit (Tree .IntLit (uid)))),
131
125
Assign (res, r, rest))
132
126
def unapply (blk : Block ) = blk match
133
127
case Assign (
134
128
res,
135
- PureCall (Value .Ref (`callSymbol`), List (Value .Lit (Tree .IntLit (uid)), Value . Lit ( Tree . BoolLit (canRet)) )),
129
+ PureCall (Value .Ref (`callSymbol`), List (Value .Lit (Tree .IntLit (uid)))),
136
130
Assign (_, c, rest)) =>
137
- Some (res, uid, canRet, c, rest)
131
+ Some (res, uid, c, rest)
138
132
case _ => None
139
133
140
134
object StateTransition :
@@ -287,7 +281,6 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
287
281
case TryBlock (sub, finallyDo, rest) => ??? // ignore
288
282
case Throw (_) => PartRet (blk, Nil )
289
283
case _ : HandleBlock => lastWords(" unexpected handleBlock" ) // already translated at this point
290
- case _ : HandleBlockReturn => lastWords(" unexpected handleBlockReturn" ) // already translated at this point
291
284
292
285
val result = go(blk)(using labelIds, N )
293
286
result.states
@@ -327,26 +320,26 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
327
320
val fun2 = applyPath(fun)
328
321
val args2 = args.mapConserve(applyArg)
329
322
val c2 = if (fun2 is fun) && (args2 is args) then c else Call (fun2, args2)(c.isMlsFun, c.mayRaiseEffects)
330
- ResultPlaceholder (lhs, freshId(), handlerCtx.isHandlerMtd, c2, applyBlock(rest))
323
+ ResultPlaceholder (lhs, freshId(), c2, applyBlock(rest))
331
324
case Assign (lhs, c @ Instantiate (cls, args), rest) =>
332
325
val cls2 = applyPath(cls)
333
326
val args2 = args.mapConserve(applyPath)
334
327
val c2 = if (cls2 is cls) && (args2 is args) then c else Instantiate (cls2, args2)
335
- ResultPlaceholder (lhs, freshId(), handlerCtx.isHandlerMtd, c2, applyBlock(rest))
328
+ ResultPlaceholder (lhs, freshId(), c2, applyBlock(rest))
336
329
case _ => super .applyBlock(b)
337
330
override def applyResult2 (r : Result )(k : Result => Block ): Block = r match
338
331
case c @ Call (fun, args) if c.mayRaiseEffects =>
339
332
val res = freshTmp(" res" )
340
333
val fun2 = applyPath(fun)
341
334
val args2 = args.mapConserve(applyArg)
342
335
val c2 = if (fun2 is fun) && (args2 is args) then c else Call (fun2, args2)(c.isMlsFun, c.mayRaiseEffects)
343
- ResultPlaceholder (res, freshId(), handlerCtx.isHandlerMtd, c2, k(Value .Ref (res)))
336
+ ResultPlaceholder (res, freshId(), c2, k(Value .Ref (res)))
344
337
case c @ Instantiate (cls, args) =>
345
338
val res = freshTmp(" res" )
346
339
val cls2 = applyPath(cls)
347
340
val args2 = args.mapConserve(applyPath)
348
341
val c2 = if (cls2 is cls) && (args2 is args) then c else Instantiate (cls2, args2)
349
- ResultPlaceholder (res, freshId(), handlerCtx.isHandlerMtd, c2, k(Value .Ref (res)))
342
+ ResultPlaceholder (res, freshId(), c2, k(Value .Ref (res)))
350
343
case r => super .applyResult2(r)(k)
351
344
override def applyLam (lam : Value .Lam ): Value .Lam =
352
345
Value .Lam (lam.params, translateBlock(lam.body, functionHandlerCtx(s " Cont $$ lambda $$ " )))
@@ -389,21 +382,8 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
389
382
val sym = BlockMemberSymbol (s " handleBlock $$ " , Nil )
390
383
val lbl = freshTmp(" handlerBody" )
391
384
val lblLoop = freshTmp(" handlerLoop" )
392
- val tmp = freshTmp(" retCont" )
393
- def prepareBody (b : Block ): Block =
394
-
395
- val transform = new BlockTransformerShallow (SymbolSubst ()):
396
- override def applyBlock (b : Block ): Block =
397
- b match
398
- case Return (res, implct) =>
399
- // In case res is effectful, it will be handled in translateBlock
400
- Assign (tmp, res, Return (Instantiate (paths.retClsPath, tmp.asPath :: Nil ), implct))
401
- case HandleBlockReturn (res) =>
402
- Return (res, false )
403
- case _ => super .applyBlock(b)
404
- transform.applyBlock(b)
405
385
406
- val handlerBody = translateBlock(prepareBody( h.body) , HandlerCtx (false , false , false , true ,
386
+ val handlerBody = translateBlock(h.body, HandlerCtx (false , true ,
407
387
s " Cont $$ handleBlock $$ ${h.lhs.nme}$$ " , N , state => blockBuilder
408
388
.assignFieldN(state.res.contTrace.last, nextIdent, PureCall (state.cls, Value .Lit (Tree .IntLit (state.uid)) :: Nil ))
409
389
.ret(PureCall (paths.handleBlockImplPath, state.res :: h.lhs.asPath :: Nil ))))
@@ -437,7 +417,7 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
437
417
N , // no owner
438
418
sym, PlainParamList (Nil ) :: Nil , body)
439
419
440
- val result = Define (defn, ResultPlaceholder (h.res, freshId(), ! handlerCtx.isTopLevel, Call (sym.asPath, Nil )(true , true ), h.rest))
420
+ val result = Define (defn, ResultPlaceholder (h.res, freshId(), Call (sym.asPath, Nil )(true , true ), h.rest))
441
421
result
442
422
443
423
private def genContClass (b : Block )(using HandlerCtx ): Opt [ClsLikeDefn ] =
@@ -453,7 +433,7 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
453
433
val transform = new BlockTransformerShallow (SymbolSubst ()):
454
434
override def applyBlock (b : Block ): Block = b match
455
435
case Define (_ : (ClsLikeDefn | FunDefn ), rst) => applyBlock(rst)
456
- case ResultPlaceholder (res, uid, canRet, c, rest) =>
436
+ case ResultPlaceholder (res, uid, c, rest) =>
457
437
trivial = false
458
438
blockBuilder
459
439
.assign(res, c)
@@ -463,12 +443,6 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
463
443
ReturnCont (res, uid)
464
444
)
465
445
.chain(ResumptionPoint (res, uid, _))
466
- .staticif(canRet, _.ifthen(
467
- res.asPath,
468
- Case .Cls (paths.retClsSym, paths.retClsPath),
469
- blockBuilder
470
- .ret(if handlerCtx.shouldUnwrapRet then res.asPath.value else res.asPath)
471
- ))
472
446
.rest(applyBlock(rest))
473
447
case _ => super .applyBlock(b)
474
448
transform.applyBlock(b)
@@ -558,19 +532,14 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
558
532
private def genNormalBody (b : Block , clsSym : BlockMemberSymbol )(using HandlerCtx ): Block =
559
533
val transform = new BlockTransformerShallow (SymbolSubst ()):
560
534
override def applyBlock (b : Block ): Block = b match
561
- case ResultPlaceholder (res, uid, canRet, c, rest) =>
535
+ case ResultPlaceholder (res, uid, c, rest) =>
562
536
blockBuilder
563
537
.assign(res, c)
564
538
.ifthen(
565
539
res.asPath,
566
540
Case .Cls (paths.effectSigSym, paths.effectSigPath),
567
541
handlerCtx.linkAndHandle(LinkState (res.asPath, clsSym.asPath, uid))
568
542
)
569
- .staticif(canRet, _.ifthen(
570
- res.asPath,
571
- Case .Cls (paths.retClsSym, paths.retClsPath),
572
- blockBuilder.ret(if handlerCtx.shouldUnwrapRet then res.asPath.value else res.asPath)
573
- ))
574
543
.rest(applyBlock(rest))
575
544
case _ => super .applyBlock(b)
576
545
0 commit comments