Skip to content

Commit 4f2a20e

Browse files
committed
Merge pull request scala#5098 from sjrd/simplify-scala-runtime
Simplify scala.runtime
2 parents 804a4cc + 468dead commit 4f2a20e

File tree

16 files changed

+66
-343
lines changed

16 files changed

+66
-343
lines changed

src/compiler/scala/reflect/reify/phases/Reify.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package scala.reflect.reify
22
package phases
33

4-
import scala.runtime.ScalaRunTime.isAnyVal
54
import scala.reflect.reify.codegen._
65

76
trait Reify extends GenSymbols
@@ -57,4 +56,9 @@ trait Reify extends GenSymbols
5756
case _ =>
5857
throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass))
5958
})
59+
60+
private def isAnyVal(x: Any) = x match {
61+
case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true
62+
case _ => false
63+
}
6064
}

src/compiler/scala/tools/nsc/typechecker/Macros.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import scala.reflect.internal.util.ListOfNil
1212
import scala.reflect.macros.runtime.{AbortMacroException, MacroRuntimes}
1313
import scala.reflect.macros.compiler.DefaultMacroCompiler
1414
import scala.tools.reflect.FastTrack
15-
import scala.runtime.ScalaRunTime
1615
import Fingerprint._
1716

1817
/**
@@ -239,7 +238,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers {
239238
if (!payload.contains(field)) failField("is supposed to be there")
240239
val raw: Any = payload(field)
241240
if (raw == null) failField(s"is not supposed to be null")
242-
val expected = ScalaRunTime.box(clazz)
241+
val expected = box(clazz)
243242
val actual = raw.getClass
244243
if (!expected.isAssignableFrom(actual)) failField(s"has wrong type: expected $expected, actual $actual")
245244
raw.asInstanceOf[T]
@@ -256,6 +255,19 @@ trait Macros extends MacroRuntimes with Traces with Helpers {
256255
val signature = unpickle("signature", classOf[List[List[Fingerprint]]])
257256
MacroImplBinding(isBundle, isBlackbox, className, methodName, signature, targs)
258257
}
258+
259+
private def box[T](clazz: Class[T]): Class[_] = clazz match {
260+
case java.lang.Byte.TYPE => classOf[java.lang.Byte]
261+
case java.lang.Short.TYPE => classOf[java.lang.Short]
262+
case java.lang.Character.TYPE => classOf[java.lang.Character]
263+
case java.lang.Integer.TYPE => classOf[java.lang.Integer]
264+
case java.lang.Long.TYPE => classOf[java.lang.Long]
265+
case java.lang.Float.TYPE => classOf[java.lang.Float]
266+
case java.lang.Double.TYPE => classOf[java.lang.Double]
267+
case java.lang.Void.TYPE => classOf[scala.runtime.BoxedUnit]
268+
case java.lang.Boolean.TYPE => classOf[java.lang.Boolean]
269+
case _ => clazz
270+
}
259271
}
260272

261273
def bindMacroImpl(macroDef: Symbol, macroImplRef: Tree): Unit = {

src/library/scala/collection/mutable/ArrayOps.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ package collection
1111
package mutable
1212

1313
import scala.reflect.ClassTag
14-
import scala.runtime.ScalaRunTime._
1514
import parallel.mutable.ParArray
1615

1716
/** This class serves as a wrapper for `Array`s with all the operations found in
@@ -35,15 +34,15 @@ import parallel.mutable.ParArray
3534
sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] {
3635

3736
private def elementClass: Class[_] =
38-
arrayElementClass(repr.getClass)
37+
repr.getClass.getComponentType
3938

4039
override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) {
4140
val l = len min repr.length min (xs.length - start)
4241
if (l > 0) Array.copy(repr, 0, xs, start, l)
4342
}
4443

4544
override def toArray[U >: T : ClassTag]: Array[U] = {
46-
val thatElementClass = arrayElementClass(implicitly[ClassTag[U]])
45+
val thatElementClass = implicitly[ClassTag[U]].runtimeClass
4746
if (elementClass eq thatElementClass)
4847
repr.asInstanceOf[Array[U]]
4948
else
@@ -91,7 +90,7 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara
9190
val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(ClassTag[Array[U]](elementClass))
9291
if (isEmpty) bb.result()
9392
else {
94-
def mkRowBuilder() = Array.newBuilder(ClassTag[U](arrayElementClass(elementClass)))
93+
def mkRowBuilder() = Array.newBuilder(ClassTag[U](elementClass.getComponentType))
9594
val bs = asArray(head) map (_ => mkRowBuilder())
9695
for (xs <- this) {
9796
var i = 0
@@ -184,7 +183,7 @@ object ArrayOps {
184183

185184
override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr)
186185
override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr)
187-
override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](arrayElementClass(repr.getClass)))
186+
override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](repr.getClass.getComponentType))
188187

189188
def length: Int = repr.length
190189
def apply(index: Int): T = repr(index)

src/library/scala/collection/mutable/WrappedArray.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ package collection
1313
package mutable
1414

1515
import scala.reflect.ClassTag
16-
import scala.runtime.ScalaRunTime._
1716
import scala.collection.generic._
1817
import scala.collection.parallel.mutable.ParArray
1918

@@ -46,7 +45,7 @@ extends AbstractSeq[T]
4645
def elemTag: ClassTag[T]
4746

4847
@deprecated("use elemTag instead", "2.10.0")
49-
def elemManifest: ClassManifest[T] = ClassManifest.fromClass[T](arrayElementClass(elemTag).asInstanceOf[Class[T]])
48+
def elemManifest: ClassManifest[T] = ClassManifest.fromClass[T](elemTag.runtimeClass.asInstanceOf[Class[T]])
5049

5150
/** The length of the array */
5251
def length: Int
@@ -63,10 +62,10 @@ extends AbstractSeq[T]
6362
override def par = ParArray.handoff(array)
6463

