diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2006-09-21 12:34:07 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2006-09-21 12:34:07 +0000 |
commit | 655a7f3801818e3630de4916097d46dbd8a97da3 (patch) | |
tree | 74c5a3d8f5cbdd1b9bc9bf9ddd29be6ee1300252 | |
parent | 3101d1577ea0309057bbe3abb1976099baa00dda (diff) | |
download | scala-655a7f3801818e3630de4916097d46dbd8a97da3.tar.gz scala-655a7f3801818e3630de4916097d46dbd8a97da3.tar.bz2 scala-655a7f3801818e3630de4916097d46dbd8a97da3.zip |
Added a local variable for closures' apply meth...
Added a local variable for closures' apply method which points to the outer instance (which appears in Scala source as 'this') -- only for -g:vars and above
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index f4ad9a4add..26275056df 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -415,13 +415,31 @@ abstract class GenJVM extends SubComponent { } if (!jmethod.isAbstract()) { + jcode = jmethod.getCode().asInstanceOf[JExtendedCode] + + // add a fake local for debugging purpuses + if (emitVars && isClosureApply(method.symbol)) { + val outerField = clasz.symbol.info.decl(nme.getterToLocal(nme.OUTER)); + if (outerField != NoSymbol) { + log("Adding fake local to represent outer 'this' for closure " + clasz); + val _this = new Local(method.symbol.newVariable(positionConfiguration.NoPos, "this$"), toTypeKind(outerField.tpe), false); + m.locals = m.locals ::: List(_this); + computeLocalVarsIndex(m) // since we added a new local, we need to recompute indexes + + jcode.emitALOAD_0; + jcode.emitGETFIELD(javaName(clasz.symbol), + javaName(outerField), + javaType(outerField)); + jcode.emitSTORE(indexOf(_this), javaType(_this.kind)); + } + } + for (val local <- m.locals; (! m.params.contains(local))) { if (settings.debug.value) log("add local var: " + local); jmethod.addNewLocalVariable(javaType(local.kind), javaName(local.sym)); } - jcode = jmethod.getCode().asInstanceOf[JExtendedCode] genCode(m) if (emitVars) genLocalVariableTable(m); @@ -432,6 +450,15 @@ abstract class GenJVM extends SubComponent { addParamAnnotations(m.params.map(.sym.attributes)) } + def isClosureApply(sym: Symbol): Boolean = { + (sym.name == nme.apply) && + sym.owner.hasFlag(Flags.SYNTHETIC) && + sym.owner.tpe.parents.exists { t => + val TypeRef(_, sym, _) = t; + definitions.FunctionClass exists sym.== + } + } + def addModuleInstanceField: Unit = { import JAccessFlags._ jclass.addNewField(ACC_PUBLIC | ACC_FINAL | ACC_STATIC, @@ -782,6 +809,7 @@ abstract class GenJVM extends SubComponent { val tagArray = new Array[Array[Int]](tags.length) var caze = tags var i = 0 + while (i < tagArray.length) { tagArray(i) = new Array[Int](caze.head.length) caze.head.copyToArray(tagArray(i), 0) |