diff options
author | Paul Phillips <paulp@improving.org> | 2012-02-04 21:06:42 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-02-04 21:10:51 -0800 |
commit | 6ba9411c7c6abdbd907ca93208ac58b474b201d0 (patch) | |
tree | 614eeef46130287f58da14ec1b8aa6c35853cfef /src | |
parent | dcb5fe93162fcf7112d95733ecb78075dbd34f90 (diff) | |
download | scala-6ba9411c7c6abdbd907ca93208ac58b474b201d0.tar.gz scala-6ba9411c7c6abdbd907ca93208ac58b474b201d0.tar.bz2 scala-6ba9411c7c6abdbd907ca93208ac58b474b201d0.zip |
Restored msil.
Diffstat (limited to 'src')
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 |