6564
private def elementClass: Class[_] =
66-
arrayElementClass(array.getClass)
65+
array.getClass.getComponentType
6766

6867
override def toArray[U >: T : ClassTag]: Array[U] = {
69-
val thatElementClass = arrayElementClass(implicitly[ClassTag[U]])
68+
val thatElementClass = implicitly[ClassTag[U]].runtimeClass
7069
if (elementClass eq thatElementClass)
7170
array.asInstanceOf[Array[U]]
7271
else
@@ -122,7 +121,7 @@ object WrappedArray {
122121
def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer
123122

124123
final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable {
125-
lazy val elemTag = ClassTag[T](arrayElementClass(array.getClass))
124+
lazy val elemTag = ClassTag[T](array.getClass.getComponentType)
126125
def length: Int = array.length
127126
def apply(index: Int): T = array(index).asInstanceOf[T]
128127
def update(index: Int, elem: T) { array(index) = elem }

src/library/scala/collection/mutable/WrappedArrayBuilder.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ package collection
1313
package mutable
1414

1515
import scala.reflect.ClassTag
16-
import scala.runtime.ScalaRunTime._
1716

1817
/** A builder class for arrays.
1918
*
@@ -34,7 +33,7 @@ class WrappedArrayBuilder[A](tag: ClassTag[A]) extends ReusableBuilder[A, Wrappe
3433
private var size: Int = 0
3534

3635
private def mkArray(size: Int): WrappedArray[A] = {
37-
val runtimeClass = arrayElementClass(tag)
36+
val runtimeClass = tag.runtimeClass
3837
val newelems = runtimeClass match {
3938
case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](size)).asInstanceOf[WrappedArray[A]]
4039
case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](size)).asInstanceOf[WrappedArray[A]]

src/library/scala/reflect/ClassTag.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package scala
22
package reflect
33

44
import java.lang.{ Class => jClass }
5-
import scala.runtime.ScalaRunTime.arrayElementClass
65

76
/**
87
*
@@ -105,7 +104,7 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial
105104
override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass)
106105
override def toString = {
107106
def prettyprint(clazz: jClass[_]): String =
108-
if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else
107+
if (clazz.isArray) s"Array[${prettyprint(clazz.getComponentType)}]" else
109108
clazz.getName
110109
prettyprint(runtimeClass)
111110
}

src/library/scala/runtime/ArrayRuntime.java

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/library/scala/runtime/Boxed.scala

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/library/scala/runtime/BoxesRunTime.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,6 @@ public static int hashFromNumber(java.lang.Number n) {
257257
else if (n instanceof java.lang.Float) return hashFromFloat((java.lang.Float)n);
258258
else return n.hashCode();
259259
}
260-
public static int hashFromObject(Object a) {
261-
if (a instanceof Number) return hashFromNumber((Number)a);
262-
else return a.hashCode();
263-
}
264260

265261
private static int unboxCharOrInt(Object arg1, int code) {
266262
if (code == CHAR)

src/library/scala/runtime/ScalaRunTime.scala

Lines changed: 13 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,6 @@ object ScalaRunTime {
2929
private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean =
3030
clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1))
3131

32-
def isValueClass(clazz: jClass[_]) = clazz.isPrimitive()
33-
34-
// includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22)
35-
def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple")
36-
def isAnyVal(x: Any) = x match {
37-
case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true
38-
case _ => false
39-
}
40-
4132
// A helper method to make my life in the pattern matcher a lot easier.
4233
def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr =
4334
traversable conversion coll drop num
@@ -50,15 +41,6 @@ object ScalaRunTime {
5041
else java.lang.reflect.Array.newInstance(clazz, 0).getClass
5142
}
5243

53-
/** Return the class object representing elements in arrays described by a given schematic.
54-
*/
55-
def arrayElementClass(schematic: Any): jClass[_] = schematic match {
56-
case cls: jClass[_] => cls.getComponentType
57-
case tag: ClassTag[_] => tag.runtimeClass
58-
case _ =>
59-
throw new UnsupportedOperationException(s"unsupported schematic $schematic (${schematic.getClass})")
60-
}
61-
6244
/** Return the class object representing an unboxed value type,
6345
* e.g., classOf[int], not classOf[java.lang.Integer]. The compiler
6446
* rewrites expressions like 5.getClass to come here.
@@ -116,15 +98,15 @@ object ScalaRunTime {
11698
}
11799

118100
def array_clone(xs: AnyRef): AnyRef = xs match {
119-
case x: Array[AnyRef] => ArrayRuntime.cloneArray(x)
120-
case x: Array[Int] => ArrayRuntime.cloneArray(x)
121-
case x: Array[Double] => ArrayRuntime.cloneArray(x)
122-
case x: Array[Long] => ArrayRuntime.cloneArray(x)
123-
case x: Array[Float] => ArrayRuntime.cloneArray(x)
124-
case x: Array[Char] => ArrayRuntime.cloneArray(x)
125-
case x: Array[Byte] => ArrayRuntime.cloneArray(x)
126-
case x: Array[Short] => ArrayRuntime.cloneArray(x)
127-
case x: Array[Boolean] => ArrayRuntime.cloneArray(x)
101+
case x: Array[AnyRef] => x.clone()
102+
case x: Array[Int] => x.clone()
103+
case x: Array[Double] => x.clone()
104+
case x: Array[Long] => x.clone()
105+
case x: Array[Float] => x.clone()
106+
case x: Array[Char] => x.clone()
107+
case x: Array[Byte] => x.clone()
108+
case x: Array[Short] => x.clone()
109+
case x: Array[Boolean] => x.clone()
128110
case x: Array[Unit] => x
129111
case null => throw new NullPointerException
130112
}
@@ -157,9 +139,6 @@ object ScalaRunTime {
157139
// More background at ticket #2318.
158140
def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m)
159141

160-
def checkInitialized[T <: AnyRef](x: T): T =
161-
if (x == null) throw new UninitializedError else x
162-
163142
def _toString(x: Product): String =
164143
x.productIterator.mkString(x.productPrefix + "(", ",", ")")
165144

@@ -179,72 +158,12 @@ object ScalaRunTime {
179158
}
180159
}
181160

182-
/** Fast path equality method for inlining; used when -optimise is set.
183-
*/
184-
@inline def inlinedEquals(x: Object, y: Object): Boolean =
185-
if (x eq y) true
186-
else if (x eq null) false
187-
else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.equalsNumObject(x.asInstanceOf[java.lang.Number], y)
188-
else if (x.isInstanceOf[java.lang.Character]) BoxesRunTime.equalsCharObject(x.asInstanceOf[java.lang.Character], y)
189-
else x.equals(y)
190-
191-
def _equals(x: Product, y: Any): Boolean = y match {
192-
case y: Product if x.productArity == y.productArity => x.productIterator sameElements y.productIterator
193-
case _ => false
194-
}
195-
196-
// hashcode -----------------------------------------------------------
197-
//
198-
// Note that these are the implementations called by ##, so they
199-
// must not call ## themselves.
200-
161+
/** Implementation of `##`. */
201162
def hash(x: Any): Int =
202163
if (x == null) 0
203164
else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number])
204165
else x.hashCode
205166

206-
def hash(dv: Double): Int = {
207-
val iv = dv.toInt
208-
if (iv == dv) return iv
209-
210-
val lv = dv.toLong
211-
if (lv == dv) return lv.hashCode
212-
213-
val fv = dv.toFloat
214-
if (fv == dv) fv.hashCode else dv.hashCode
215-
}
216-
def hash(fv: Float): Int = {
217-
val iv = fv.toInt
218-
if (iv == fv) return iv
219-
220-
val lv = fv.toLong
221-
if (lv == fv) hash(lv)
222-
else fv.hashCode
223-
}
224-
def hash(lv: Long): Int = {
225-
val low = lv.toInt
226-
val lowSign = low >>> 31
227-
val high = (lv >>> 32).toInt
228-
low ^ (high + lowSign)
229-
}
230-
def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x)
231-
232-
// The remaining overloads are here for completeness, but the compiler
233-
// inlines these definitions directly so they're not generally used.
234-
def hash(x: Int): Int = x
235-
def hash(x: Short): Int = x.toInt
236-
def hash(x: Byte): Int = x.toInt
237-
def hash(x: Char): Int = x.toInt
238-
def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode
239-
def hash(x: Unit): Int = 0
240-
241-
/** A helper method for constructing case class equality methods,
242-
* because existential types get in the way of a clean outcome and
243-
* it's performing a series of Any/Any equals comparisons anyway.
244-
* See ticket #2867 for specifics.
245-
*/
246-
def sameElements(xs1: scala.collection.Seq[Any], xs2: scala.collection.Seq[Any]) = xs1 sameElements xs2
247-
248167
/** Given any Scala value, convert it to a String.
249168
*
250169
* The primary motivation for this method is to provide a means for
@@ -266,6 +185,9 @@ object ScalaRunTime {
266185
def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala."
267186
def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc."
268187

188+
// includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22)
189+
def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple")
190+
269191
// We use reflection because the scala.xml package might not be available
270192
def isSubClassOf(potentialSubClass: Class[_], ofClass: String) =
271193
try {
@@ -345,17 +267,4 @@ object ScalaRunTime {
345267

346268
nl + s + "\n"
347269
}
348-
349-
def box[T](clazz: jClass[T]): jClass[_] = clazz match {
350-
case java.lang.Byte.TYPE => classOf[java.lang.Byte]
351-
case java.lang.Short.TYPE => classOf[java.lang.Short]
352-
case java.lang.Character.TYPE => classOf[java.lang.Character]
353-
case java.lang.Integer.TYPE => classOf[java.lang.Integer]
354-
case java.lang.Long.TYPE => classOf[java.lang.Long]
355-
case java.lang.Float.TYPE => classOf[java.lang.Float]
356-
case java.lang.Double.TYPE => classOf[java.lang.Double]
357-
case java.lang.Void.TYPE => classOf[scala.runtime.BoxedUnit]
358-
case java.lang.Boolean.TYPE => classOf[java.lang.Boolean]
359-
case _ => clazz
360-
}
361270
}

0 commit comments

Comments
 (0)