diff options
-rw-r--r-- | src/dotty/runtime/Arrays.scala | 35 | ||||
-rw-r--r-- | src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/backend/sjs/JSCodeGen.scala | 20 | ||||
-rw-r--r-- | src/dotty/tools/backend/sjs/JSPrimitives.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/tpd.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Erasure.scala | 18 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 3 |
8 files changed, 36 insertions, 67 deletions
diff --git a/src/dotty/runtime/Arrays.scala b/src/dotty/runtime/Arrays.scala index 4469dced7..2771df66b 100644 --- a/src/dotty/runtime/Arrays.scala +++ b/src/dotty/runtime/Arrays.scala @@ -2,6 +2,8 @@ package dotty.runtime import scala.reflect.ClassTag +import java.lang.{reflect => jlr} + /** All but the first two operations should be short-circuited and implemented specially by * the backend. */ @@ -22,35 +24,44 @@ object Arrays { arr } - /** Create an array of type T. T must be of form Array[E], with - * E being a reference type. + /** Create an array of a reference type T. */ - def newRefArray[T](length: Int): T = ??? + def newRefArray[T](componentType: Class[T])(length: Int): Array[T] = + jlr.Array.newInstance(componentType, length).asInstanceOf[Array[T]] /** Create a Byte[] array */ - def newByteArray(length: Int): Array[Byte] = ??? + def newByteArray(length: Int): Array[Byte] = + jlr.Array.newInstance(classOf[Byte], length).asInstanceOf[Array[Byte]] /** Create a Short[] array */ - def newShortArray(length: Int): Array[Short] = ??? + def newShortArray(length: Int): Array[Short] = + jlr.Array.newInstance(classOf[Short], length).asInstanceOf[Array[Short]] /** Create a Char[] array */ - def newCharArray(length: Int): Array[Char] = ??? + def newCharArray(length: Int): Array[Char] = + jlr.Array.newInstance(classOf[Char], length).asInstanceOf[Array[Char]] /** Create an Int[] array */ - def newIntArray(length: Int): Array[Int] = ??? + def newIntArray(length: Int): Array[Int] = + jlr.Array.newInstance(classOf[Int], length).asInstanceOf[Array[Int]] /** Create a Long[] array */ - def newLongArray(length: Int): Array[Long] = ??? + def newLongArray(length: Int): Array[Long] = + jlr.Array.newInstance(classOf[Long], length).asInstanceOf[Array[Long]] /** Create a Float[] array */ - def newFloatArray(length: Int): Array[Float] = ??? + def newFloatArray(length: Int): Array[Float] = + jlr.Array.newInstance(classOf[Float], length).asInstanceOf[Array[Float]] /** Create a Double[] array */ - def newDoubleArray(length: Int): Array[Double] = ??? + def newDoubleArray(length: Int): Array[Double] = + jlr.Array.newInstance(classOf[Double], length).asInstanceOf[Array[Double]] /** Create a Boolean[] array */ - def newBooleanArray(length: Int): Array[Boolean] = ??? + def newBooleanArray(length: Int): Array[Boolean] = + jlr.Array.newInstance(classOf[Boolean], length).asInstanceOf[Array[Boolean]] /** Create a scala.runtime.BoxedUnit[] array */ - def newUnitArray(length: Int): Array[Unit] = ??? + def newUnitArray(length: Int): Array[Unit] = + jlr.Array.newInstance(classOf[scala.runtime.BoxedUnit], length).asInstanceOf[Array[Unit]] } diff --git a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index ef8e4997f..6e4431b1a 100644 --- a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -153,7 +153,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile)(implicit ctx: Context }.toMap def unboxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap - private val mkArrayNames: Set[Name] = Set("Byte", "Float", "Char", "Double", "Boolean", "Unit", "Long", "Int", "Short", "Ref").map{ x=> + private val mkArrayNames: Set[Name] = Set("Byte", "Float", "Char", "Double", "Boolean", "Unit", "Long", "Int", "Short"/*, "Ref"*/).map{ x=> ("new" + x + "Array").toTermName } diff --git a/src/dotty/tools/backend/sjs/JSCodeGen.scala b/src/dotty/tools/backend/sjs/JSCodeGen.scala index 70c5af1e7..401e01784 100644 --- a/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -1036,8 +1036,6 @@ class JSCodeGen()(implicit ctx: Context) { genStringConcat(tree, receiver, args) else if (code == HASH) genScalaHash(tree, receiver) - else if (isArrayNew(code)) - genArrayNew(tree, code) else if (isArrayOp(code)) genArrayOp(tree, code) else if (code == SYNCHRONIZED) @@ -1409,24 +1407,6 @@ class JSCodeGen()(implicit ctx: Context) { List(genExpr(receiver))) } - /** Gen JS code for a new array operation. */ - private def genArrayNew(tree: Tree, code: Int): js.Tree = { - import scala.tools.nsc.backend.ScalaPrimitives._ - - implicit val pos: Position = tree.pos - - val Apply(fun, args) = tree - val genLength = genExpr(args.head) - - toIRType(tree.tpe) match { - case arrayType: jstpe.ArrayType => - js.NewArray(arrayType, List(genLength)) - - case irTpe => - throw new FatalError(s"ArrayNew $tree must have an array type but was $irTpe") - } - } - /** Gen JS code for an array operation (get, set or length) */ private def genArrayOp(tree: Tree, code: Int): js.Tree = { import scala.tools.nsc.backend.ScalaPrimitives._ diff --git a/src/dotty/tools/backend/sjs/JSPrimitives.scala b/src/dotty/tools/backend/sjs/JSPrimitives.scala index 52b5dc4b9..6c3c5715c 100644 --- a/src/dotty/tools/backend/sjs/JSPrimitives.scala +++ b/src/dotty/tools/backend/sjs/JSPrimitives.scala @@ -80,18 +80,6 @@ class JSPrimitives(ctx: Context) extends DottyPrimitives(ctx) { val jsdefn = JSDefinitions.jsdefn - // For some reason, the JVM primitive set does not register those - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newBooleanArray")), NEW_ZARRAY) - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newByteArray")), NEW_BARRAY) - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newShortArray")), NEW_SARRAY) - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newCharArray")), NEW_CARRAY) - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newIntArray")), NEW_IARRAY) - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newLongArray")), NEW_LARRAY) - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newFloatArray")), NEW_FARRAY) - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newDoubleArray")), NEW_DARRAY) - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newRefArray")), NEW_OARRAY) - addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newUnitArray")), NEW_OARRAY) - addPrimitive(defn.Any_getClass, GETCLASS) for (i <- 0 to 22) diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index 8d21953ae..a58ff7f51 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -371,9 +371,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { newArr("Generic").appliedToTypeTrees(typeArg :: Nil) else if (elemClass.isPrimitiveValueClass) newArr(elemClass.name.toString) - else - newArr("Ref").appliedToTypeTrees( - TypeTree(defn.ArrayOf(elemType)).withPos(typeArg.pos) :: Nil) + else { + val typeApplied = newArr("Ref").appliedToTypeTrees(typeArg :: Nil) + val classOfArg = + ref(defn.Predef_classOf).appliedToTypeTrees(typeArg :: Nil) + Apply(typeApplied, classOfArg :: Nil).withPos(typeArg.pos) + } } // ------ Creating typed equivalents of trees that exist only in untyped form ------- diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 6625cff3f..fb71fa467 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -247,8 +247,6 @@ class Definitions { lazy val DottyArraysModuleRef = ctx.requiredModuleRef("dotty.runtime.Arrays") def DottyArraysModule(implicit ctx: Context) = DottyArraysModuleRef.symbol - def newRefArrayMethod(implicit ctx: Context) = DottyArraysModule.requiredMethod("newRefArray") - lazy val NilModuleRef = ctx.requiredModuleRef("scala.collection.immutable.Nil") def NilModule(implicit ctx: Context) = NilModuleRef.symbol @@ -622,7 +620,7 @@ class Definitions { lazy val PhantomClasses = Set[Symbol](AnyClass, AnyValClass, NullClass, NothingClass) def isPolymorphicAfterErasure(sym: Symbol) = - (sym eq Any_isInstanceOf) || (sym eq Any_asInstanceOf) || (sym eq newRefArrayMethod) + (sym eq Any_isInstanceOf) || (sym eq Any_asInstanceOf) def isTupleType(tp: Type)(implicit ctx: Context) = { val arity = tp.dealias.argInfos.length diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index 7acb14af4..4e7bcffd4 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -467,28 +467,18 @@ object Erasure extends TypeTestsCasts{ tpt = untpd.TypedSplice(TypeTree(sym.info).withPos(vdef.tpt.pos))), sym) override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = { - var effectiveSym = sym - if (sym == defn.newRefArrayMethod) { - // newRefArray is treated specially: It's the only source-defined method - // that has a polymorphic type after erasure. But treating its (dummy) definition - // with a polymorphic type at and after erasure is an awkward special case. - // We therefore rewrite the method definition with a new Symbol of type - // (length: Int)Object - val MethodType(pnames, ptypes) = sym.info.resultType - effectiveSym = sym.copy(info = MethodType(pnames, ptypes, defn.ObjectType)) - } val restpe = - if (effectiveSym.isConstructor) defn.UnitType - else effectiveSym.info.resultType + if (sym.isConstructor) defn.UnitType + else sym.info.resultType val ddef1 = untpd.cpy.DefDef(ddef)( tparams = Nil, - vparamss = (outer.paramDefs(effectiveSym) ::: ddef.vparamss.flatten) :: Nil, + vparamss = (outer.paramDefs(sym) ::: ddef.vparamss.flatten) :: Nil, tpt = untpd.TypedSplice(TypeTree(restpe).withPos(ddef.tpt.pos)), rhs = ddef.rhs match { case id @ Ident(nme.WILDCARD) => untpd.TypedSplice(id.withType(restpe)) case _ => ddef.rhs }) - super.typedDefDef(ddef1, effectiveSym) + super.typedDefDef(ddef1, sym) } /** After erasure, we may have to replace the closure method by a bridge. diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala index 007869e06..f11789c9a 100644 --- a/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -359,8 +359,7 @@ class TreeChecker extends Phase with SymTransformer { def isNonMagicalMethod(x: Symbol) = x.is(Method) && !x.isCompanionMethod && - !x.isValueClassConvertMethod && - x != defn.newRefArrayMethod + !x.isValueClassConvertMethod val symbolsNotDefined = cls.classInfo.decls.toSet.filter(isNonMagicalMethod) -- impl.body.map(_.symbol) - constr.symbol |