diff options
author | shack <shack@epfl.ch> | 2008-02-08 14:24:25 +0000 |
---|---|---|
committer | shack <shack@epfl.ch> | 2008-02-08 14:24:25 +0000 |
commit | baa83f11ee666ff98ddf20dd10a0e8c5a86ee220 (patch) | |
tree | 09f635873983814b227a7f524fb422e841ce16e3 | |
parent | 87e7a42076d6516e7d36426b47c788702b0d6689 (diff) | |
download | scala-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
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala | 25 |
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) } |