@@ -1052,15 +1052,21 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1052
1052
varsInScope = Nil
1053
1053
stats foreach genStat
1054
1054
genLoadTo(expr, expectedType, dest)
1055
- val end = currProgramPoint()
1055
+ emitLocalVarScopes()
1056
+ varsInScope = savedScope
1057
+ }
1058
+
1059
+ /** Add entries to the `LocalVariableTable` JVM attribute for all the vars in
1060
+ * `varsInScope`, ending at the current program point.
1061
+ */
1062
+ def emitLocalVarScopes (): Unit =
1056
1063
if (emitVars) {
1057
- // add entries to LocalVariableTable JVM attribute
1064
+ val end = currProgramPoint()
1058
1065
for ((sym, start) <- varsInScope.reverse) {
1059
1066
emitLocalVarScope(sym, start, end)
1060
1067
}
1061
1068
}
1062
- varsInScope = savedScope
1063
- }
1069
+ end emitLocalVarScopes
1064
1070
1065
1071
def adapt (from : BType , to : BType ): Unit = {
1066
1072
if (! from.conformsTo(to)) {
@@ -1553,6 +1559,26 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1553
1559
loadAndTestBoolean()
1554
1560
}
1555
1561
1562
+ case Block (stats, expr) =>
1563
+ /* Push the decision further down the `expr`.
1564
+ * This is particularly effective for the shape of do..while loops.
1565
+ */
1566
+ val savedScope = varsInScope
1567
+ varsInScope = Nil
1568
+ stats foreach genStat
1569
+ genCond(expr, success, failure, targetIfNoJump)
1570
+ emitLocalVarScopes()
1571
+ varsInScope = savedScope
1572
+
1573
+ case If (condp, thenp, elsep) =>
1574
+ val innerSuccess = new asm.Label
1575
+ val innerFailure = new asm.Label
1576
+ genCond(condp, innerSuccess, innerFailure, targetIfNoJump = innerSuccess)
1577
+ markProgramPoint(innerSuccess)
1578
+ genCond(thenp, success, failure, targetIfNoJump = innerFailure)
1579
+ markProgramPoint(innerFailure)
1580
+ genCond(elsep, success, failure, targetIfNoJump)
1581
+
1556
1582
case _ => loadAndTestBoolean()
1557
1583
}
1558
1584
0 commit comments