summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorshack <shack@epfl.ch>2008-02-08 14:24:25 +0000
committershack <shack@epfl.ch>2008-02-08 14:24:25 +0000
commitbaa83f11ee666ff98ddf20dd10a0e8c5a86ee220 (patch)
tree09f635873983814b227a7f524fb422e841ce16e3 /src
parent87e7a42076d6516e7d36426b47c788702b0d6689 (diff)
downloadscala-baa83f11ee666ff98ddf20dd10a0e8c5a86ee220.tar.gz
scala-baa83f11ee666ff98ddf20dd10a0e8c5a86ee220.tar.bz2
scala-baa83f11ee666ff98ddf20dd10a0e8c5a86ee220.zip
Fixed several issues in the MSIL backend
predef.dll does now 'peverify' under .NET 3.5 * Method visibility (protected cannot be mapped to family) When implementing methods from traits the visibility must be public (the methods of the interface generated from the trait are already public) * Nested exception handler flaws * Static calls replaced by virtual calls (it seemed to be possible in earlier versions of the .NET framework to call virtual methods using 'call' instead of 'callvirt') * Calls to the static comparator function (see Comparator.cs in the dotnet-library) were broken. Comparator::equals(object) was always called instead
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala25
2 files changed, 19 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index be79d93483..4b510100e6 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -47,7 +47,7 @@ abstract class GenICode extends SubComponent {
if (!forMSIL)
definitions.getMember(definitions.BoxesRunTimeClass, nme.equals_)
else
- definitions.getMember(definitions.getClass("scala.runtime.Comparator"), nme.equals_)
+ definitions.getMember(definitions.getClass("scala.runtime.Comparator").linkedModuleOfClass, nme.equals_)
override def run {
scalaPrimitives.init
diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
index fae7800d0f..ed7e1cefc8 100644
--- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
+++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
@@ -600,7 +600,6 @@ abstract class GenMSIL extends SubComponent {
var needAdditionalRet: Boolean = false
def genCode(m: IMethod) {
-
code = m.code
labels.clear
@@ -929,7 +928,7 @@ abstract class GenMSIL extends SubComponent {
def replaceJump(block: BasicBlock, from: BasicBlock, to: BasicBlock) = block.lastInstruction match {
case JUMP(whereto) =>
//assert(from == whereto)
- block.replaceInstruction(block.lastInstruction, JUMP(to))
+ block.replaceInstruction(block.lastInstruction, JUMP(to))
case CJUMP(success, failure, cond, kind) =>
if (from == success)
block.replaceInstruction(block.lastInstruction, CJUMP(to, failure, cond, kind))
@@ -948,6 +947,13 @@ abstract class GenMSIL extends SubComponent {
val newLabels = labels.map(b => if (b == from) to else b)
assert(newLabels.contains(to))
block.replaceInstruction(block.lastInstruction, SWITCH(tags, newLabels))
+ /*
+ case RETURN(kind) =>
+ if (kind != UNIT) {
+ returnVal
+ }
+ block.replaceInstruction(block.lastInstructionm JUMP(to))
+ */
case _ => () //abort("expected branch at the end of block " + block)
}
@@ -993,15 +999,16 @@ abstract class GenMSIL extends SubComponent {
affectedHandlers = h :: affectedHandlers
}
})
- affectedHandlers = affectedHandlers.filter(h => {h.covered.length == affectedHandlers(0).covered.length})
- untreatedHandlers = untreatedHandlers.diff(affectedHandlers)
// shorter try-catch-finally last (the ones contained in another)
affectedHandlers = affectedHandlers.sort({(h1, h2) => h1.covered.length > h2.covered.length})
+ affectedHandlers = affectedHandlers.filter(h => {h.covered.length == affectedHandlers(0).covered.length})
+ untreatedHandlers = untreatedHandlers.diff(affectedHandlers)
// more than one catch produces more than one exh, but we only need one
var singleAffectedHandler: ExceptionHandler = affectedHandlers(0) // List[ExceptionHandler] = Nil
var exceptionBlock: Option[ExceptionBlock] = None
+ if (settings.debug.value) log("affected handlers " + affectedHandlers)
affectedHandlers.foreach(h1 => {
val (adaptedBlocks, newBlock) = adaptBlocks(blocksToPut.intersect(h1.blocks), singleAffectedHandler)
newBlock match {
@@ -1030,6 +1037,7 @@ abstract class GenMSIL extends SubComponent {
case None => ()
}
currentBlock = excBlock.tryBlock
+ if (settings.debug.value) log("adding try blocks " + tryBlocks)
addBlocks(tryBlocks)
if (singleAffectedHandler.finalizer != null && singleAffectedHandler.finalizer != NoFinalizer) {
@@ -1079,7 +1087,7 @@ abstract class GenMSIL extends SubComponent {
TopBlock.close()
if (settings.debug.value) log("TopBlock tree is: ")
- if (settings.debug.value) Console.println(TopBlock)
+ if (settings.debug.value) log(TopBlock)
bb2exHInstructions.clear
def addExHInstruction(b: BasicBlock, ehi: ExHInstruction) = {
@@ -1109,6 +1117,10 @@ abstract class GenMSIL extends SubComponent {
for (b <- cb.blocks) flatten(b)
case eb: ExceptionBlock =>
val handler = eb.handler
+ if (settings.debug.value) {
+ log("new exception block " + eb)
+ log("try: " + eb.tryBlock)
+ }
addExHInstruction(eb.tryBlock.firstBasicBlock, new BeginExceptionBlock(handler))
omitJump(eb.tryBlock.lastBasicBlock)
flatten(eb.tryBlock)
@@ -1869,7 +1881,6 @@ abstract class GenMSIL extends SubComponent {
def msilMethodFlags(sym: Symbol): Short = {
var mf: Int = MethodAttributes.HideBySig |
(if (sym hasFlag Flags.PRIVATE) MethodAttributes.Private
- else if (sym hasFlag Flags.PROTECTED) MethodAttributes.Family
else MethodAttributes.Public)
if (!sym.isClassConstructor) {
@@ -2217,7 +2228,7 @@ abstract class GenMSIL extends SubComponent {
mirrorCode.Emit(OpCodes.Ldsfld, getModuleInstanceField(sym))
0.until(paramTypes.length) foreach loadArg(mirrorCode)
- mirrorCode.Emit(OpCodes.Call, getMethod(m))
+ mirrorCode.Emit(OpCodes.Callvirt, getMethod(m))
mirrorCode.Emit(OpCodes.Ret)
}