Skip to content

Commit ba993b1

Browse files
committed
update JVMGen to support initializer in LocalVarDef
1 parent 3f54988 commit ba993b1

File tree

2 files changed

+23
-20
lines changed

2 files changed

+23
-20
lines changed

src/main/scala/decaf/jvm/JVMGen.scala

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ class JVMGen extends Phase[Tree, List[JVMClass]]("jvm") with Util {
9090
def appendReturnIfNecessary(methodDef: MethodDef)(implicit mv: MethodVisitor): Unit = {
9191
if (!methodDef.returnType.typ.isVoidType) return
9292

93-
val stmts = methodDef.body.asInstanceOf[Block].stmts
93+
val stmts = methodDef.body.stmts
9494
if (stmts.isEmpty || !stmts.last.isInstanceOf[Return]) mv.visitInsn(Opcodes.RETURN)
9595
}
9696

97-
type LocalVars = mutable.HashMap[LocalVarSymbol, Int]
97+
type LocalVars = mutable.TreeMap[LocalVarSymbol, Int]
9898

9999
private class Context(isStatic: Boolean = true) {
100100
val index: LocalVars = new LocalVars
@@ -123,27 +123,29 @@ class JVMGen extends Phase[Tree, List[JVMClass]]("jvm") with Util {
123123
case v: LocalVarDef =>
124124
// JVM will complain if a local variable is read but not initialized yet. It also seems that when the local
125125
// variable is firstly initialized in a more inner scope rather than the outer most local scope, JVM reports
126-
// an error. To avoid these, let's simply initialize every user-defined local variable right now.
126+
// an error. To avoid these, let's simply initialize every user-defined local variable right now, in case
127+
// the user didn't.
127128
val index = ctx.declare(v.symbol)
128-
loadDefaultValue(v.typeLit.typ)
129+
v.init match {
130+
case Some(expr) => emitExpr(expr)
131+
case None => loadDefaultValue(v.typeLit.typ)
132+
}
129133
mv.visitVarInsn(storeOp(v.typeLit.typ), index)
130134

131-
case Assign(lhs, rhs) =>
132-
lhs match {
133-
case LocalVar(v) =>
134-
emitExpr(rhs)
135-
mv.visitVarInsn(storeOp(v.typ), ctx.index(v))
136-
case MemberVar(receiver, v) =>
137-
emitExpr(receiver)
138-
emitExpr(rhs)
139-
mv.visitFieldInsn(Opcodes.PUTFIELD, internalName(v.owner), v.name, descriptor(v))
140-
case IndexSel(array, index) =>
141-
emitExpr(array)
142-
emitExpr(index)
143-
emitExpr(rhs)
144-
val elemType = array.typ.asInstanceOf[ArrayType].elemType
145-
mv.visitInsn(arrayStoreOp(elemType))
146-
}
135+
case Assign(LocalVar(v), rhs) =>
136+
emitExpr(rhs)
137+
mv.visitVarInsn(storeOp(v.typ), ctx.index(v))
138+
case Assign(MemberVar(receiver, v), rhs) =>
139+
emitExpr(receiver)
140+
emitExpr(rhs)
141+
mv.visitFieldInsn(Opcodes.PUTFIELD, internalName(v.owner), v.name, descriptor(v))
142+
case Assign(IndexSel(array, index), rhs) =>
143+
emitExpr(array)
144+
emitExpr(index)
145+
emitExpr(rhs)
146+
val elemType = array.typ.asInstanceOf[ArrayType].elemType
147+
mv.visitInsn(arrayStoreOp(elemType))
148+
147149
case ExprEval(expr) => emitExpr(expr)
148150
case Skip() => // nop
149151

src/main/scala/decaf/tac/TacEmitter.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ trait TacEmitter {
4747
fv.visitAssign(ctx.vars(v), t)
4848

4949
case ExprEval(expr) => emitExpr(expr)
50+
case Skip() => // nop
5051

5152
case If(cond, trueBranch, falseBranch) =>
5253
val t = emitExpr(cond)

0 commit comments

Comments
 (0)