diff options
-rw-r--r-- | lib/msil.jar.desired.sha1 | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala | 64 | ||||
-rw-r--r-- | src/msil/ch/epfl/lamp/compiler/msil/Assembly.java | 6 | ||||
-rw-r--r-- | src/msil/ch/epfl/lamp/compiler/msil/PEFile.java | 23 | ||||
-rw-r--r-- | src/msil/ch/epfl/lamp/compiler/msil/emit/ILGenerator.scala | 14 |
5 files changed, 60 insertions, 49 deletions
diff --git a/lib/msil.jar.desired.sha1 b/lib/msil.jar.desired.sha1 index 6a95abf8e6..7dd6b5d66b 100644 --- a/lib/msil.jar.desired.sha1 +++ b/lib/msil.jar.desired.sha1 @@ -1 +1 @@ -411bfee5f3b2b6bae5f6ac06f84b4f4624370492 ?msil.jar +58f64cd00399c724e7d526e5bdcbce3e2b79f78b ?msil.jar diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index a38916b8e4..d593a13d8b 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -108,14 +108,14 @@ abstract class GenMSIL extends SubComponent { val objParam = Array(MOBJECT) -// val toBool: MethodInfo = SystemConvert.GetMethod("ToBoolean", objParam) - val toSByte: MethodInfo = SystemConvert.GetMethod("ToSByte", objParam) - val toShort: MethodInfo = SystemConvert.GetMethod("ToInt16", objParam) - val toChar: MethodInfo = SystemConvert.GetMethod("ToChar", objParam) - val toInt: MethodInfo = SystemConvert.GetMethod("ToInt32", objParam) - val toLong: MethodInfo = SystemConvert.GetMethod("ToInt64", objParam) - val toFloat: MethodInfo = SystemConvert.GetMethod("ToSingle", objParam) - val toDouble: MethodInfo = SystemConvert.GetMethod("ToDouble", objParam) + val toBool: MethodInfo = SystemConvert.GetMethod("ToBoolean", objParam) // see comment in emitUnbox + val toSByte: MethodInfo = SystemConvert.GetMethod("ToSByte", objParam) + val toShort: MethodInfo = SystemConvert.GetMethod("ToInt16", objParam) + val toChar: MethodInfo = SystemConvert.GetMethod("ToChar", objParam) + val toInt: MethodInfo = SystemConvert.GetMethod("ToInt32", objParam) + val toLong: MethodInfo = SystemConvert.GetMethod("ToInt64", objParam) + val toFloat: MethodInfo = SystemConvert.GetMethod("ToSingle", objParam) + val toDouble: MethodInfo = SystemConvert.GetMethod("ToDouble", objParam) //val boxedUnit: FieldInfo = msilType(definitions.BoxedUnitModule.info).GetField("UNIT") val boxedUnit: FieldInfo = fields(definitions.BoxedUnit_UNIT) @@ -460,9 +460,8 @@ abstract class GenMSIL extends SubComponent { } private[GenMSIL] def ilasmFileName(iclass: IClass) : String = { - val singleBackslashed = iclass.cunit.source.file.toString - val doubleBackslashed = singleBackslashed.replace("\\", "\\\\") - doubleBackslashed + // method.sourceFile contains just the filename + iclass.cunit.source.file.toString.replace("\\", "\\\\") } private[GenMSIL] def genClass(iclass: IClass) { @@ -564,6 +563,10 @@ abstract class GenMSIL extends SubComponent { val labels: HashMap[BasicBlock, Label] = new HashMap() + /* when emitting .line, it's enough to include the full filename just once per method, thus reducing filesize. + * this scheme relies on the fact that the entry block is emitted first. */ + var dbFilenameSeen = false + def genCode(m: IMethod) { def makeLabels(blocks: List[BasicBlock]) = { @@ -587,6 +590,7 @@ abstract class GenMSIL extends SubComponent { // debug val MButNotL = (blocksInM.toSet) diff (blocksInL.toSet) // if non-empty, a jump to B fails to find a label for B (case CJUMP, case CZJUMP) // debug if(!MButNotL.isEmpty) { } + dbFilenameSeen = false genBlocks(linearization) // RETURN inside exception blocks are replaced by Leave. The target of the @@ -897,6 +901,7 @@ abstract class GenMSIL extends SubComponent { var previousWasNEW = false var lastLineNr: Int = 0 + var lastPos: Position = NoPosition // EndExceptionBlock must happen before MarkLabel because it adds the @@ -932,18 +937,24 @@ abstract class GenMSIL extends SubComponent { } for (instr <- block) { - val currentLineNr = try { - instr.pos.line - } catch { - case _: UnsupportedOperationException => - log("Warning: wrong position in: " + method) - lastLineNr - } - - if (currentLineNr != lastLineNr) { - mcode.setPosition(currentLineNr, ilasmFileName(clasz)) // method.sourceFile contains just the filename - lastLineNr = currentLineNr - } + try { + val currentLineNr = instr.pos.line + val skip = if(instr.pos.isRange) instr.pos.sameRange(lastPos) else (currentLineNr == lastLineNr); + if(!skip || !dbFilenameSeen) { + val fileName = if(dbFilenameSeen) "" else {dbFilenameSeen = true; ilasmFileName(clasz)}; + if(instr.pos.isRange) { + val startLine = instr.pos.focusStart.line + val endLine = instr.pos.focusEnd.line + val startCol = instr.pos.focusStart.column + val endCol = instr.pos.focusEnd.column + mcode.setPosition(startLine, endLine, startCol, endCol, fileName) + } else { + mcode.setPosition(instr.pos.line, fileName) + } + lastLineNr = currentLineNr + lastPos = instr.pos + } + } catch { case _: UnsupportedOperationException => () } if (previousWasNEW) assert(instr.isInstanceOf[DUP], block) @@ -2194,7 +2205,12 @@ abstract class GenMSIL extends SubComponent { def emitUnbox(code: ILGenerator, boxType: TypeKind) = (boxType: @unchecked) match { case UNIT => code.Emit(OpCodes.Pop) - case BOOL => code.Emit(OpCodes.Unbox, MBOOL); code.Emit(OpCodes.Ldind_I1) + /* (1) it's essential to keep the code emitted here (as of now plain calls to System.Convert.ToBlaBla methods) + behaviorally.equiv.wrt. BoxesRunTime.unboxToBlaBla methods + (case null: that's easy, case boxed: track changes to unboxBlaBla) + (2) See also: asInstanceOf to cast from Any to number, + tracked in http://lampsvn.epfl.ch/trac/scala/ticket/4437 */ + case BOOL => code.Emit(OpCodes.Call, toBool) case BYTE => code.Emit(OpCodes.Call, toSByte) case SHORT => code.Emit(OpCodes.Call, toShort) case CHAR => code.Emit(OpCodes.Call, toChar) diff --git a/src/msil/ch/epfl/lamp/compiler/msil/Assembly.java b/src/msil/ch/epfl/lamp/compiler/msil/Assembly.java index d2adf3750a..59bbeee3a4 100644 --- a/src/msil/ch/epfl/lamp/compiler/msil/Assembly.java +++ b/src/msil/ch/epfl/lamp/compiler/msil/Assembly.java @@ -45,13 +45,11 @@ public abstract class Assembly extends CustomAttributeProvider { // dir = dir.getCanonicalFile(); // } catch (java.io.IOException e) {} - if (name.endsWith(".exe") || name.endsWith(".EXE") || - name.endsWith(".dll") || name.endsWith(".DLL")) - { + if (name.toUpperCase().endsWith(".EXE") || name.toUpperCase().endsWith(".DLL")) { file = new File(dir, name); pefile = getPEFile(file); name = name.substring(0, name.length() - 4); - } + } File adir = pefile == null ? new File(dir, name) : null; diff --git a/src/msil/ch/epfl/lamp/compiler/msil/PEFile.java b/src/msil/ch/epfl/lamp/compiler/msil/PEFile.java index 481d5f2116..3eb22b9985 100644 --- a/src/msil/ch/epfl/lamp/compiler/msil/PEFile.java +++ b/src/msil/ch/epfl/lamp/compiler/msil/PEFile.java @@ -95,7 +95,7 @@ public class PEFile { /** Ecma 335, 25.2.1 MS-DOS header: * * "The PE format starts with an MS-DOS stub of exactly the following 128 bytes to - * be placed at the front of the module." + * be placed at the front of the module." * * We are only checking for MZ (Mark Zbikowski) */ @@ -107,13 +107,13 @@ public class PEFile { /** Ecma 335, 25.2.1 MS-DOS header: * * "At offset 0x3c in the DOS header is a 4-byte unsigned integer offset, lfanew, - * to the PE signature (shall be "PE\0\0"), immediately followed by the PE file header. + * to the PE signature (shall be "PE\0\0"), immediately followed by the PE file header." */ seek(0x3c); PE_SIGNATURE_OFFSET = readInt(); seek(PE_SIGNATURE_OFFSET); - + // start of PE signature (a signature that is just 4 bytes long) fileFormatCheck(readByte() != 0x50, "Invalid PE file format: " + filename); // 'P' fileFormatCheck(readByte() != 0x45, "Invalid PE file format: " + filename); // 'E' fileFormatCheck(readByte() != 0x00, "Invalid PE file format: " + filename); // 0 @@ -125,26 +125,19 @@ public class PEFile { PE_HEADER_OFFSET = COFF_HEADER_OFFSET + 20; seek(COFF_HEADER_OFFSET); - skip(2); - /** Ecma 335, 25.2.2: "Number of sections; indicates size of the Section Table" */ - numOfSections = readShort(); - //trace("Number of sections = " + numOfSections); - /** Ecma 335, 25.2.2: "Time and date the file was created in seconds since - * January 1st 1970 00:00:00 or 0." - */ + /* start of PE file header, Sec. 25.2.2 in Partition II */ + skip(2); // Machine (always 0x14c) + numOfSections = readShort(); // Number of sections; indicates size of the Section Table Date timeStamp = new Date(readInt() * 1000L); - //trace("Time stamp = " + timeStamp); - - skip(2 * INT_SIZE); + skip(2 * INT_SIZE); // skip Pointer to Symbol Table (always 0) and Number of Symbols (always 0) optHeaderSize = readShort(); int characteristics = readShort(); isDLL = (characteristics & 0x2000) != 0; - //trace("Characteristics = " + Integer.toHexString(characteristics)); seek(PE_HEADER_OFFSET + 208); // p.157, Partition II - CLI_RVA = readInt(); + CLI_RVA = readInt(); // called "Data Directory Table" in Ch. 4 of Expert IL book CLI_Length = readInt(); //trace("CLI_RVA = 0x" + Table.int2hex(CLI_RVA)); //trace("CLI_Length = 0x" + Table.int2hex(CLI_Length)); diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/ILGenerator.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/ILGenerator.scala index c7899c7f54..2223a6db0f 100644 --- a/src/msil/ch/epfl/lamp/compiler/msil/emit/ILGenerator.scala +++ b/src/msil/ch/epfl/lamp/compiler/msil/emit/ILGenerator.scala @@ -402,16 +402,20 @@ import ILGenerator._ * sets the line of the source file corresponding to the next instruction */ def setPosition(line: Int) { - if (line != 0) - lineNums.put(lastLabel, Integer.toString(line)) + if (line != 0) lineNums.put(lastLabel, Integer.toString(line)) } def setPosition(line: Int, filename: String) { - if (line != 0) - lineNums.put(lastLabel, line + " '" + filename + "'") + if (line != 0) lineNums.put(lastLabel, line + " '" + filename + "'") } - def getLocals(): Array[LocalBuilder] = localList.toArray + def setPosition(startLine: Int, endLine: Int, startCol: Int, endCol: Int, filename: String) { + val lineRange = startLine + "," + endLine + val colRange = startCol + "," + endCol + lineNums.put(lastLabel, lineRange + ":" + colRange + " '" + filename + "'") + } + + def getLocals(): Array[LocalBuilder] = localList.toArray def getLabelIterator() = labelList.iterator |