summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-02-04 21:06:42 -0800
committerPaul Phillips <paulp@improving.org>2012-02-04 21:10:51 -0800
commit6ba9411c7c6abdbd907ca93208ac58b474b201d0 (patch)
tree614eeef46130287f58da14ec1b8aa6c35853cfef /src/compiler
parentdcb5fe93162fcf7112d95733ecb78075dbd34f90 (diff)
downloadscala-6ba9411c7c6abdbd907ca93208ac58b474b201d0.tar.gz
scala-6ba9411c7c6abdbd907ca93208ac58b474b201d0.tar.bz2
scala-6ba9411c7c6abdbd907ca93208ac58b474b201d0.zip
Restored msil.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/backend/MSILPlatform.scala11
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala322
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala114
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala13
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala25
-rw-r--r--src/compiler/scala/tools/nsc/io/MsilFile.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala32
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala15
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala165
-rw-r--r--src/compiler/scala/tools/nsc/util/MsilClassPath.scala21
10 files changed, 359 insertions, 364 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/MSILPlatform.scala b/src/compiler/scala/tools/nsc/backend/MSILPlatform.scala
index d5a02f9242..65b1fbc229 100644
--- a/src/compiler/scala/tools/nsc/backend/MSILPlatform.scala
+++ b/src/compiler/scala/tools/nsc/backend/MSILPlatform.scala
@@ -6,12 +6,12 @@
package scala.tools.nsc
package backend
-// import ch.epfl.lamp.compiler.{ msil => msillib }
-// import util.{ ClassPath, MsilClassPath }
-// import msil.GenMSIL
-// import io.{ AbstractFile, MsilFile }
+import ch.epfl.lamp.compiler.{ msil => msillib }
+import util.{ ClassPath, MsilClassPath }
+import msil.GenMSIL
+import io.{ AbstractFile, MsilFile }
-trait MSILPlatform /*extends Platform {
+trait MSILPlatform extends Platform {
import global._
import definitions.{ ComparatorClass, BoxedNumberClass, getMember }
@@ -63,4 +63,3 @@ trait MSILPlatform /*extends Platform {
def needCompile(bin: MsilFile, src: AbstractFile) =
false // always use compiled file on .net
}
-*/ \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index acb20b4627..3baff7da9e 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -160,8 +160,8 @@ abstract class GenICode extends SubComponent {
case Assign(lhs @ Select(_, _), rhs) =>
val isStatic = lhs.symbol.isStaticMember
var ctx1 = if (isStatic) ctx
- // else if (forMSIL && msil_IsValuetypeInstField(lhs.symbol))
- // msil_genLoadQualifierAddress(lhs, ctx)
+ else if (forMSIL && msil_IsValuetypeInstField(lhs.symbol))
+ msil_genLoadQualifierAddress(lhs, ctx)
else genLoadQualifier(lhs, ctx)
ctx1 = genLoad(rhs, ctx1, toTypeKind(lhs.symbol.info))
@@ -460,132 +460,132 @@ abstract class GenICode extends SubComponent {
fun.symbol.simpleName + ") " + " at: " + (tree.pos)
)
}
- //
- // /**
- // * forMSIL
- // */
- // private def msil_IsValuetypeInstMethod(msym: Symbol) = (
- // loaders.clrTypes.methods get msym exists (mMSIL =>
- // mMSIL.IsInstance && mMSIL.DeclaringType.IsValueType
- // )
- // )
- // private def msil_IsValuetypeInstField(fsym: Symbol) = (
- // loaders.clrTypes.fields get fsym exists (fMSIL =>
- // !fMSIL.IsStatic && fMSIL.DeclaringType.IsValueType
- // )
- // )
- //
- // /**
- // * forMSIL: Adds a local var, the emitted code requires one more slot on the stack as on entry
- // */
- // private def msil_genLoadZeroOfNonEnumValuetype(ctx: Context, kind: TypeKind, pos: Position, leaveAddressOnStackInstead: Boolean) {
- // val REFERENCE(clssym) = kind
- // assert(loaders.clrTypes.isNonEnumValuetype(clssym), clssym)
- // val local = ctx.makeLocal(pos, clssym.tpe, "tmp")
- // ctx.method.addLocal(local)
- // ctx.bb.emit(CIL_LOAD_LOCAL_ADDRESS(local), pos)
- // ctx.bb.emit(CIL_INITOBJ(kind), pos)
- // val instr = if (leaveAddressOnStackInstead)
- // CIL_LOAD_LOCAL_ADDRESS(local)
- // else
- // LOAD_LOCAL(local)
- // ctx.bb.emit(instr, pos)
- // }
- //
- // /**
- // * forMSIL
- // */
- // private def msil_genLoadAddressOf(tree: Tree, ctx: Context, expectedType: TypeKind, butRawValueIsAlsoGoodEnough: Boolean): Context = {
- // var generatedType = expectedType
- // var addressTaken = false
- // debuglog("at line: " + (if (tree.pos.isDefined) tree.pos.line else tree.pos))
- //
- // var resCtx: Context = tree match {
- //
- // // emits CIL_LOAD_FIELD_ADDRESS
- // case Select(qualifier, selector) if (!tree.symbol.isModule) =>
- // addressTaken = true
- // val sym = tree.symbol
- // generatedType = toTypeKind(sym.info)
- //
- // if (sym.isStaticMember) {
- // ctx.bb.emit(CIL_LOAD_FIELD_ADDRESS(sym, true), tree.pos)
- // ctx
- // } else {
- // val ctx1 = genLoadQualifier(tree, ctx)
- // ctx1.bb.emit(CIL_LOAD_FIELD_ADDRESS(sym, false), tree.pos)
- // ctx1
- // }
- //
- // // emits CIL_LOAD_LOCAL_ADDRESS
- // case Ident(name) if (!tree.symbol.isPackage && !tree.symbol.isModule)=>
- // addressTaken = true
- // val sym = tree.symbol
- // try {
- // val Some(l) = ctx.method.lookupLocal(sym)
- // ctx.bb.emit(CIL_LOAD_LOCAL_ADDRESS(l), tree.pos)
- // generatedType = l.kind // actually, should be "V&" but the callsite is aware of this
- // } catch {
- // case ex: MatchError =>
- // abort("symbol " + sym + " does not exist in " + ctx.method)
- // }
- // ctx
- //
- // // emits CIL_LOAD_ARRAY_ITEM_ADDRESS
- // case Apply(fun, args) =>
- // if (isPrimitive(fun.symbol)) {
- //
- // val sym = tree.symbol
- // val Apply(fun @ Select(receiver, _), args) = tree
- // val code = scalaPrimitives.getPrimitive(sym, receiver.tpe)
- //
- // if (isArrayOp(code)) {
- // val arrayObj = receiver
- // val k = toTypeKind(arrayObj.tpe)
- // val ARRAY(elementType) = k
- // if (scalaPrimitives.isArrayGet(code)) {
- // var ctx1 = genLoad(arrayObj, ctx, k)
- // // load argument on stack
- // debugassert(args.length == 1, "Too many arguments for array get operation: " + tree)
- // ctx1 = genLoad(args.head, ctx1, INT)
- // generatedType = elementType // actually "managed pointer to element type" but the callsite is aware of this
- // ctx1.bb.emit(CIL_LOAD_ARRAY_ITEM_ADDRESS(elementType), tree.pos)
- // addressTaken = true
- // ctx1
- // } else null
- // } else null
- // } else null
- //
- // case This(qual) =>
- // /* TODO: this case handler is a placeholder for the time when Level 2 support for valuetypes is in place,
- // in particular when invoking other methods on this where this is a valuetype value (boxed or not).
- // As receiver, a managed pointer is expected, and a plain ldarg.0 achieves just that. */
- // addressTaken = true
- // genLoad(tree, ctx, expectedType)
- //
- // case _ =>
- // null /* A method returning ByRef won't pass peverify, so I guess this case handler is dead code.
- // Even if it's not, the code below to handler !addressTaken below. */
- // }
- //
- // if (!addressTaken) {
- // resCtx = genLoad(tree, ctx, expectedType)
- // if (!butRawValueIsAlsoGoodEnough) {
- // // raw value on stack (must be an intermediate result, e.g. returned by method call), take address
- // addressTaken = true
- // val boxType = expectedType // toTypeKind(expectedType /* TODO FIXME */)
- // resCtx.bb.emit(BOX(boxType), tree.pos)
- // resCtx.bb.emit(CIL_UNBOX(boxType), tree.pos)
- // }
- // }
- //
- // // emit conversion
- // if (generatedType != expectedType)
- // abort("Unexpected tree in msil_genLoadAddressOf: " + tree + " at: " + tree.pos)
- //
- // resCtx
- // }
- //
+
+ /**
+ * forMSIL
+ */
+ private def msil_IsValuetypeInstMethod(msym: Symbol) = (
+ loaders.clrTypes.methods get msym exists (mMSIL =>
+ mMSIL.IsInstance && mMSIL.DeclaringType.IsValueType
+ )
+ )
+ private def msil_IsValuetypeInstField(fsym: Symbol) = (
+ loaders.clrTypes.fields get fsym exists (fMSIL =>
+ !fMSIL.IsStatic && fMSIL.DeclaringType.IsValueType
+ )
+ )
+
+ /**
+ * forMSIL: Adds a local var, the emitted code requires one more slot on the stack as on entry
+ */
+ private def msil_genLoadZeroOfNonEnumValuetype(ctx: Context, kind: TypeKind, pos: Position, leaveAddressOnStackInstead: Boolean) {
+ val REFERENCE(clssym) = kind
+ assert(loaders.clrTypes.isNonEnumValuetype(clssym), clssym)
+ val local = ctx.makeLocal(pos, clssym.tpe, "tmp")
+ ctx.method.addLocal(local)
+ ctx.bb.emit(CIL_LOAD_LOCAL_ADDRESS(local), pos)
+ ctx.bb.emit(CIL_INITOBJ(kind), pos)
+ val instr = if (leaveAddressOnStackInstead)
+ CIL_LOAD_LOCAL_ADDRESS(local)
+ else
+ LOAD_LOCAL(local)
+ ctx.bb.emit(instr, pos)
+ }
+
+ /**
+ * forMSIL
+ */
+ private def msil_genLoadAddressOf(tree: Tree, ctx: Context, expectedType: TypeKind, butRawValueIsAlsoGoodEnough: Boolean): Context = {
+ var generatedType = expectedType
+ var addressTaken = false
+ debuglog("at line: " + (if (tree.pos.isDefined) tree.pos.line else tree.pos))
+
+ var resCtx: Context = tree match {
+
+ // emits CIL_LOAD_FIELD_ADDRESS
+ case Select(qualifier, selector) if (!tree.symbol.isModule) =>
+ addressTaken = true
+ val sym = tree.symbol
+ generatedType = toTypeKind(sym.info)
+
+ if (sym.isStaticMember) {
+ ctx.bb.emit(CIL_LOAD_FIELD_ADDRESS(sym, true), tree.pos)
+ ctx
+ } else {
+ val ctx1 = genLoadQualifier(tree, ctx)
+ ctx1.bb.emit(CIL_LOAD_FIELD_ADDRESS(sym, false), tree.pos)
+ ctx1
+ }
+
+ // emits CIL_LOAD_LOCAL_ADDRESS
+ case Ident(name) if (!tree.symbol.isPackage && !tree.symbol.isModule)=>
+ addressTaken = true
+ val sym = tree.symbol
+ try {
+ val Some(l) = ctx.method.lookupLocal(sym)
+ ctx.bb.emit(CIL_LOAD_LOCAL_ADDRESS(l), tree.pos)
+ generatedType = l.kind // actually, should be "V&" but the callsite is aware of this
+ } catch {
+ case ex: MatchError =>
+ abort("symbol " + sym + " does not exist in " + ctx.method)
+ }
+ ctx
+
+ // emits CIL_LOAD_ARRAY_ITEM_ADDRESS
+ case Apply(fun, args) =>
+ if (isPrimitive(fun.symbol)) {
+
+ val sym = tree.symbol
+ val Apply(fun @ Select(receiver, _), args) = tree
+ val code = scalaPrimitives.getPrimitive(sym, receiver.tpe)
+
+ if (isArrayOp(code)) {
+ val arrayObj = receiver
+ val k = toTypeKind(arrayObj.tpe)
+ val ARRAY(elementType) = k
+ if (scalaPrimitives.isArrayGet(code)) {
+ var ctx1 = genLoad(arrayObj, ctx, k)
+ // load argument on stack
+ debugassert(args.length == 1, "Too many arguments for array get operation: " + tree)
+ ctx1 = genLoad(args.head, ctx1, INT)
+ generatedType = elementType // actually "managed pointer to element type" but the callsite is aware of this
+ ctx1.bb.emit(CIL_LOAD_ARRAY_ITEM_ADDRESS(elementType), tree.pos)
+ addressTaken = true
+ ctx1
+ } else null
+ } else null
+ } else null
+
+ case This(qual) =>
+ /* TODO: this case handler is a placeholder for the time when Level 2 support for valuetypes is in place,
+ in particular when invoking other methods on this where this is a valuetype value (boxed or not).
+ As receiver, a managed pointer is expected, and a plain ldarg.0 achieves just that. */
+ addressTaken = true
+ genLoad(tree, ctx, expectedType)
+
+ case _ =>
+ null /* A method returning ByRef won't pass peverify, so I guess this case handler is dead code.
+ Even if it's not, the code below to handler !addressTaken below. */
+ }
+
+ if (!addressTaken) {
+ resCtx = genLoad(tree, ctx, expectedType)
+ if (!butRawValueIsAlsoGoodEnough) {
+ // raw value on stack (must be an intermediate result, e.g. returned by method call), take address
+ addressTaken = true
+ val boxType = expectedType // toTypeKind(expectedType /* TODO FIXME */)
+ resCtx.bb.emit(BOX(boxType), tree.pos)
+ resCtx.bb.emit(CIL_UNBOX(boxType), tree.pos)
+ }
+ }
+
+ // emit conversion
+ if (generatedType != expectedType)
+ abort("Unexpected tree in msil_genLoadAddressOf: " + tree + " at: " + tree.pos)
+
+ resCtx
+ }
+
/**
* Generate code for trees that produce values on the stack
@@ -793,19 +793,19 @@ abstract class GenICode extends SubComponent {
debugassert(ctor.owner == cls,
"Symbol " + ctor.owner.fullName + " is different than " + tpt)
- // val ctx2 = if (forMSIL && loaders.clrTypes.isNonEnumValuetype(cls)) {
- // /* parameterful constructors are the only possible custom constructors,
- // a default constructor can't be defined for valuetypes, CLR dixit */
- // val isDefaultConstructor = args.isEmpty
- // if (isDefaultConstructor) {
- // msil_genLoadZeroOfNonEnumValuetype(ctx, rt, tree.pos, leaveAddressOnStackInstead = false)
- // ctx
- // } else {
- // val ctx1 = genLoadArguments(args, ctor.info.paramTypes, ctx)
- // ctx1.bb.emit(CIL_NEWOBJ(ctor), tree.pos)
- // ctx1
- // }
- // } else {
+ val ctx2 = if (forMSIL && loaders.clrTypes.isNonEnumValuetype(cls)) {
+ /* parameterful constructors are the only possible custom constructors,
+ a default constructor can't be defined for valuetypes, CLR dixit */
+ val isDefaultConstructor = args.isEmpty
+ if (isDefaultConstructor) {
+ msil_genLoadZeroOfNonEnumValuetype(ctx, rt, tree.pos, leaveAddressOnStackInstead = false)
+ ctx
+ } else {
+ val ctx1 = genLoadArguments(args, ctor.info.paramTypes, ctx)
+ ctx1.bb.emit(CIL_NEWOBJ(ctor), tree.pos)
+ ctx1
+ }
+ } else {
val nw = NEW(rt)
ctx.bb.emit(nw, tree.pos)
ctx.bb.emit(DUP(generatedType))
@@ -815,8 +815,8 @@ abstract class GenICode extends SubComponent {
nw.init = init
ctx1.bb.emit(init, tree.pos)
ctx1
- // }
- // ctx2
+ }
+ ctx2
case _ =>
abort("Cannot instantiate " + tpt + "of kind: " + generatedType)
@@ -845,12 +845,12 @@ abstract class GenICode extends SubComponent {
generatedType = boxType
ctx1.bb.emit(UNBOX(boxType), expr.pos)
ctx1
- //
- // case Apply(fun @ _, List(expr)) if (forMSIL && loaders.clrTypes.isAddressOf(fun.symbol)) =>
- // debuglog("ADDRESSOF : " + fun.symbol.fullName);
- // val ctx1 = msil_genLoadAddressOf(expr, ctx, toTypeKind(expr.tpe), butRawValueIsAlsoGoodEnough = false)
- // generatedType = toTypeKind(fun.symbol.tpe.resultType)
- // ctx1
+
+ case Apply(fun @ _, List(expr)) if (forMSIL && loaders.clrTypes.isAddressOf(fun.symbol)) =>
+ debuglog("ADDRESSOF : " + fun.symbol.fullName);
+ val ctx1 = msil_genLoadAddressOf(expr, ctx, toTypeKind(expr.tpe), butRawValueIsAlsoGoodEnough = false)
+ generatedType = toTypeKind(fun.symbol.tpe.resultType)
+ ctx1
case app @ Apply(fun, args) =>
val sym = fun.symbol
@@ -887,9 +887,9 @@ abstract class GenICode extends SubComponent {
var ctx1 =
if (invokeStyle.hasInstance) {
- // if (forMSIL && !(invokeStyle.isInstanceOf[SuperCall]) && msil_IsValuetypeInstMethod(sym))
- // msil_genLoadQualifierAddress(fun, ctx)
- // else
+ if (forMSIL && !(invokeStyle.isInstanceOf[SuperCall]) && msil_IsValuetypeInstMethod(sym))
+ msil_genLoadQualifierAddress(fun, ctx)
+ else
genLoadQualifier(fun, ctx)
} else ctx
@@ -1150,15 +1150,15 @@ abstract class GenICode extends SubComponent {
case _ =>
abort("Unknown qualifier " + tree)
}
- //
- // /** forMSIL */
- // private def msil_genLoadQualifierAddress(tree: Tree, ctx: Context): Context =
- // tree match {
- // case Select(qualifier, _) =>
- // msil_genLoadAddressOf(qualifier, ctx, toTypeKind(qualifier.tpe), butRawValueIsAlsoGoodEnough = false)
- // case _ =>
- // abort("Unknown qualifier " + tree)
- // }
+
+ /** forMSIL */
+ private def msil_genLoadQualifierAddress(tree: Tree, ctx: Context): Context =
+ tree match {
+ case Select(qualifier, _) =>
+ msil_genLoadAddressOf(qualifier, ctx, toTypeKind(qualifier.tpe), butRawValueIsAlsoGoodEnough = false)
+ case _ =>
+ abort("Unknown qualifier " + tree)
+ }
/**
* Generate code that loads args into label parameters.
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
index bf8580b903..2bcfb9d4a9 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
@@ -636,63 +636,63 @@ trait Opcodes { self: ICodes =>
// CLR backend
-//
-// case class CIL_LOAD_LOCAL_ADDRESS(local: Local) extends Instruction {
-// /** Returns a string representation of this instruction */
-// override def toString(): String = "CIL_LOAD_LOCAL_ADDRESS "+local //+isArgument?" (argument)":"";
-//
-// override def consumed = 0
-// override def produced = 1
-//
-// override def producedTypes = List(msil_mgdptr(local.kind))
-// }
-//
-// case class CIL_LOAD_FIELD_ADDRESS(field: Symbol, isStatic: Boolean) extends Instruction {
-// /** Returns a string representation of this instruction */
-// override def toString(): String =
-// "CIL_LOAD_FIELD_ADDRESS " + (if (isStatic) field.fullName else field.toString)
-//
-// override def consumed = if (isStatic) 0 else 1
-// override def produced = 1
-//
-// override def consumedTypes = if (isStatic) Nil else List(REFERENCE(field.owner));
-// override def producedTypes = List(msil_mgdptr(REFERENCE(field.owner)));
-// }
-//
-// case class CIL_LOAD_ARRAY_ITEM_ADDRESS(kind: TypeKind) extends Instruction {
-// /** Returns a string representation of this instruction */
-// override def toString(): String = "CIL_LOAD_ARRAY_ITEM_ADDRESS (" + kind + ")"
-//
-// override def consumed = 2
-// override def produced = 1
-//
-// override def consumedTypes = List(ARRAY(kind), INT)
-// override def producedTypes = List(msil_mgdptr(kind))
-// }
-//
-// case class CIL_UNBOX(valueType: TypeKind) extends Instruction {
-// override def toString(): String = "CIL_UNBOX " + valueType
-// override def consumed = 1
-// override def consumedTypes = ObjectReference :: Nil // actually consumes a 'boxed valueType'
-// override def produced = 1
-// override def producedTypes = List(msil_mgdptr(valueType))
-// }
-//
-// case class CIL_INITOBJ(valueType: TypeKind) extends Instruction {
-// override def toString(): String = "CIL_INITOBJ " + valueType
-// override def consumed = 1
-// override def consumedTypes = ObjectReference :: Nil // actually consumes a managed pointer
-// override def produced = 0
-// }
-//
-// case class CIL_NEWOBJ(method: Symbol) extends Instruction {
-// override def toString(): String = "CIL_NEWOBJ " + hostClass.fullName + method.fullName
-// var hostClass: Symbol = method.owner;
-// override def consumed = method.tpe.paramTypes.length
-// override def consumedTypes = method.tpe.paramTypes map toTypeKind
-// override def produced = 1
-// override def producedTypes = List(toTypeKind(method.tpe.resultType))
-// }
+
+ case class CIL_LOAD_LOCAL_ADDRESS(local: Local) extends Instruction {
+ /** Returns a string representation of this instruction */
+ override def toString(): String = "CIL_LOAD_LOCAL_ADDRESS "+local //+isArgument?" (argument)":"";
+
+ override def consumed = 0
+ override def produced = 1
+
+ override def producedTypes = List(msil_mgdptr(local.kind))
+ }
+
+ case class CIL_LOAD_FIELD_ADDRESS(field: Symbol, isStatic: Boolean) extends Instruction {
+ /** Returns a string representation of this instruction */
+ override def toString(): String =
+ "CIL_LOAD_FIELD_ADDRESS " + (if (isStatic) field.fullName else field.toString)
+
+ override def consumed = if (isStatic) 0 else 1
+ override def produced = 1
+
+ override def consumedTypes = if (isStatic) Nil else List(REFERENCE(field.owner));
+ override def producedTypes = List(msil_mgdptr(REFERENCE(field.owner)));
+}
+
+ case class CIL_LOAD_ARRAY_ITEM_ADDRESS(kind: TypeKind) extends Instruction {
+ /** Returns a string representation of this instruction */
+ override def toString(): String = "CIL_LOAD_ARRAY_ITEM_ADDRESS (" + kind + ")"
+
+ override def consumed = 2
+ override def produced = 1
+
+ override def consumedTypes = List(ARRAY(kind), INT)
+ override def producedTypes = List(msil_mgdptr(kind))
+ }
+
+ case class CIL_UNBOX(valueType: TypeKind) extends Instruction {
+ override def toString(): String = "CIL_UNBOX " + valueType
+ override def consumed = 1
+ override def consumedTypes = ObjectReference :: Nil // actually consumes a 'boxed valueType'
+ override def produced = 1
+ override def producedTypes = List(msil_mgdptr(valueType))
+ }
+
+ case class CIL_INITOBJ(valueType: TypeKind) extends Instruction {
+ override def toString(): String = "CIL_INITOBJ " + valueType
+ override def consumed = 1
+ override def consumedTypes = ObjectReference :: Nil // actually consumes a managed pointer
+ override def produced = 0
+ }
+
+ case class CIL_NEWOBJ(method: Symbol) extends Instruction {
+ override def toString(): String = "CIL_NEWOBJ " + hostClass.fullName + method.fullName
+ var hostClass: Symbol = method.owner;
+ override def consumed = method.tpe.paramTypes.length
+ override def consumedTypes = method.tpe.paramTypes map toTypeKind
+ override def produced = 1
+ override def producedTypes = List(toTypeKind(method.tpe.resultType))
+ }
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
index 998ac90778..a485272ca6 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
@@ -423,10 +423,11 @@ trait TypeKinds { self: ICodes =>
primitiveTypeMap.getOrElse(sym, newReference(sym))
private def primitiveOrClassType(sym: Symbol, targs: List[Type]) =
primitiveTypeMap.getOrElse(sym, arrayOrClassType(sym, targs))
- //
- // def msil_mgdptr(tk: TypeKind): TypeKind = (tk: @unchecked) match {
- // case REFERENCE(cls) => REFERENCE(loaders.clrTypes.mdgptrcls4clssym(cls))
- // // TODO have ready class-symbols for the by-ref versions of built-in valuetypes
- // case _ => abort("cannot obtain a managed pointer for " + tk)
- // }
+
+ def msil_mgdptr(tk: TypeKind): TypeKind = (tk: @unchecked) match {
+ case REFERENCE(cls) => REFERENCE(loaders.clrTypes.mdgptrcls4clssym(cls))
+ // TODO have ready class-symbols for the by-ref versions of built-in valuetypes
+ case _ => abort("cannot obtain a managed pointer for " + tk)
+ }
+
}
diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
index aba537f3bd..d2e54ff3f1 100644
--- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
+++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
@@ -7,16 +7,16 @@
package scala.tools.nsc
package backend.msil
-// import java.io.{File, IOException}
-// import java.nio.{ByteBuffer, ByteOrder}
-// import scala.collection.{ mutable, immutable }
-// import scala.tools.nsc.symtab._
-//
-// import ch.epfl.lamp.compiler.msil.{Type => MsilType, _}
-// import ch.epfl.lamp.compiler.msil.emit._
-// import ch.epfl.lamp.compiler.msil.util.PECustomMod
-
-abstract class GenMSIL /*extends SubComponent {
+import java.io.{File, IOException}
+import java.nio.{ByteBuffer, ByteOrder}
+import scala.collection.{ mutable, immutable }
+import scala.tools.nsc.symtab._
+
+import ch.epfl.lamp.compiler.msil.{Type => MsilType, _}
+import ch.epfl.lamp.compiler.msil.emit._
+import ch.epfl.lamp.compiler.msil.util.PECustomMod
+
+abstract class GenMSIL extends SubComponent {
import global._
import loaders.clrTypes
import clrTypes.{types, constructors, methods, fields}
@@ -1815,7 +1815,7 @@ abstract class GenMSIL /*extends SubComponent {
types.get(sym).getOrElse {
classes.get(sym) match {
case Some(iclass) =>
- msilTypeBuilderFromSym(sym)
+ msilTypeBuilderFromSym(sym)
case None =>
getType(sym)
}
@@ -1844,7 +1844,7 @@ abstract class GenMSIL /*extends SubComponent {
debuglog("super type: " + parents(0).typeSymbol + ", msil type: " + superType)
val interfaces: Array[MsilType] =
- parents.tail.map(p => msilTypeFromSym(p.typeSymbol)).toArray
+ parents.tail.map(p => msilTypeFromSym(p.typeSymbol)).toArray
if (parents.length > 1) {
if (settings.debug.value) {
log("interfaces:")
@@ -2355,4 +2355,3 @@ abstract class GenMSIL /*extends SubComponent {
} // class BytecodeGenerator
} // class GenMSIL
-*/ \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/io/MsilFile.scala b/src/compiler/scala/tools/nsc/io/MsilFile.scala
index aeaa1b759b..d970d0e9c9 100644
--- a/src/compiler/scala/tools/nsc/io/MsilFile.scala
+++ b/src/compiler/scala/tools/nsc/io/MsilFile.scala
@@ -6,14 +6,13 @@
package scala.tools.nsc
package io
-// import ch.epfl.lamp.compiler.msil.{ Type => MsilType, _ }
+import ch.epfl.lamp.compiler.msil.{ Type => MsilType, _ }
/** This class wraps an MsilType. It exists only so
* ClassPath can treat all of JVM/MSIL/bin/src files
* uniformly, as AbstractFiles.
*/
-class MsilFile /* (val msilType: MsilType) extends VirtualFile(msilType.FullName, msilType.Namespace) {
+class MsilFile(val msilType: MsilType) extends VirtualFile(msilType.FullName, msilType.Namespace) {
}
object NoMsilFile extends MsilFile(null) { }
-*/ \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 2241bb224e..942ec1fa86 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -13,7 +13,7 @@ import classfile.ClassfileParser
import reflect.internal.Flags._
import reflect.internal.MissingRequirementError
import util.Statistics._
-import scala.tools.nsc.io.{ AbstractFile } //, MsilFile }
+import scala.tools.nsc.io.{ AbstractFile, MsilFile }
/** This class ...
*
@@ -236,16 +236,16 @@ abstract class SymbolLoaders {
}
override def sourcefile: Option[AbstractFile] = classfileParser.srcfile
}
- //
- // class MsilFileLoader(msilFile: MsilFile) extends SymbolLoader {
- // private def typ = msilFile.msilType
- // private object typeParser extends clr.TypeParser {
- // val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
- // }
- //
- // protected def description = "MsilFile "+ typ.FullName + ", assembly "+ typ.Assembly.FullName
- // protected def doComplete(root: Symbol) { typeParser.parse(typ, root) }
- // }
+
+ class MsilFileLoader(msilFile: MsilFile) extends SymbolLoader {
+ private def typ = msilFile.msilType
+ private object typeParser extends clr.TypeParser {
+ val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
+ }
+
+ protected def description = "MsilFile "+ typ.FullName + ", assembly "+ typ.Assembly.FullName
+ protected def doComplete(root: Symbol) { typeParser.parse(typ, root) }
+ }
class SourcefileLoader(val srcfile: AbstractFile) extends SymbolLoader {
protected def description = "source file "+ srcfile.toString
@@ -258,11 +258,11 @@ abstract class SymbolLoaders {
protected def description = "module class loader"
protected def doComplete(root: Symbol) { root.sourceModule.initialize }
}
- //
- // object clrTypes extends clr.CLRTypes {
- // val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
- // if (global.forMSIL) init()
- // }
+
+ object clrTypes extends clr.CLRTypes {
+ val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
+ if (global.forMSIL) init()
+ }
/** used from classfile parser to avoid cyclies */
var parentsLevel = 0
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
index 469f7ce3ab..7be0fcb146 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
@@ -7,17 +7,17 @@ package scala.tools.nsc
package symtab
package clr
-// import java.io.File
-// import java.util.{Comparator, StringTokenizer}
-// import scala.util.Sorting
-// import ch.epfl.lamp.compiler.msil._
-// import scala.collection.{ mutable, immutable }
-// import scala.tools.nsc.util.{Position, NoPosition}
+import java.io.File
+import java.util.{Comparator, StringTokenizer}
+import scala.util.Sorting
+import ch.epfl.lamp.compiler.msil._
+import scala.collection.{ mutable, immutable }
+import scala.tools.nsc.util.{Position, NoPosition}
/**
* Collects all types from all reference assemblies.
*/
-abstract class CLRTypes /*{
+abstract class CLRTypes {
val global: Global
import global.Symbol
@@ -135,4 +135,3 @@ abstract class CLRTypes /*{
def isDelegateType(t: Type): Boolean = { t.BaseType() == DELEGATE }
} // CLRTypes
-*/ \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
index d16c9980d5..e11a5a4ad9 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
@@ -6,17 +6,17 @@ package scala.tools.nsc
package symtab
package clr
-// import java.io.IOException
-// import io.MsilFile
-// import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute, _}
-// import scala.collection.{ mutable, immutable }
-// import scala.reflect.internal.pickling.UnPickler
-// import ch.epfl.lamp.compiler.msil.Type.TMVarUsage
+import java.io.IOException
+import io.MsilFile
+import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute, _}
+import scala.collection.{ mutable, immutable }
+import scala.reflect.internal.pickling.UnPickler
+import ch.epfl.lamp.compiler.msil.Type.TMVarUsage
/**
* @author Nikolay Mihaylov
*/
-abstract class TypeParser /*{
+abstract class TypeParser {
val global: Global
@@ -224,14 +224,14 @@ abstract class TypeParser /*{
if (canBeTakenAddressOf) {
clazzBoxed.setInfo( if (ownTypeParams.isEmpty) classInfoAsInMetadata
- else GenPolyType(ownTypeParams, classInfoAsInMetadata) )
+ else polyType(ownTypeParams, classInfoAsInMetadata) )
clazzBoxed.setFlag(flags)
val rawValueInfoType = ClassInfoType(definitions.anyvalparam, instanceDefs, clazz)
clazz.setInfo( if (ownTypeParams.isEmpty) rawValueInfoType
- else GenPolyType(ownTypeParams, rawValueInfoType) )
+ else polyType(ownTypeParams, rawValueInfoType) )
} else {
clazz.setInfo( if (ownTypeParams.isEmpty) classInfoAsInMetadata
- else GenPolyType(ownTypeParams, classInfoAsInMetadata) )
+ else polyType(ownTypeParams, classInfoAsInMetadata) )
}
// TODO I don't remember if statics.setInfo and staticModule.setInfo should also know about type params
@@ -256,18 +256,18 @@ abstract class TypeParser /*{
// import nested types
for (ntype <- typ.getNestedTypes() if !(ntype.IsNestedPrivate || ntype.IsNestedAssembly || ntype.IsNestedFamANDAssem)
- || ntype.IsInterface /* TODO why shouldn't nested ifaces be type-parsed too? */ )
+ || ntype.IsInterface /* TODO why shouldn't nested ifaces be type-parsed too? */ )
{
val loader = new loaders.MsilFileLoader(new MsilFile(ntype))
- val nclazz = statics.newClass(ntype.Name.toTypeName)
- val nmodule = statics.newModule(ntype.Name)
- nclazz.setInfo(loader)
- nmodule.setInfo(loader)
- staticDefs.enter(nclazz)
- staticDefs.enter(nmodule)
-
- assert(nclazz.companionModule == nmodule, nmodule)
- assert(nmodule.companionClass == nclazz, nclazz)
+ val nclazz = statics.newClass(ntype.Name.toTypeName)
+ val nmodule = statics.newModule(ntype.Name)
+ nclazz.setInfo(loader)
+ nmodule.setInfo(loader)
+ staticDefs.enter(nclazz)
+ staticDefs.enter(nmodule)
+
+ assert(nclazz.companionModule == nmodule, nmodule)
+ assert(nmodule.companionClass == nclazz, nclazz)
}
val fields = typ.getFields()
@@ -280,9 +280,9 @@ abstract class TypeParser /*{
val name = newTermName(field.Name);
val fieldType =
if (field.IsLiteral && !field.FieldType.IsEnum && isDefinedAtgetConstant(getCLRType(field.FieldType)))
- ConstantType(getConstant(getCLRType(field.FieldType), field.getValue))
- else
- getCLRType(field.FieldType)
+ ConstantType(getConstant(getCLRType(field.FieldType), field.getValue))
+ else
+ getCLRType(field.FieldType)
val owner = if (field.IsStatic()) statics else clazz;
val sym = owner.newValue(NoPosition, name).setFlag(flags).setInfo(fieldType);
// TODO: set private within!!! -> look at typechecker/Namers.scala
@@ -301,49 +301,49 @@ abstract class TypeParser /*{
for (prop <- typ.getProperties) {
val propType: Type = getCLSType(prop.PropertyType);
if (propType != null) {
- val getter: MethodInfo = prop.GetGetMethod(true);
- val setter: MethodInfo = prop.GetSetMethod(true);
- var gparamsLength: Int = -1;
- if (!(getter == null || getter.IsPrivate || getter.IsAssembly
+ val getter: MethodInfo = prop.GetGetMethod(true);
+ val setter: MethodInfo = prop.GetSetMethod(true);
+ var gparamsLength: Int = -1;
+ if (!(getter == null || getter.IsPrivate || getter.IsAssembly
|| getter.IsFamilyAndAssembly || getter.HasPtrParamOrRetType))
- {
- assert(prop.PropertyType == getter.ReturnType);
- val gparams: Array[ParameterInfo] = getter.GetParameters();
- gparamsLength = gparams.length;
- val name: Name = if (gparamsLength == 0) prop.Name else nme.apply;
- val flags = translateAttributes(getter);
- val owner: Symbol = if (getter.IsStatic) statics else clazz;
- val methodSym = owner.newMethod(NoPosition, name).setFlag(flags)
+ {
+ assert(prop.PropertyType == getter.ReturnType);
+ val gparams: Array[ParameterInfo] = getter.GetParameters();
+ gparamsLength = gparams.length;
+ val name: Name = if (gparamsLength == 0) prop.Name else nme.apply;
+ val flags = translateAttributes(getter);
+ val owner: Symbol = if (getter.IsStatic) statics else clazz;
+ val methodSym = owner.newMethod(NoPosition, name).setFlag(flags)
val mtype: Type = if (gparamsLength == 0) NullaryMethodType(propType) // .NET properties can't be polymorphic
else methodType(getter, getter.ReturnType)(methodSym)
methodSym.setInfo(mtype);
- methodSym.setFlag(Flags.ACCESSOR);
- (if (getter.IsStatic) staticDefs else instanceDefs).enter(methodSym)
- clrTypes.methods(methodSym) = getter;
- methodsSet -= getter;
- }
- if (!(setter == null || setter.IsPrivate || setter.IsAssembly
+ methodSym.setFlag(Flags.ACCESSOR);
+ (if (getter.IsStatic) staticDefs else instanceDefs).enter(methodSym)
+ clrTypes.methods(methodSym) = getter;
+ methodsSet -= getter;
+ }
+ if (!(setter == null || setter.IsPrivate || setter.IsAssembly
|| setter.IsFamilyAndAssembly || setter.HasPtrParamOrRetType))
- {
- val sparams: Array[ParameterInfo] = setter.GetParameters()
- if(getter != null)
- assert(getter.IsStatic == setter.IsStatic);
- assert(setter.ReturnType == clrTypes.VOID);
- if(getter != null)
- assert(sparams.length == gparamsLength + 1, "" + getter + "; " + setter);
-
- val name: Name = if (gparamsLength == 0) nme.getterToSetter(prop.Name)
- else nme.update;
- val flags = translateAttributes(setter);
- val mtype = methodType(setter, definitions.UnitClass.tpe);
- val owner: Symbol = if (setter.IsStatic) statics else clazz;
- val methodSym = owner.newMethod(NoPosition, name).setFlag(flags)
+ {
+ val sparams: Array[ParameterInfo] = setter.GetParameters()
+ if(getter != null)
+ assert(getter.IsStatic == setter.IsStatic);
+ assert(setter.ReturnType == clrTypes.VOID);
+ if(getter != null)
+ assert(sparams.length == gparamsLength + 1, "" + getter + "; " + setter);
+
+ val name: Name = if (gparamsLength == 0) nme.getterToSetter(prop.Name)
+ else nme.update;
+ val flags = translateAttributes(setter);
+ val mtype = methodType(setter, definitions.UnitClass.tpe);
+ val owner: Symbol = if (setter.IsStatic) statics else clazz;
+ val methodSym = owner.newMethod(NoPosition, name).setFlag(flags)
methodSym.setInfo(mtype(methodSym))
- methodSym.setFlag(Flags.ACCESSOR);
- (if (setter.IsStatic) staticDefs else instanceDefs).enter(methodSym);
- clrTypes.methods(methodSym) = setter;
- methodsSet -= setter;
- }
+ methodSym.setFlag(Flags.ACCESSOR);
+ (if (setter.IsStatic) staticDefs else instanceDefs).enter(methodSym);
+ clrTypes.methods(methodSym) = setter;
+ methodsSet -= setter;
+ }
}
}
@@ -354,27 +354,27 @@ abstract class TypeParser /*{
val adder: MethodInfo = event.GetAddMethod();
val remover: MethodInfo = event.GetRemoveMethod();
if (!(adder == null || adder.IsPrivate || adder.IsAssembly
- || adder.IsFamilyAndAssembly))
- {
- assert(adder.ReturnType == clrTypes.VOID);
- assert(adder.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType));
- val name = encode("+=");
- val flags = translateAttributes(adder);
- val mtype: Type = methodType(adder, adder.ReturnType);
- createMethod(name, flags, mtype, adder, adder.IsStatic)
- methodsSet -= adder;
- }
+ || adder.IsFamilyAndAssembly))
+ {
+ assert(adder.ReturnType == clrTypes.VOID);
+ assert(adder.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType));
+ val name = encode("+=");
+ val flags = translateAttributes(adder);
+ val mtype: Type = methodType(adder, adder.ReturnType);
+ createMethod(name, flags, mtype, adder, adder.IsStatic)
+ methodsSet -= adder;
+ }
if (!(remover == null || remover.IsPrivate || remover.IsAssembly
- || remover.IsFamilyAndAssembly))
- {
- assert(remover.ReturnType == clrTypes.VOID);
- assert(remover.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType));
- val name = encode("-=");
- val flags = translateAttributes(remover);
- val mtype: Type = methodType(remover, remover.ReturnType);
- createMethod(name, flags, mtype, remover, remover.IsStatic)
- methodsSet -= remover;
- }
+ || remover.IsFamilyAndAssembly))
+ {
+ assert(remover.ReturnType == clrTypes.VOID);
+ assert(remover.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType));
+ val name = encode("-=");
+ val flags = translateAttributes(remover);
+ val mtype: Type = methodType(remover, remover.ReturnType);
+ createMethod(name, flags, mtype, remover, remover.IsStatic)
+ methodsSet -= remover;
+ }
} */
/* Adds view amounting to syntax sugar for a CLR implicit overload.
@@ -480,7 +480,7 @@ abstract class TypeParser /*{
val mtype = methodType(method, rettype);
if (mtype == null) return;
/* START CLR generics (snippet 4) */
- val mInfo = if (method.IsGeneric) GenPolyType(newMethodTParams, mtype(methodSym))
+ val mInfo = if (method.IsGeneric) polyType(newMethodTParams, mtype(methodSym))
else mtype(methodSym)
/* END CLR generics (snippet 4) */
/* START CLR non-generics (snippet 4)
@@ -805,7 +805,7 @@ abstract class TypeParser /*{
private def translateAttributes(typ: MSILType): Long = {
var flags: Long = Flags.JAVA;
if (typ.IsNotPublic() || typ.IsNestedPrivate()
- || typ.IsNestedAssembly() || typ.IsNestedFamANDAssem())
+ || typ.IsNestedAssembly() || typ.IsNestedFamANDAssem())
flags = flags | Flags.PRIVATE;
else if (typ.IsNestedFamily() || typ.IsNestedFamORAssem())
flags = flags | Flags.PROTECTED;
@@ -849,4 +849,3 @@ abstract class TypeParser /*{
flags
}
}
-*/ \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala
index e46f3cbc77..6215506141 100644
--- a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala
@@ -8,20 +8,20 @@
package scala.tools.nsc
package util
-// import java.io.File
-// import java.net.URL
-// import java.util.StringTokenizer
-// import scala.util.Sorting
-// import scala.collection.mutable
-// import scala.tools.nsc.io.{ AbstractFile, MsilFile }
-// import ch.epfl.lamp.compiler.msil.{ Type => MSILType, Assembly }
-// import ClassPath.{ ClassPathContext, isTraitImplementation }
+import java.io.File
+import java.net.URL
+import java.util.StringTokenizer
+import scala.util.Sorting
+import scala.collection.mutable
+import scala.tools.nsc.io.{ AbstractFile, MsilFile }
+import ch.epfl.lamp.compiler.msil.{ Type => MSILType, Assembly }
+import ClassPath.{ ClassPathContext, isTraitImplementation }
/** Keeping the MSIL classpath code in its own file is important to make sure
* we don't accidentally introduce a dependency on msil.jar in the jvm.
*/
-object MsilClassPath /*{
+object MsilClassPath {
def collectTypes(assemFile: AbstractFile) = {
var res: Array[MSILType] = MSILType.EmptyTypes
val assem = Assembly.LoadFrom(assemFile.path)
@@ -166,5 +166,4 @@ class AssemblyClassPath(types: Array[MSILType], namespace: String, val context:
* MSILType values.
*/
class MsilClassPath(ext: String, user: String, source: String, context: MsilContext)
-extends MergedClassPath[MsilFile](MsilClassPath.assembleEntries(ext, user, source, context), context) { }
-*/ \ No newline at end of file
+extends MergedClassPath[MsilFile](MsilClassPath.assembleEntries(ext, user, source, context), context) { } \ No newline at end of file