1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
/* NSC -- new Scala compiler
* Copyright 2005-2011 LAMP/EPFL
* @author Paul Phillips
*/
package scala.tools.nsc
package backend
import ch.epfl.lamp.compiler.{ msil => msillib }
import util.{ ClassPath, MsilClassPath }
import msil.GenMSIL
import io.{ AbstractFile, MsilFile }
trait MSILPlatform extends Platform {
import global._
import definitions.{ ComparatorClass, BoxedNumberClass, getMember }
type BinaryRepr = MsilFile
if (settings.verbose.value)
inform("[AssemRefs = " + settings.assemrefs.value + "]")
// phaseName = "msil"
object genMSIL extends {
val global: MSILPlatform.this.global.type = MSILPlatform.this.global
val runsAfter = List[String]("dce")
val runsRightAfter = None
} with GenMSIL
lazy val classPath = MsilClassPath.fromSettings(settings)
def rootLoader = new loaders.PackageLoader(classPath.asInstanceOf[ClassPath[platform.BinaryRepr]])
// See discussion in JavaPlatForm for why we need a cast here.
/** Update classpath with a substituted subentry */
def updateClassPath(oldEntry: ClassPath[BinaryRepr], newEntry: ClassPath[BinaryRepr]) =
throw new UnsupportedOperationException("classpath invalidations not supported on MSIL")
def platformPhases = List(
genMSIL // generate .msil files
)
lazy val externalEquals = getMember(ComparatorClass.companionModule, nme.equals_)
def isMaybeBoxed(sym: Symbol) = sym isNonBottomSubClass BoxedNumberClass
def newClassLoader(bin: MsilFile): loaders.SymbolLoader = new loaders.MsilFileLoader(bin)
/**
* Tells whether a class should be loaded and entered into the package
* scope. On .NET, this method returns `false` for all synthetic classes
* (anonymous classes, implementation classes, module classes), their
* symtab is encoded in the pickle of another class.
*/
def doLoad(cls: ClassPath[BinaryRepr]#ClassRep): Boolean = {
if (cls.binary.isDefined) {
val typ = cls.binary.get.msilType
if (typ.IsDefined(loaders.clrTypes.SCALA_SYMTAB_ATTR, false)) {
val attrs = typ.GetCustomAttributes(loaders.clrTypes.SCALA_SYMTAB_ATTR, false)
assert(attrs.length == 1, attrs.length)
val a = attrs(0).asInstanceOf[msillib.Attribute]
// symtab_constr takes a byte array argument (the pickle), i.e. typ has a pickle.
// otherwise, symtab_default_constr was used, which marks typ as scala-synthetic.
a.getConstructor() == loaders.clrTypes.SYMTAB_CONSTR
} else true // always load non-scala types
} else true // always load source
}
def needCompile(bin: MsilFile, src: AbstractFile) =
false // always use compiled file on .net
}
|