@@ -113,16 +113,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
113
113
}
114
114
}
115
115
116
- def genThrow (expr : Tree ): BType = {
116
+ def genThrow (expr : Tree ): Unit = {
117
117
val thrownKind = tpeTK(expr)
118
118
// `throw null` is valid although scala.Null (as defined in src/libray-aux) isn't a subtype of Throwable.
119
119
// Similarly for scala.Nothing (again, as defined in src/libray-aux).
120
120
assert(thrownKind.isNullType || thrownKind.isNothingType || thrownKind.asClassBType.isSubtypeOf(ThrowableReference ))
121
121
genLoad(expr, thrownKind)
122
122
lineNumber(expr)
123
123
emit(asm.Opcodes .ATHROW ) // ICode enters here into enterIgnoreMode, we'll rely instead on DCE at ClassNode level.
124
-
125
- RT_NOTHING // always returns the same, the invoker should know :)
126
124
}
127
125
128
126
/* Generate code for primitive arithmetic operations. */
@@ -319,13 +317,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
319
317
generatedType = expectedType
320
318
321
319
case t @ WhileDo (_, _) =>
322
- generatedType = genWhileDo(t)
320
+ generatedType = genWhileDo(t, expectedType )
323
321
324
322
case t @ Try (_, _, _) =>
325
323
generatedType = genLoadTry(t)
326
324
327
325
case t : Apply if t.fun.symbol eq defn.throwMethod =>
328
- generatedType = genThrow(t.args.head)
326
+ genThrow(t.args.head)
327
+ generatedType = expectedType
329
328
330
329
case New (tpt) =>
331
330
abort(s " Unexpected New( ${tpt.tpe.showSummary()}/ $tpt) reached GenBCode. \n " +
@@ -586,41 +585,47 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
586
585
}
587
586
} // end of genReturn()
588
587
589
- def genWhileDo (tree : WhileDo ): BType = tree match {
588
+ def genWhileDo (tree : WhileDo , expectedType : BType ): BType = tree match {
590
589
case WhileDo (cond, body) =>
591
590
592
591
val isInfinite = cond == tpd.EmptyTree
593
592
594
- val loop = new asm.Label
595
- markProgramPoint(loop)
596
-
597
- if (isInfinite) {
598
- genLoad(body, UNIT )
599
- bc goTo loop
600
- RT_NOTHING
601
- } else {
602
- val hasBody = cond match {
603
- case Literal (value) if value.tag == UnitTag => false
604
- case _ => true
605
- }
606
-
607
- if (hasBody) {
608
- val success = new asm.Label
609
- val failure = new asm.Label
610
- genCond(cond, success, failure, targetIfNoJump = success)
611
- markProgramPoint(success)
612
- genLoad(body, UNIT )
613
- bc goTo loop
614
- markProgramPoint(failure)
615
- } else {
616
- // this is the shape of do..while loops, so do something smart about them
617
- val failure = new asm.Label
618
- genCond(cond, loop, failure, targetIfNoJump = failure)
619
- markProgramPoint(failure)
620
- }
621
-
593
+ if isInfinite then
594
+ body match
595
+ case Labeled (bind, expr) if tpeTK(body) == UNIT =>
596
+ // this is the shape of tailrec methods
597
+ val loop = programPoint(bind.symbol)
598
+ markProgramPoint(loop)
599
+ genLoad(expr, UNIT )
600
+ bc goTo loop
601
+ case _ =>
602
+ val loop = new asm.Label
603
+ markProgramPoint(loop)
604
+ genLoad(body, UNIT )
605
+ bc goTo loop
606
+ end match
607
+ expectedType
608
+ else
609
+ body match
610
+ case Literal (value) if value.tag == UnitTag =>
611
+ // this is the shape of do..while loops
612
+ val loop = new asm.Label
613
+ markProgramPoint(loop)
614
+ val exitLoop = new asm.Label
615
+ genCond(cond, loop, exitLoop, targetIfNoJump = exitLoop)
616
+ markProgramPoint(exitLoop)
617
+ case _ =>
618
+ val loop = new asm.Label
619
+ val success = new asm.Label
620
+ val failure = new asm.Label
621
+ markProgramPoint(loop)
622
+ genCond(cond, success, failure, targetIfNoJump = success)
623
+ markProgramPoint(success)
624
+ genLoad(body, UNIT )
625
+ bc goTo loop
626
+ markProgramPoint(failure)
627
+ end match
622
628
UNIT
623
- }
624
629
}
625
630
626
631
def genTypeApply (t : TypeApply ): BType = (t : @ unchecked) match {
0 commit comments