Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {

val hasElse = !elsep.isEmpty && (elsep match {
case Literal(value) if value.tag == UnitTag => false
case _ => true
case _ => true
})
val postIf = if (hasElse) new asm.Label else failure

Expand Down Expand Up @@ -308,6 +308,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
genReturn(r)
generatedType = expectedType

case t @ WhileDo(_, _) =>
generatedType = genWhileDo(t)

case t @ Try(_, _, _) =>
generatedType = genLoadTry(t)

Expand Down Expand Up @@ -599,6 +602,45 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
}
} // end of genReturn()

def genWhileDo(tree: WhileDo): BType = tree match{
case WhileDo(cond, body) =>

val isInfinite = cond match {
case Literal(value) if value.tag == BooleanTag => value.booleanValue
case _ => false
}

val loop = new asm.Label
markProgramPoint(loop)

if (isInfinite) {
genLoad(body, UNIT)
bc goTo loop
} else {
val hasBody = cond match {
case Literal(value) if value.tag == UnitTag => false
case _ => true
}

if (hasBody) {
val success = new asm.Label
val failure = new asm.Label
genCond(cond, success, failure, targetIfNoJump = success)
markProgramPoint(success)
genLoad(body, UNIT)
bc goTo loop
markProgramPoint(failure)
} else {
// this is the shape of do..while loops, so do something smart about them
val failure = new asm.Label
genCond(cond, loop, failure, targetIfNoJump = failure)
markProgramPoint(failure)
}
}

UNIT
}

def genTypeApply(t: TypeApply): BType = t match {
case TypeApply(fun@Select(obj, _), targs) =>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
type Throw >: Null <: Tree
type Labeled >: Null <: Tree
type Return >: Null <: Tree
type WhileDo >: Null <: Tree
type Literal >: Null <: Tree
type Block >: Null <: Tree
type Typed >: Null <: Tree
Expand Down Expand Up @@ -69,6 +70,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
implicit val ThrowTag: ClassTag[Throw]
implicit val LabeledTag: ClassTag[Labeled]
implicit val ReturnTag: ClassTag[Return]
implicit val WhileDoTag: ClassTag[WhileDo]
implicit val LiteralTag: ClassTag[Literal]
implicit val BlockTag: ClassTag[Block]
implicit val TypedTag: ClassTag[Typed]
Expand Down Expand Up @@ -205,6 +207,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
val Try: TryDeconstructor
val Labeled: LabeledDeconstructor
val Return: ReturnDeconstructor
val WhileDo: WhileDoDeconstructor
val LabelDef: LabelDeconstructor
val Literal: LiteralDeconstructor
val Typed: TypedDeconstrutor
Expand Down Expand Up @@ -302,6 +305,11 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
def _2: Symbol // target label, NoSymbol if return to method
}

abstract class WhileDoDeconstructor extends DeconstructorCommon[WhileDo]{
def _1: Tree // cond
def _2: Tree // body
}

abstract class ThrownException {
def unapply(a: Annotation): Option[Symbol]
}
Expand Down