diff options
author | Aleksandar Pokopec <aleksandar.prokopec@epfl.ch> | 2011-02-09 15:46:31 +0000 |
---|---|---|
committer | Aleksandar Pokopec <aleksandar.prokopec@epfl.ch> | 2011-02-09 15:46:31 +0000 |
commit | c3130988e86a56eaf5416bef7fe9c496bd006111 (patch) | |
tree | 4bd6230227f00bc20b20a6874ca782519469ebfe /src/compiler | |
parent | 756a086802b90674545888c9138575ea9a2237f4 (diff) | |
download | scala-c3130988e86a56eaf5416bef7fe9c496bd006111.tar.gz scala-c3130988e86a56eaf5416bef7fe9c496bd006111.tar.bz2 scala-c3130988e86a56eaf5416bef7fe9c496bd006111.zip |
Specialization work in progress.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 44 |
2 files changed, 41 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 1757048036..99367e1de8 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -49,7 +49,8 @@ trait Definitions extends reflect.generic.StandardDefinitions { tpnme.Float -> FLOAT_TAG, tpnme.Double -> DOUBLE_TAG, tpnme.Boolean -> BOOL_TAG, - tpnme.Unit -> VOID_TAG + tpnme.Unit -> VOID_TAG, + tpnme.Object -> CLASS_TAG ) private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f) @@ -58,7 +59,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { private def boxedName(name: Name) = sn.Boxed(name.toTypeName) - lazy val abbrvTag = symbolsMap(ScalaValueClasses, nameToTag) + lazy val abbrvTag = symbolsMap(ObjectClass :: ScalaValueClasses, nameToTag) lazy val numericWeight = symbolsMapFilt(ScalaValueClasses, nameToWeight.keySet, nameToWeight) lazy val boxedModule = classesMap(x => getModule(boxedName(x))) lazy val boxedClass = classesMap(x => getClass(boxedName(x))) @@ -175,6 +176,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { lazy val AnyClass = newClass(ScalaPackageClass, tpnme.Any, Nil) setFlag (ABSTRACT) lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.typeConstructor) lazy val ObjectClass = getClass(sn.Object) + lazy val AnyCompanionClass = getClass("scala.AnyCompanion") setFlag (SEALED | ABSTRACT | TRAIT) lazy val AnyValCompanionClass = getClass("scala.AnyValCompanion") setFlag (SEALED | ABSTRACT | TRAIT) // bottom types @@ -237,7 +239,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { lazy val ConsoleModule: Symbol = getModule("scala.Console") lazy val ScalaRunTimeModule: Symbol = getModule("scala.runtime.ScalaRunTime") lazy val SymbolModule: Symbol = getModule("scala.Symbol") - lazy val Symbol_apply = getMember(SymbolModule, nme.apply) + lazy val Symbol_apply = getMember(SymbolModule, nme.apply) def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq) def arrayApplyMethod = getMember(ScalaRunTimeModule, "array_apply") def arrayUpdateMethod = getMember(ScalaRunTimeModule, "array_update") @@ -246,6 +248,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { def ensureAccessibleMethod = getMember(ScalaRunTimeModule, "ensureAccessible") def scalaRuntimeHash = getMember(ScalaRunTimeModule, "hash") def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements) + lazy val RefModule = getModule("scala.Ref") // classes with special meanings lazy val NotNullClass = getClass("scala.NotNull") diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index bd8d9db27e..db951c9111 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -29,7 +29,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { import definitions.{ RootClass, BooleanClass, UnitClass, ArrayClass, ScalaValueClasses, - SpecializedClass, RepeatedParamClass, JavaRepeatedParamClass + SpecializedClass, RepeatedParamClass, JavaRepeatedParamClass, + AnyRefClass, RefModule, ObjectClass } private def isSpecialized(sym: Symbol) = sym hasAnnotation SpecializedClass @@ -232,17 +233,24 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { nme.getterToLocal(specializedName(nme.localToGetter(name), types1, types2)) else { val (base, cs, ms) = nme.splitSpecializedName(name) + val abbrevs = definitions.abbrvTag withDefaultValue definitions.abbrvTag(ObjectClass) newTermName(base.toString + "$" - + "m" + ms + types1.map(t => definitions.abbrvTag(t.typeSymbol)).mkString("", "", "") - + "c" + cs + types2.map(t => definitions.abbrvTag(t.typeSymbol)).mkString("", "", "$sp")) + + "m" + ms + types1.map(t => abbrevs(t.typeSymbol)).mkString("", "", "") + + "c" + cs + types2.map(t => abbrevs(t.typeSymbol)).mkString("", "", "$sp")) } } lazy val primitiveTypes = ScalaValueClasses map (_.tpe) + private def tParamSubAnyRef(sym: Symbol) = { + val tparam = sym.owner.newTypeParameter(sym.pos, sym.name.asInstanceOf[TypeName]) + .setInfo(TypeBounds.upper(AnyRefClass.tpe)) + tparam.tpe + } + /** Return the concrete types `sym' should be specialized at. */ - def concreteTypes(sym: Symbol): List[Type] = + def concreteTypes(sym: Symbol): List[Type] = { sym.getAnnotation(SpecializedClass) match { case Some(AnnotationInfo(_, args, _)) => args match { @@ -250,13 +258,16 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { log(sym + " specialized on everything") primitiveTypes case _ => - val tpes = args.map(_.symbol.companionClass.tpe) + val tpes = args map { + t => if (t.symbol == RefModule) tParamSubAnyRef(sym) else t.symbol.companionClass.tpe + } log(sym + " specialized on " + tpes) tpes } case _ => Nil } + } /** Return a list of all type environments for all specializations * of @specialized types in `tps'. @@ -338,6 +349,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case _ => immutable.ListSet.empty[Symbol] } + def isPrimitive(tpe: Type) = definitions.ScalaValueClasses contains tpe.typeSymbol + + def survivingParams(params: List[Symbol], env: TypeEnv) = + params.filter(p => !isSpecialized(p) || !isPrimitive(env(p))) + + def cloneAndRemoveAnnotation(syms: List[Symbol], owner: Symbol) = { + val cloned = cloneSymbols(syms, owner) + cloned foreach { _.removeAnnotation(SpecializedClass) } + cloned + } + /** Specialize 'clazz', in the environment `outerEnv`. The outer * environment contains bindings for specialized types of enclosing * classes. @@ -369,12 +391,15 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // has to be a val in order to be computed early. It is later called // within 'atPhase(next)', which would lead to an infinite cycle otherwise val specializedInfoType: Type = { - val (_, unspecParams) = splitParams(clazz.info.typeParams) - oldClassTParams = unspecParams - newClassTParams = cloneSymbols(unspecParams, cls) map subst(env) + // val (_, unspecParams) = splitParams(clazz.info.typeParams) + // oldClassTParams = unspecParams + val survivedParams = survivingParams(clazz.info.typeParams, env) + oldClassTParams = survivedParams + newClassTParams = cloneAndRemoveAnnotation(survivedParams, cls) map subst(env) + log("new tparams " + newClassTParams.zip(newClassTParams map {_.tpe})) def applyContext(tpe: Type) = - subst(env, tpe).subst(unspecParams, newClassTParams map (_.tpe)) + subst(env, tpe).subst(survivedParams, newClassTParams map (_.tpe)) /** Return a list of specialized parents to be re-mixed in a specialized subclass. * Assuming env = [T -> Int] and @@ -586,6 +611,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { }) var hasSubclasses = false + log("For " + clazz + " - " + specializations(clazz.info.typeParams)) for (env <- specializations(clazz.info.typeParams) if satisfiable(env)) { val spc = specializedClass(env, decls1) log("entered " + spc + " in " + clazz.owner) |