From b2523fee17389a876af48c683b92e64209ca6105 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 14:10:03 +0200 Subject: [PATCH 01/16] Allow disabling value classes entirely from command line. --- src/dotty/tools/dotc/config/ScalaSettings.scala | 1 + src/dotty/tools/dotc/transform/ValueClasses.scala | 1 + 2 files changed, 2 insertions(+) diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala index 2ad39c3c0faa..2ba9070845c3 100644 --- a/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -88,6 +88,7 @@ class ScalaSettings extends Settings.SettingGroup { val Xshowobj = StringSetting("-Xshow-object", "object", "Show internal representation of object.", "") val showPhases = BooleanSetting("-Xshow-phases", "Print a synopsis of compiler phases.") val sourceReader = StringSetting("-Xsource-reader", "classname", "Specify a custom method for reading source files.", "") + val XnoValueClasses = BooleanSetting("-Xno-value-classes", "Do not use value classes. Helps debugging.") val XoldPatmat = BooleanSetting("-Xoldpatmat", "Use the pre-2.10 pattern matcher. Otherwise, the 'virtualizing' pattern matcher is used in 2.10.") val XnoPatmatAnalysis = BooleanSetting("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.") diff --git a/src/dotty/tools/dotc/transform/ValueClasses.scala b/src/dotty/tools/dotc/transform/ValueClasses.scala index f17a0e75753d..3c7131130c4e 100644 --- a/src/dotty/tools/dotc/transform/ValueClasses.scala +++ b/src/dotty/tools/dotc/transform/ValueClasses.scala @@ -13,6 +13,7 @@ import StdNames._ object ValueClasses { def isDerivedValueClass(d: SymDenotation)(implicit ctx: Context) = { + !ctx.settings.XnoValueClasses.value && !d.isRefinementClass && d.isValueClass && (d.initial.symbol ne defn.AnyValClass) && // Compare the initial symbol because AnyVal does not exist after erasure From fa4b46a8a4337411eefac61d58d68f6497974bd5 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 14:50:44 +0200 Subject: [PATCH 02/16] Add Value classes and array prototypes. Making actual value classes extend this prototypes serves two goals: - This is a basis for implementing arrays of value classes. - Having underlying final in those glasses makes all unbox methods monomorphic and final. - this decreases size of an empty case-class to 1/3 of previous size. --- src/dotty/runtime/vc/VCBooleanPrototype.scala | 43 +++++++++++++++++++ src/dotty/runtime/vc/VCBytePrototype.scala | 43 +++++++++++++++++++ src/dotty/runtime/vc/VCCharPrototype.scala | 43 +++++++++++++++++++ src/dotty/runtime/vc/VCDoublePrototype.scala | 43 +++++++++++++++++++ src/dotty/runtime/vc/VCFloatPrototype.scala | 43 +++++++++++++++++++ src/dotty/runtime/vc/VCIntPrototype.scala | 43 +++++++++++++++++++ src/dotty/runtime/vc/VCLongPrototype.scala | 43 +++++++++++++++++++ src/dotty/runtime/vc/VCObjectPrototype.scala | 43 +++++++++++++++++++ src/dotty/runtime/vc/VCPrototype.scala | 14 ++++++ src/dotty/runtime/vc/VCShortPrototype.scala | 43 +++++++++++++++++++ 10 files changed, 401 insertions(+) create mode 100644 src/dotty/runtime/vc/VCBooleanPrototype.scala create mode 100644 src/dotty/runtime/vc/VCBytePrototype.scala create mode 100644 src/dotty/runtime/vc/VCCharPrototype.scala create mode 100644 src/dotty/runtime/vc/VCDoublePrototype.scala create mode 100644 src/dotty/runtime/vc/VCFloatPrototype.scala create mode 100644 src/dotty/runtime/vc/VCIntPrototype.scala create mode 100644 src/dotty/runtime/vc/VCLongPrototype.scala create mode 100644 src/dotty/runtime/vc/VCObjectPrototype.scala create mode 100644 src/dotty/runtime/vc/VCPrototype.scala create mode 100644 src/dotty/runtime/vc/VCShortPrototype.scala diff --git a/src/dotty/runtime/vc/VCBooleanPrototype.scala b/src/dotty/runtime/vc/VCBooleanPrototype.scala new file mode 100644 index 000000000000..f7ebf276fa10 --- /dev/null +++ b/src/dotty/runtime/vc/VCBooleanPrototype.scala @@ -0,0 +1,43 @@ +package dotty.runtime.vc + +import scala.reflect.ClassTag + +import scala.runtime.Statics + +abstract class VCBooleanPrototype(val underlying: Boolean) extends VCPrototype {} + +abstract class VCBooleanCasePrototype(underlying: Boolean) extends VCBooleanPrototype(underlying) with Product1[Boolean] { + + final def _1: Boolean = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCBooleanCompanion[T <: VCBooleanPrototype] extends ClassTag[T] { + def box(underlying: Boolean): T + final def unbox(boxed: T) = boxed.underlying +} + +final class VCArrayBoolean[T <: VCBooleanPrototype](val ct: VCBooleanCompanion[T], sz: Int) extends VCArrayPrototype[T] { + val arr = new Array[Boolean](sz) + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def toString: String = { + "[" + ct.runtimeClass + } + + // Todo: what was the reason for 255 classes in my original proposal? arr.toString! + // todo: need to discuss do we want to be compatible with ugly format of jvm here? +} diff --git a/src/dotty/runtime/vc/VCBytePrototype.scala b/src/dotty/runtime/vc/VCBytePrototype.scala new file mode 100644 index 000000000000..5a9741551e76 --- /dev/null +++ b/src/dotty/runtime/vc/VCBytePrototype.scala @@ -0,0 +1,43 @@ +package dotty.runtime.vc + +import scala.reflect.ClassTag + +import scala.runtime.Statics + +abstract class VCBytePrototype(val underlying: Byte) extends VCPrototype {} + +abstract class VCByteCasePrototype(underlying: Byte) extends VCBytePrototype(underlying) with Product1[Byte] { + + final def _1: Byte = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { + def box(underlying: Byte): T + final def unbox(boxed: T) = boxed.underlying +} + +final class VCArrayByte[T <: VCBytePrototype](val ct: VCByteCompanion[T], sz: Int) extends VCArrayPrototype[T] { + val arr = new Array[Byte](sz) + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def toString: String = { + "[" + ct.runtimeClass + } + + // Todo: what was the reason for 255 classes in my original proposal? arr.toString! + // todo: need to discuss do we want to be compatible with ugly format of jvm here? +} diff --git a/src/dotty/runtime/vc/VCCharPrototype.scala b/src/dotty/runtime/vc/VCCharPrototype.scala new file mode 100644 index 000000000000..f46514d0ce09 --- /dev/null +++ b/src/dotty/runtime/vc/VCCharPrototype.scala @@ -0,0 +1,43 @@ +package dotty.runtime.vc + +import scala.reflect.ClassTag + +import scala.runtime.Statics + +abstract class VCCharPrototype(val underlying: Char) extends VCPrototype {} + +abstract class VCCharCasePrototype(underlying: Char) extends VCCharPrototype(underlying) with Product1[Char] { + + final def _1: Char = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { + def box(underlying: Char): T + final def unbox(boxed: T) = boxed.underlying +} + +final class VCArrayChar[T <: VCCharPrototype](val ct: VCCharCompanion[T], sz: Int) extends VCArrayPrototype[T] { + val arr = new Array[Char](sz) + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def toString: String = { + "[" + ct.runtimeClass + } + + // Todo: what was the reason for 255 classes in my original proposal? arr.toString! + // todo: need to discuss do we want to be compatible with ugly format of jvm here? +} diff --git a/src/dotty/runtime/vc/VCDoublePrototype.scala b/src/dotty/runtime/vc/VCDoublePrototype.scala new file mode 100644 index 000000000000..5a8c9041bdaa --- /dev/null +++ b/src/dotty/runtime/vc/VCDoublePrototype.scala @@ -0,0 +1,43 @@ +package dotty.runtime.vc + +import scala.reflect.ClassTag + +import scala.runtime.Statics + +abstract class VCDoublePrototype(val underlying: Double) extends VCPrototype {} + +abstract class VCDoubleCasePrototype(underlying: Double) extends VCDoublePrototype(underlying) with Product1[Double] { + + final def _1: Double = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { + def box(underlying: Double): T + final def unbox(boxed: T) = boxed.underlying +} + +final class VCArrayDouble[T <: VCDoublePrototype](val ct: VCDoubleCompanion[T], sz: Int) extends VCArrayPrototype[T] { + val arr = new Array[Double](sz) + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def toString: String = { + "[" + ct.runtimeClass + } + + // Todo: what was the reason for 255 classes in my original proposal? arr.toString! + // todo: need to discuss do we want to be compatible with ugly format of jvm here? +} diff --git a/src/dotty/runtime/vc/VCFloatPrototype.scala b/src/dotty/runtime/vc/VCFloatPrototype.scala new file mode 100644 index 000000000000..b1b682a24dfb --- /dev/null +++ b/src/dotty/runtime/vc/VCFloatPrototype.scala @@ -0,0 +1,43 @@ +package dotty.runtime.vc + +import scala.reflect.ClassTag + +import scala.runtime.Statics + +abstract class VCFloatPrototype(val underlying: Float) extends VCPrototype {} + +abstract class VCFloatCasePrototype(underlying: Float) extends VCFloatPrototype(underlying) with Product1[Float] { + + final def _1: Float = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { + def box(underlying: Float): T + final def unbox(boxed: T) = boxed.underlying +} + +final class VCArrayFloat[T <: VCFloatPrototype](val ct: VCFloatCompanion[T], sz: Int) extends VCArrayPrototype[T] { + val arr = new Array[Float](sz) + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def toString: String = { + "[" + ct.runtimeClass + } + + // Todo: what was the reason for 255 classes in my original proposal? arr.toString! + // todo: need to discuss do we want to be compatible with ugly format of jvm here? +} diff --git a/src/dotty/runtime/vc/VCIntPrototype.scala b/src/dotty/runtime/vc/VCIntPrototype.scala new file mode 100644 index 000000000000..3f4b580b58de --- /dev/null +++ b/src/dotty/runtime/vc/VCIntPrototype.scala @@ -0,0 +1,43 @@ +package dotty.runtime.vc + +import scala.reflect.ClassTag + +import scala.runtime.Statics + +abstract class VCIntPrototype(val underlying: Int) extends VCPrototype {} + +abstract class VCIntCasePrototype(underlying: Int) extends VCIntPrototype(underlying) with Product1[Int] { + + final def _1: Int = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { + def box(underlying: Int): T + final def unbox(boxed: T) = boxed.underlying +} + +final class VCArrayInt[T <: VCIntPrototype](val ct: VCIntCompanion[T], sz: Int) extends VCArrayPrototype[T] { + val arr = new Array[Int](sz) + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def toString: String = { + "[" + ct.runtimeClass + } + + // Todo: what was the reason for 255 classes in my original proposal? arr.toString! + // todo: need to discuss do we want to be compatible with ugly format of jvm here? +} diff --git a/src/dotty/runtime/vc/VCLongPrototype.scala b/src/dotty/runtime/vc/VCLongPrototype.scala new file mode 100644 index 000000000000..83f5c83b8814 --- /dev/null +++ b/src/dotty/runtime/vc/VCLongPrototype.scala @@ -0,0 +1,43 @@ +package dotty.runtime.vc + +import scala.reflect.ClassTag + +import scala.runtime.Statics + +abstract class VCLongPrototype(val underlying: Long) extends VCPrototype {} + +abstract class VCLongCasePrototype(underlying: Long) extends VCLongPrototype(underlying) with Product1[Long] { + + final def _1: Long = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { + def box(underlying: Long): T + final def unbox(boxed: T) = boxed.underlying +} + +final class VCArrayLong[T <: VCLongPrototype](val ct: VCLongCompanion[T], sz: Int) extends VCArrayPrototype[T] { + val arr = new Array[Long](sz) + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def toString: String = { + "[" + ct.runtimeClass + } + + // Todo: what was the reason for 255 classes in my original proposal? arr.toString! + // todo: need to discuss do we want to be compatible with ugly format of jvm here? +} diff --git a/src/dotty/runtime/vc/VCObjectPrototype.scala b/src/dotty/runtime/vc/VCObjectPrototype.scala new file mode 100644 index 000000000000..fedbc57ff5c6 --- /dev/null +++ b/src/dotty/runtime/vc/VCObjectPrototype.scala @@ -0,0 +1,43 @@ +package dotty.runtime.vc + +import scala.reflect.ClassTag + +import scala.runtime.Statics + +abstract class VCObjectPrototype(val underlying: Object) extends VCPrototype {} + +abstract class VCObjectCasePrototype(underlying: Object) extends VCObjectPrototype(underlying) with Product1[Object] { + + final def _1: Object = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { + def box(underlying: Object): T + final def unbox(boxed: T) = boxed.underlying +} + +final class VCArrayObject[T <: VCObjectPrototype](val ct: VCObjectCompanion[T], sz: Int) extends VCArrayPrototype[T] { + val arr = new Array[Object](sz) + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def toString: String = { + "[" + ct.runtimeClass + } + + // Todo: what was the reason for 255 classes in my original proposal? arr.toString! + // todo: need to discuss do we want to be compatible with ugly format of jvm here? +} diff --git a/src/dotty/runtime/vc/VCPrototype.scala b/src/dotty/runtime/vc/VCPrototype.scala new file mode 100644 index 000000000000..5b43e74f468a --- /dev/null +++ b/src/dotty/runtime/vc/VCPrototype.scala @@ -0,0 +1,14 @@ +package dotty.runtime.vc + +abstract class VCPrototype { +} + +abstract class VCCompanionPrototype { + +} + +abstract class VCArrayPrototype[T <: VCPrototype] { + def apply(idx: Int): Object + def update(idx: Int, el: T): Unit + def length: Int +} diff --git a/src/dotty/runtime/vc/VCShortPrototype.scala b/src/dotty/runtime/vc/VCShortPrototype.scala new file mode 100644 index 000000000000..92711c709591 --- /dev/null +++ b/src/dotty/runtime/vc/VCShortPrototype.scala @@ -0,0 +1,43 @@ +package dotty.runtime.vc + +import scala.reflect.ClassTag + +import scala.runtime.Statics + +abstract class VCShortPrototype(val underlying: Short) extends VCPrototype {} + +abstract class VCShortCasePrototype(underlying: Short) extends VCShortPrototype(underlying) with Product1[Short] { + + final def _1: Short = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { + def box(underlying: Short): T + final def unbox(boxed: T) = boxed.underlying +} + +final class VCArrayShort[T <: VCShortPrototype](val ct: VCShortCompanion[T], sz: Int) extends VCArrayPrototype[T] { + val arr = new Array[Short](sz) + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def toString: String = { + "[" + ct.runtimeClass + } + + // Todo: what was the reason for 255 classes in my original proposal? arr.toString! + // todo: need to discuss do we want to be compatible with ugly format of jvm here? +} From 7eca8788ef9c16de94263c3b3ebdcbac262307a6 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 14:52:04 +0200 Subject: [PATCH 03/16] implement templates for value class companions. Decreases the size of companion of case value class to 1/8 of it's original size. --- src/dotty/runtime/vc/VCBooleanPrototype.scala | 5 +++++ src/dotty/runtime/vc/VCBytePrototype.scala | 5 +++++ src/dotty/runtime/vc/VCCharPrototype.scala | 5 +++++ src/dotty/runtime/vc/VCDoublePrototype.scala | 5 +++++ src/dotty/runtime/vc/VCFloatPrototype.scala | 5 +++++ src/dotty/runtime/vc/VCIntPrototype.scala | 9 +++++++-- src/dotty/runtime/vc/VCLongPrototype.scala | 5 +++++ src/dotty/runtime/vc/VCObjectPrototype.scala | 5 +++++ src/dotty/runtime/vc/VCShortPrototype.scala | 5 +++++ 9 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/dotty/runtime/vc/VCBooleanPrototype.scala b/src/dotty/runtime/vc/VCBooleanPrototype.scala index f7ebf276fa10..f9e12a4451a0 100644 --- a/src/dotty/runtime/vc/VCBooleanPrototype.scala +++ b/src/dotty/runtime/vc/VCBooleanPrototype.scala @@ -24,6 +24,11 @@ abstract class VCBooleanCasePrototype(underlying: Boolean) extends VCBooleanProt abstract class VCBooleanCompanion[T <: VCBooleanPrototype] extends ClassTag[T] { def box(underlying: Boolean): T final def unbox(boxed: T) = boxed.underlying + + final def _1$extension(underlying: Boolean) = underlying + final def hashCode$extension(underlying: Boolean) = underlying.hashCode() + final def toString$extension(underlying: Boolean) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Boolean): String } final class VCArrayBoolean[T <: VCBooleanPrototype](val ct: VCBooleanCompanion[T], sz: Int) extends VCArrayPrototype[T] { diff --git a/src/dotty/runtime/vc/VCBytePrototype.scala b/src/dotty/runtime/vc/VCBytePrototype.scala index 5a9741551e76..57c5ec443c7d 100644 --- a/src/dotty/runtime/vc/VCBytePrototype.scala +++ b/src/dotty/runtime/vc/VCBytePrototype.scala @@ -24,6 +24,11 @@ abstract class VCByteCasePrototype(underlying: Byte) extends VCBytePrototype(und abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { def box(underlying: Byte): T final def unbox(boxed: T) = boxed.underlying + + final def _1$extension(underlying: Byte) = underlying + final def hashCode$extension(underlying: Byte) = underlying.hashCode() + final def toString$extension(underlying: Byte) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Byte): String } final class VCArrayByte[T <: VCBytePrototype](val ct: VCByteCompanion[T], sz: Int) extends VCArrayPrototype[T] { diff --git a/src/dotty/runtime/vc/VCCharPrototype.scala b/src/dotty/runtime/vc/VCCharPrototype.scala index f46514d0ce09..895eff61e3be 100644 --- a/src/dotty/runtime/vc/VCCharPrototype.scala +++ b/src/dotty/runtime/vc/VCCharPrototype.scala @@ -24,6 +24,11 @@ abstract class VCCharCasePrototype(underlying: Char) extends VCCharPrototype(und abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { def box(underlying: Char): T final def unbox(boxed: T) = boxed.underlying + + final def _1$extension(underlying: Char) = underlying + final def hashCode$extension(underlying: Char) = underlying.hashCode() + final def toString$extension(underlying: Char) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Char): String } final class VCArrayChar[T <: VCCharPrototype](val ct: VCCharCompanion[T], sz: Int) extends VCArrayPrototype[T] { diff --git a/src/dotty/runtime/vc/VCDoublePrototype.scala b/src/dotty/runtime/vc/VCDoublePrototype.scala index 5a8c9041bdaa..7037d868445a 100644 --- a/src/dotty/runtime/vc/VCDoublePrototype.scala +++ b/src/dotty/runtime/vc/VCDoublePrototype.scala @@ -24,6 +24,11 @@ abstract class VCDoubleCasePrototype(underlying: Double) extends VCDoublePrototy abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { def box(underlying: Double): T final def unbox(boxed: T) = boxed.underlying + + final def _1$extension(underlying: Double) = underlying + final def hashCode$extension(underlying: Double) = underlying.hashCode() + final def toString$extension(underlying: Double) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Double): String } final class VCArrayDouble[T <: VCDoublePrototype](val ct: VCDoubleCompanion[T], sz: Int) extends VCArrayPrototype[T] { diff --git a/src/dotty/runtime/vc/VCFloatPrototype.scala b/src/dotty/runtime/vc/VCFloatPrototype.scala index b1b682a24dfb..07c0fd8ebdec 100644 --- a/src/dotty/runtime/vc/VCFloatPrototype.scala +++ b/src/dotty/runtime/vc/VCFloatPrototype.scala @@ -24,6 +24,11 @@ abstract class VCFloatCasePrototype(underlying: Float) extends VCFloatPrototype( abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { def box(underlying: Float): T final def unbox(boxed: T) = boxed.underlying + + final def _1$extension(underlying: Float) = underlying + final def hashCode$extension(underlying: Float) = underlying.hashCode() + final def toString$extension(underlying: Float) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Float): String } final class VCArrayFloat[T <: VCFloatPrototype](val ct: VCFloatCompanion[T], sz: Int) extends VCArrayPrototype[T] { diff --git a/src/dotty/runtime/vc/VCIntPrototype.scala b/src/dotty/runtime/vc/VCIntPrototype.scala index 3f4b580b58de..377c36ec9365 100644 --- a/src/dotty/runtime/vc/VCIntPrototype.scala +++ b/src/dotty/runtime/vc/VCIntPrototype.scala @@ -22,8 +22,13 @@ abstract class VCIntCasePrototype(underlying: Int) extends VCIntPrototype(underl } abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { - def box(underlying: Int): T - final def unbox(boxed: T) = boxed.underlying + def box(underlying: Int): T + final def unbox(boxed: T) = boxed.underlying + + final def _1$extension(underlying: Int) = underlying + final def hashCode$extension(underlying: Int) = underlying.hashCode() + final def toString$extension(underlying: Int) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Int): String } final class VCArrayInt[T <: VCIntPrototype](val ct: VCIntCompanion[T], sz: Int) extends VCArrayPrototype[T] { diff --git a/src/dotty/runtime/vc/VCLongPrototype.scala b/src/dotty/runtime/vc/VCLongPrototype.scala index 83f5c83b8814..855acab5d40c 100644 --- a/src/dotty/runtime/vc/VCLongPrototype.scala +++ b/src/dotty/runtime/vc/VCLongPrototype.scala @@ -24,6 +24,11 @@ abstract class VCLongCasePrototype(underlying: Long) extends VCLongPrototype(und abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { def box(underlying: Long): T final def unbox(boxed: T) = boxed.underlying + + final def _1$extension(underlying: Long) = underlying + final def hashCode$extension(underlying: Long) = underlying.hashCode() + final def toString$extension(underlying: Long) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Long): String } final class VCArrayLong[T <: VCLongPrototype](val ct: VCLongCompanion[T], sz: Int) extends VCArrayPrototype[T] { diff --git a/src/dotty/runtime/vc/VCObjectPrototype.scala b/src/dotty/runtime/vc/VCObjectPrototype.scala index fedbc57ff5c6..bce50d9f10b5 100644 --- a/src/dotty/runtime/vc/VCObjectPrototype.scala +++ b/src/dotty/runtime/vc/VCObjectPrototype.scala @@ -24,6 +24,11 @@ abstract class VCObjectCasePrototype(underlying: Object) extends VCObjectPrototy abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { def box(underlying: Object): T final def unbox(boxed: T) = boxed.underlying + + final def _1$extension(underlying: Object) = underlying + final def hashCode$extension(underlying: Object) = underlying.hashCode() + final def toString$extension(underlying: Object) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Object): String } final class VCArrayObject[T <: VCObjectPrototype](val ct: VCObjectCompanion[T], sz: Int) extends VCArrayPrototype[T] { diff --git a/src/dotty/runtime/vc/VCShortPrototype.scala b/src/dotty/runtime/vc/VCShortPrototype.scala index 92711c709591..36753e14a37b 100644 --- a/src/dotty/runtime/vc/VCShortPrototype.scala +++ b/src/dotty/runtime/vc/VCShortPrototype.scala @@ -24,6 +24,11 @@ abstract class VCShortCasePrototype(underlying: Short) extends VCShortPrototype( abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { def box(underlying: Short): T final def unbox(boxed: T) = boxed.underlying + + final def _1$extension(underlying: Short) = underlying + final def hashCode$extension(underlying: Short) = underlying.hashCode() + final def toString$extension(underlying: Short) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Short): String } final class VCArrayShort[T <: VCShortPrototype](val ct: VCShortCompanion[T], sz: Int) extends VCArrayPrototype[T] { From 5c68af8badf42954ad8eeedb7845d458eab50692 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 14:59:13 +0200 Subject: [PATCH 04/16] Add array creations to class tags of value classes. Works as Array[T] is erased to Object. --- src/dotty/runtime/vc/VCBooleanPrototype.scala | 3 +++ src/dotty/runtime/vc/VCBytePrototype.scala | 2 ++ src/dotty/runtime/vc/VCCharPrototype.scala | 2 ++ src/dotty/runtime/vc/VCDoublePrototype.scala | 2 ++ src/dotty/runtime/vc/VCFloatPrototype.scala | 2 ++ src/dotty/runtime/vc/VCIntPrototype.scala | 2 ++ src/dotty/runtime/vc/VCLongPrototype.scala | 2 ++ src/dotty/runtime/vc/VCObjectPrototype.scala | 2 ++ src/dotty/runtime/vc/VCShortPrototype.scala | 2 ++ 9 files changed, 19 insertions(+) diff --git a/src/dotty/runtime/vc/VCBooleanPrototype.scala b/src/dotty/runtime/vc/VCBooleanPrototype.scala index f9e12a4451a0..e51e7f647095 100644 --- a/src/dotty/runtime/vc/VCBooleanPrototype.scala +++ b/src/dotty/runtime/vc/VCBooleanPrototype.scala @@ -24,6 +24,9 @@ abstract class VCBooleanCasePrototype(underlying: Boolean) extends VCBooleanProt abstract class VCBooleanCompanion[T <: VCBooleanPrototype] extends ClassTag[T] { def box(underlying: Boolean): T final def unbox(boxed: T) = boxed.underlying + override def newArray(len: Int): Array[T] = + new VCArrayBoolean(this, len).asInstanceOf[Array[T]] + final def _1$extension(underlying: Boolean) = underlying final def hashCode$extension(underlying: Boolean) = underlying.hashCode() diff --git a/src/dotty/runtime/vc/VCBytePrototype.scala b/src/dotty/runtime/vc/VCBytePrototype.scala index 57c5ec443c7d..734f830e041f 100644 --- a/src/dotty/runtime/vc/VCBytePrototype.scala +++ b/src/dotty/runtime/vc/VCBytePrototype.scala @@ -24,6 +24,8 @@ abstract class VCByteCasePrototype(underlying: Byte) extends VCBytePrototype(und abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { def box(underlying: Byte): T final def unbox(boxed: T) = boxed.underlying + override def newArray(len: Int): Array[T] = + new VCArrayByte(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Byte) = underlying final def hashCode$extension(underlying: Byte) = underlying.hashCode() diff --git a/src/dotty/runtime/vc/VCCharPrototype.scala b/src/dotty/runtime/vc/VCCharPrototype.scala index 895eff61e3be..60e1dc8ff494 100644 --- a/src/dotty/runtime/vc/VCCharPrototype.scala +++ b/src/dotty/runtime/vc/VCCharPrototype.scala @@ -24,6 +24,8 @@ abstract class VCCharCasePrototype(underlying: Char) extends VCCharPrototype(und abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { def box(underlying: Char): T final def unbox(boxed: T) = boxed.underlying + override def newArray(len: Int): Array[T] = + new VCArrayChar(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Char) = underlying final def hashCode$extension(underlying: Char) = underlying.hashCode() diff --git a/src/dotty/runtime/vc/VCDoublePrototype.scala b/src/dotty/runtime/vc/VCDoublePrototype.scala index 7037d868445a..091f8be4323e 100644 --- a/src/dotty/runtime/vc/VCDoublePrototype.scala +++ b/src/dotty/runtime/vc/VCDoublePrototype.scala @@ -24,6 +24,8 @@ abstract class VCDoubleCasePrototype(underlying: Double) extends VCDoublePrototy abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { def box(underlying: Double): T final def unbox(boxed: T) = boxed.underlying + override def newArray(len: Int): Array[T] = + new VCArrayDouble(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Double) = underlying final def hashCode$extension(underlying: Double) = underlying.hashCode() diff --git a/src/dotty/runtime/vc/VCFloatPrototype.scala b/src/dotty/runtime/vc/VCFloatPrototype.scala index 07c0fd8ebdec..fefb05a19384 100644 --- a/src/dotty/runtime/vc/VCFloatPrototype.scala +++ b/src/dotty/runtime/vc/VCFloatPrototype.scala @@ -24,6 +24,8 @@ abstract class VCFloatCasePrototype(underlying: Float) extends VCFloatPrototype( abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { def box(underlying: Float): T final def unbox(boxed: T) = boxed.underlying + override def newArray(len: Int): Array[T] = + new VCArrayFloat(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Float) = underlying final def hashCode$extension(underlying: Float) = underlying.hashCode() diff --git a/src/dotty/runtime/vc/VCIntPrototype.scala b/src/dotty/runtime/vc/VCIntPrototype.scala index 377c36ec9365..8e6980ec4f40 100644 --- a/src/dotty/runtime/vc/VCIntPrototype.scala +++ b/src/dotty/runtime/vc/VCIntPrototype.scala @@ -24,6 +24,8 @@ abstract class VCIntCasePrototype(underlying: Int) extends VCIntPrototype(underl abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { def box(underlying: Int): T final def unbox(boxed: T) = boxed.underlying + override def newArray(len: Int): Array[T] = + new VCArrayInt(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Int) = underlying final def hashCode$extension(underlying: Int) = underlying.hashCode() diff --git a/src/dotty/runtime/vc/VCLongPrototype.scala b/src/dotty/runtime/vc/VCLongPrototype.scala index 855acab5d40c..0d92a2af5c27 100644 --- a/src/dotty/runtime/vc/VCLongPrototype.scala +++ b/src/dotty/runtime/vc/VCLongPrototype.scala @@ -24,6 +24,8 @@ abstract class VCLongCasePrototype(underlying: Long) extends VCLongPrototype(und abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { def box(underlying: Long): T final def unbox(boxed: T) = boxed.underlying + override def newArray(len: Int): Array[T] = + new VCArrayLong(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Long) = underlying final def hashCode$extension(underlying: Long) = underlying.hashCode() diff --git a/src/dotty/runtime/vc/VCObjectPrototype.scala b/src/dotty/runtime/vc/VCObjectPrototype.scala index bce50d9f10b5..45982e3404c1 100644 --- a/src/dotty/runtime/vc/VCObjectPrototype.scala +++ b/src/dotty/runtime/vc/VCObjectPrototype.scala @@ -24,6 +24,8 @@ abstract class VCObjectCasePrototype(underlying: Object) extends VCObjectPrototy abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { def box(underlying: Object): T final def unbox(boxed: T) = boxed.underlying + override def newArray(len: Int): Array[T] = + new VCArrayObject(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Object) = underlying final def hashCode$extension(underlying: Object) = underlying.hashCode() diff --git a/src/dotty/runtime/vc/VCShortPrototype.scala b/src/dotty/runtime/vc/VCShortPrototype.scala index 36753e14a37b..e39a5d630e71 100644 --- a/src/dotty/runtime/vc/VCShortPrototype.scala +++ b/src/dotty/runtime/vc/VCShortPrototype.scala @@ -24,6 +24,8 @@ abstract class VCShortCasePrototype(underlying: Short) extends VCShortPrototype( abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { def box(underlying: Short): T final def unbox(boxed: T) = boxed.underlying + override def newArray(len: Int): Array[T] = + new VCArrayShort(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Short) = underlying final def hashCode$extension(underlying: Short) = underlying.hashCode() From 68d12d3745e8e7f71d98d9101e9aaa348070c3b0 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 14:59:31 +0200 Subject: [PATCH 05/16] Remove VCCompanionPrototype: it is not used. --- src/dotty/runtime/vc/VCPrototype.scala | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/dotty/runtime/vc/VCPrototype.scala b/src/dotty/runtime/vc/VCPrototype.scala index 5b43e74f468a..4ece214e9e26 100644 --- a/src/dotty/runtime/vc/VCPrototype.scala +++ b/src/dotty/runtime/vc/VCPrototype.scala @@ -3,10 +3,6 @@ package dotty.runtime.vc abstract class VCPrototype { } -abstract class VCCompanionPrototype { - -} - abstract class VCArrayPrototype[T <: VCPrototype] { def apply(idx: Int): Object def update(idx: Int, el: T): Unit From 955874613eb31b3709d178d0ff5d7e02bad7bcc4 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 15:01:22 +0200 Subject: [PATCH 06/16] Fork ScalaRuntime to support arrays of value classes. --- src/scala/runtime/ScalaRunTime/scala.scala | 363 +++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 src/scala/runtime/ScalaRunTime/scala.scala diff --git a/src/scala/runtime/ScalaRunTime/scala.scala b/src/scala/runtime/ScalaRunTime/scala.scala new file mode 100644 index 000000000000..fde7b7e10cde --- /dev/null +++ b/src/scala/runtime/ScalaRunTime/scala.scala @@ -0,0 +1,363 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala +package runtime + +import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator } +import scala.collection.mutable.WrappedArray +import scala.collection.immutable.{ StringLike, NumericRange, List, Stream, Nil, :: } +import scala.collection.generic.{ Sorted, IsTraversableLike } +import scala.reflect.{ ClassTag, classTag } +import scala.util.control.ControlThrowable +import java.lang.{ Class => jClass } + +import java.lang.Double.doubleToLongBits +import java.lang.reflect.{ Modifier, Method => JMethod } + +/** The object ScalaRunTime provides support methods required by + * the scala runtime. All these methods should be considered + * outside the API and subject to change or removal without notice. + */ +object ScalaRunTime { + def isArray(x: Any, atLevel: Int = 1): Boolean = + x != null && isArrayClass(x.getClass, atLevel) + + private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = + clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + + def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() + + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") + def isAnyVal(x: Any) = x match { + case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true + case _ => false + } + + // A helper method to make my life in the pattern matcher a lot easier. + def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr = + traversable conversion coll drop num + + /** Return the class object representing an array with element class `clazz`. + */ + def arrayClass(clazz: jClass[_]): jClass[_] = { + // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 + if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(clazz, 0).getClass + } + + /** Return the class object representing elements in arrays described by a given schematic. + */ + def arrayElementClass(schematic: Any): jClass[_] = schematic match { + case cls: jClass[_] => cls.getComponentType + case tag: ClassTag[_] => tag.runtimeClass + case _ => + throw new UnsupportedOperationException(s"unsupported schematic $schematic (${schematic.getClass})") + } + + /** Return the class object representing an unboxed value type, + * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler + * rewrites expressions like 5.getClass to come here. + */ + def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = + classTag[T].runtimeClass.asInstanceOf[jClass[T]] + + /** Retrieve generic array element */ + def array_apply(xs: AnyRef, idx: Int): Any = { + xs match { + case x: Array[AnyRef] => x(idx).asInstanceOf[Any] + case x: Array[Int] => x(idx).asInstanceOf[Any] + case x: Array[Double] => x(idx).asInstanceOf[Any] + case x: Array[Long] => x(idx).asInstanceOf[Any] + case x: Array[Float] => x(idx).asInstanceOf[Any] + case x: Array[Char] => x(idx).asInstanceOf[Any] + case x: Array[Byte] => x(idx).asInstanceOf[Any] + case x: Array[Short] => x(idx).asInstanceOf[Any] + case x: Array[Boolean] => x(idx).asInstanceOf[Any] + case x: Array[Unit] => x(idx).asInstanceOf[Any] + case null => throw new NullPointerException + } + } + + /** update generic array element */ + def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { + xs match { + case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] + case x: Array[Int] => x(idx) = value.asInstanceOf[Int] + case x: Array[Double] => x(idx) = value.asInstanceOf[Double] + case x: Array[Long] => x(idx) = value.asInstanceOf[Long] + case x: Array[Float] => x(idx) = value.asInstanceOf[Float] + case x: Array[Char] => x(idx) = value.asInstanceOf[Char] + case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] + case x: Array[Short] => x(idx) = value.asInstanceOf[Short] + case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] + case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case null => throw new NullPointerException + } + } + + /** Get generic array length */ + def array_length(xs: AnyRef): Int = xs match { + case x: Array[AnyRef] => x.length + case x: Array[Int] => x.length + case x: Array[Double] => x.length + case x: Array[Long] => x.length + case x: Array[Float] => x.length + case x: Array[Char] => x.length + case x: Array[Byte] => x.length + case x: Array[Short] => x.length + case x: Array[Boolean] => x.length + case x: Array[Unit] => x.length + case null => throw new NullPointerException + } + + def array_clone(xs: AnyRef): AnyRef = xs match { + case x: Array[AnyRef] => ArrayRuntime.cloneArray(x) + case x: Array[Int] => ArrayRuntime.cloneArray(x) + case x: Array[Double] => ArrayRuntime.cloneArray(x) + case x: Array[Long] => ArrayRuntime.cloneArray(x) + case x: Array[Float] => ArrayRuntime.cloneArray(x) + case x: Array[Char] => ArrayRuntime.cloneArray(x) + case x: Array[Byte] => ArrayRuntime.cloneArray(x) + case x: Array[Short] => ArrayRuntime.cloneArray(x) + case x: Array[Boolean] => ArrayRuntime.cloneArray(x) + case x: Array[Unit] => x + case null => throw new NullPointerException + } + + /** Convert an array to an object array. + * Needed to deal with vararg arguments of primitive types that are passed + * to a generic Java vararg parameter T ... + */ + def toObjectArray(src: AnyRef): Array[Object] = src match { + case x: Array[AnyRef] => x + case _ => + val length = array_length(src) + val dest = new Array[Object](length) + for (i <- 0 until length) + array_update(dest, i, array_apply(src, i)) + dest + } + + def toArray[T](xs: scala.collection.Seq[T]) = { + val arr = new Array[AnyRef](xs.length) + var i = 0 + for (x <- xs) { + arr(i) = x.asInstanceOf[AnyRef] + i += 1 + } + arr + } + + // Java bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957 + // More background at ticket #2318. + def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) + + def checkInitialized[T <: AnyRef](x: T): T = + if (x == null) throw new UninitializedError else x + + def _toString(x: Product): String = + x.productIterator.mkString(x.productPrefix + "(", ",", ")") + + def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) + + /** A helper for case classes. */ + def typedProductIterator[T](x: Product): Iterator[T] = { + new AbstractIterator[T] { + private var c: Int = 0 + private val cmax = x.productArity + def hasNext = c < cmax + def next() = { + val result = x.productElement(c) + c += 1 + result.asInstanceOf[T] + } + } + } + + /** Fast path equality method for inlining; used when -optimise is set. + */ + @inline def inlinedEquals(x: Object, y: Object): Boolean = + if (x eq y) true + else if (x eq null) false + else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.equalsNumObject(x.asInstanceOf[java.lang.Number], y) + else if (x.isInstanceOf[java.lang.Character]) BoxesRunTime.equalsCharObject(x.asInstanceOf[java.lang.Character], y) + else x.equals(y) + + def _equals(x: Product, y: Any): Boolean = y match { + case y: Product if x.productArity == y.productArity => x.productIterator sameElements y.productIterator + case _ => false + } + + // hashcode ----------------------------------------------------------- + // + // Note that these are the implementations called by ##, so they + // must not call ## themselves. + + def hash(x: Any): Int = + if (x == null) 0 + else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) + else x.hashCode + + def hash(dv: Double): Int = { + val iv = dv.toInt + if (iv == dv) return iv + + val lv = dv.toLong + if (lv == dv) return lv.hashCode + + val fv = dv.toFloat + if (fv == dv) fv.hashCode else dv.hashCode + } + def hash(fv: Float): Int = { + val iv = fv.toInt + if (iv == fv) return iv + + val lv = fv.toLong + if (lv == fv) hash(lv) + else fv.hashCode + } + def hash(lv: Long): Int = { + val low = lv.toInt + val lowSign = low >>> 31 + val high = (lv >>> 32).toInt + low ^ (high + lowSign) + } + def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x) + + // The remaining overloads are here for completeness, but the compiler + // inlines these definitions directly so they're not generally used. + def hash(x: Int): Int = x + def hash(x: Short): Int = x.toInt + def hash(x: Byte): Int = x.toInt + def hash(x: Char): Int = x.toInt + def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode + def hash(x: Unit): Int = 0 + + /** A helper method for constructing case class equality methods, + * because existential types get in the way of a clean outcome and + * it's performing a series of Any/Any equals comparisons anyway. + * See ticket #2867 for specifics. + */ + def sameElements(xs1: scala.collection.Seq[Any], xs2: scala.collection.Seq[Any]) = xs1 sameElements xs2 + + /** Given any Scala value, convert it to a String. + * + * The primary motivation for this method is to provide a means for + * correctly obtaining a String representation of a value, while + * avoiding the pitfalls of naïvely calling toString on said value. + * In particular, it addresses the fact that (a) toString cannot be + * called on null and (b) depending on the apparent type of an + * array, toString may or may not print it in a human-readable form. + * + * @param arg the value to stringify + * @return a string representation of arg. + */ + def stringOf(arg: Any): String = stringOf(arg, scala.Int.MaxValue) + def stringOf(arg: Any, maxElements: Int): String = { + def packageOf(x: AnyRef) = x.getClass.getPackage match { + case null => "" + case p => p.getName + } + def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." + def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." + + // We use reflection because the scala.xml package might not be available + def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = + try { + val classLoader = potentialSubClass.getClassLoader + val clazz = Class.forName(ofClass, /*initialize =*/ false, classLoader) + clazz.isAssignableFrom(potentialSubClass) + } catch { + case cnfe: ClassNotFoundException => false + } + def isXmlNode(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.Node") + def isXmlMetaData(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.MetaData") + + // When doing our own iteration is dangerous + def useOwnToString(x: Any) = x match { + // Range/NumericRange have a custom toString to avoid walking a gazillion elements + case _: Range | _: NumericRange[_] => true + // Sorted collections to the wrong thing (for us) on iteration - ticket #3493 + case _: Sorted[_, _] => true + // StringBuilder(a, b, c) and similar not so attractive + case _: StringLike[_] => true + // Don't want to evaluate any elements in a view + case _: TraversableView[_, _] => true + // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] + // -> catch those by isXmlNode and isXmlMetaData. + // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom + // collections which may have useful toString methods - ticket #3710 + // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. + case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlNode(x.getClass) || isXmlMetaData(x.getClass) + // Otherwise, nothing could possibly go wrong + case _ => false + } + + // A variation on inner for maps so they print -> instead of bare tuples + def mapInner(arg: Any): String = arg match { + case (k, v) => inner(k) + " -> " + inner(v) + case _ => inner(arg) + } + + // Special casing Unit arrays, the value class which uses a reference array type. + def arrayToString(x: AnyRef) = { + if (x.getClass.getComponentType == classOf[BoxedUnit]) + 0 until (array_length(x) min maxElements) map (_ => "()") mkString ("Array(", ", ", ")") + else + WrappedArray make x take maxElements map inner mkString ("Array(", ", ", ")") + } + + // The recursively applied attempt to prettify Array printing. + // Note that iterator is used if possible and foreach is used as a + // last resort, because the parallel collections "foreach" in a + // random order even on sequences. + def inner(arg: Any): String = arg match { + case null => "null" + case "" => "\"\"" + case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x + case x if useOwnToString(x) => x.toString + case x: AnyRef if isArray(x) => arrayToString(x) + case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") + case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") + case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma + case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") + case x => x.toString + } + + // The try/catch is defense against iterables which aren't actually designed + // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. + try inner(arg) + catch { + case _: UnsupportedOperationException | _: AssertionError => "" + arg + } + } + + /** stringOf formatted for use in a repl result. */ + def replStringOf(arg: Any, maxElements: Int): String = { + val s = stringOf(arg, maxElements) + val nl = if (s contains "\n") "\n" else "" + + nl + s + "\n" + } + + def box[T](clazz: jClass[T]): jClass[_] = clazz match { + case java.lang.Byte.TYPE => classOf[java.lang.Byte] + case java.lang.Short.TYPE => classOf[java.lang.Short] + case java.lang.Character.TYPE => classOf[java.lang.Character] + case java.lang.Integer.TYPE => classOf[java.lang.Integer] + case java.lang.Long.TYPE => classOf[java.lang.Long] + case java.lang.Float.TYPE => classOf[java.lang.Float] + case java.lang.Double.TYPE => classOf[java.lang.Double] + case java.lang.Void.TYPE => classOf[scala.runtime.BoxedUnit] + case java.lang.Boolean.TYPE => classOf[java.lang.Boolean] + case _ => clazz + } +} From 1d378bfe836c27b507636aac0c0cd73a980e2665 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 15:16:26 +0200 Subject: [PATCH 07/16] Change VCArray naming scheme. --- src/dotty/runtime/vc/VCBooleanPrototype.scala | 6 +++--- src/dotty/runtime/vc/VCBytePrototype.scala | 4 ++-- src/dotty/runtime/vc/VCCharPrototype.scala | 4 ++-- src/dotty/runtime/vc/VCDoublePrototype.scala | 4 ++-- src/dotty/runtime/vc/VCFloatPrototype.scala | 4 ++-- src/dotty/runtime/vc/VCIntPrototype.scala | 4 ++-- src/dotty/runtime/vc/VCLongPrototype.scala | 4 ++-- src/dotty/runtime/vc/VCObjectPrototype.scala | 4 ++-- src/dotty/runtime/vc/VCShortPrototype.scala | 4 ++-- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/dotty/runtime/vc/VCBooleanPrototype.scala b/src/dotty/runtime/vc/VCBooleanPrototype.scala index e51e7f647095..e2560825b071 100644 --- a/src/dotty/runtime/vc/VCBooleanPrototype.scala +++ b/src/dotty/runtime/vc/VCBooleanPrototype.scala @@ -25,7 +25,7 @@ abstract class VCBooleanCompanion[T <: VCBooleanPrototype] extends ClassTag[T] { def box(underlying: Boolean): T final def unbox(boxed: T) = boxed.underlying override def newArray(len: Int): Array[T] = - new VCArrayBoolean(this, len).asInstanceOf[Array[T]] + new VCBooleanArray(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Boolean) = underlying @@ -34,8 +34,8 @@ abstract class VCBooleanCompanion[T <: VCBooleanPrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Boolean): String } -final class VCArrayBoolean[T <: VCBooleanPrototype](val ct: VCBooleanCompanion[T], sz: Int) extends VCArrayPrototype[T] { - val arr = new Array[Boolean](sz) +final class VCBooleanArray[T <: VCBooleanPrototype](val ct: VCBooleanCompanion[T], sz: Int) extends VCArrayPrototype[T] { + var arr = new Array[Boolean](sz) // mutable for clone() def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = diff --git a/src/dotty/runtime/vc/VCBytePrototype.scala b/src/dotty/runtime/vc/VCBytePrototype.scala index 734f830e041f..4549e381f2b9 100644 --- a/src/dotty/runtime/vc/VCBytePrototype.scala +++ b/src/dotty/runtime/vc/VCBytePrototype.scala @@ -25,7 +25,7 @@ abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { def box(underlying: Byte): T final def unbox(boxed: T) = boxed.underlying override def newArray(len: Int): Array[T] = - new VCArrayByte(this, len).asInstanceOf[Array[T]] + new VCByteArray(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Byte) = underlying final def hashCode$extension(underlying: Byte) = underlying.hashCode() @@ -33,7 +33,7 @@ abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Byte): String } -final class VCArrayByte[T <: VCBytePrototype](val ct: VCByteCompanion[T], sz: Int) extends VCArrayPrototype[T] { +final class VCByteArray[T <: VCBytePrototype](val ct: VCByteCompanion[T], sz: Int) extends VCArrayPrototype[T] { val arr = new Array[Byte](sz) def apply(idx: Int) = ct.box(arr(idx)) diff --git a/src/dotty/runtime/vc/VCCharPrototype.scala b/src/dotty/runtime/vc/VCCharPrototype.scala index 60e1dc8ff494..d12fa4f8a0bd 100644 --- a/src/dotty/runtime/vc/VCCharPrototype.scala +++ b/src/dotty/runtime/vc/VCCharPrototype.scala @@ -25,7 +25,7 @@ abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { def box(underlying: Char): T final def unbox(boxed: T) = boxed.underlying override def newArray(len: Int): Array[T] = - new VCArrayChar(this, len).asInstanceOf[Array[T]] + new VCCharArray(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Char) = underlying final def hashCode$extension(underlying: Char) = underlying.hashCode() @@ -33,7 +33,7 @@ abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Char): String } -final class VCArrayChar[T <: VCCharPrototype](val ct: VCCharCompanion[T], sz: Int) extends VCArrayPrototype[T] { +final class VCCharArray[T <: VCCharPrototype](val ct: VCCharCompanion[T], sz: Int) extends VCArrayPrototype[T] { val arr = new Array[Char](sz) def apply(idx: Int) = ct.box(arr(idx)) diff --git a/src/dotty/runtime/vc/VCDoublePrototype.scala b/src/dotty/runtime/vc/VCDoublePrototype.scala index 091f8be4323e..c547699520d7 100644 --- a/src/dotty/runtime/vc/VCDoublePrototype.scala +++ b/src/dotty/runtime/vc/VCDoublePrototype.scala @@ -25,7 +25,7 @@ abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { def box(underlying: Double): T final def unbox(boxed: T) = boxed.underlying override def newArray(len: Int): Array[T] = - new VCArrayDouble(this, len).asInstanceOf[Array[T]] + new VCDoubleArray(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Double) = underlying final def hashCode$extension(underlying: Double) = underlying.hashCode() @@ -33,7 +33,7 @@ abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Double): String } -final class VCArrayDouble[T <: VCDoublePrototype](val ct: VCDoubleCompanion[T], sz: Int) extends VCArrayPrototype[T] { +final class VCDoubleArray[T <: VCDoublePrototype](val ct: VCDoubleCompanion[T], sz: Int) extends VCArrayPrototype[T] { val arr = new Array[Double](sz) def apply(idx: Int) = ct.box(arr(idx)) diff --git a/src/dotty/runtime/vc/VCFloatPrototype.scala b/src/dotty/runtime/vc/VCFloatPrototype.scala index fefb05a19384..9d582c8ef00a 100644 --- a/src/dotty/runtime/vc/VCFloatPrototype.scala +++ b/src/dotty/runtime/vc/VCFloatPrototype.scala @@ -25,7 +25,7 @@ abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { def box(underlying: Float): T final def unbox(boxed: T) = boxed.underlying override def newArray(len: Int): Array[T] = - new VCArrayFloat(this, len).asInstanceOf[Array[T]] + new VCFloatArray(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Float) = underlying final def hashCode$extension(underlying: Float) = underlying.hashCode() @@ -33,7 +33,7 @@ abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Float): String } -final class VCArrayFloat[T <: VCFloatPrototype](val ct: VCFloatCompanion[T], sz: Int) extends VCArrayPrototype[T] { +final class VCFloatArray[T <: VCFloatPrototype](val ct: VCFloatCompanion[T], sz: Int) extends VCArrayPrototype[T] { val arr = new Array[Float](sz) def apply(idx: Int) = ct.box(arr(idx)) diff --git a/src/dotty/runtime/vc/VCIntPrototype.scala b/src/dotty/runtime/vc/VCIntPrototype.scala index 8e6980ec4f40..48596257bf64 100644 --- a/src/dotty/runtime/vc/VCIntPrototype.scala +++ b/src/dotty/runtime/vc/VCIntPrototype.scala @@ -25,7 +25,7 @@ abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { def box(underlying: Int): T final def unbox(boxed: T) = boxed.underlying override def newArray(len: Int): Array[T] = - new VCArrayInt(this, len).asInstanceOf[Array[T]] + new VCIntArray(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Int) = underlying final def hashCode$extension(underlying: Int) = underlying.hashCode() @@ -33,7 +33,7 @@ abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Int): String } -final class VCArrayInt[T <: VCIntPrototype](val ct: VCIntCompanion[T], sz: Int) extends VCArrayPrototype[T] { +final class VCIntArray[T <: VCIntPrototype](val ct: VCIntCompanion[T], sz: Int) extends VCArrayPrototype[T] { val arr = new Array[Int](sz) def apply(idx: Int) = ct.box(arr(idx)) diff --git a/src/dotty/runtime/vc/VCLongPrototype.scala b/src/dotty/runtime/vc/VCLongPrototype.scala index 0d92a2af5c27..ca02b4f3f2e4 100644 --- a/src/dotty/runtime/vc/VCLongPrototype.scala +++ b/src/dotty/runtime/vc/VCLongPrototype.scala @@ -25,7 +25,7 @@ abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { def box(underlying: Long): T final def unbox(boxed: T) = boxed.underlying override def newArray(len: Int): Array[T] = - new VCArrayLong(this, len).asInstanceOf[Array[T]] + new VCLongArray(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Long) = underlying final def hashCode$extension(underlying: Long) = underlying.hashCode() @@ -33,7 +33,7 @@ abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Long): String } -final class VCArrayLong[T <: VCLongPrototype](val ct: VCLongCompanion[T], sz: Int) extends VCArrayPrototype[T] { +final class VCLongArray[T <: VCLongPrototype](val ct: VCLongCompanion[T], sz: Int) extends VCArrayPrototype[T] { val arr = new Array[Long](sz) def apply(idx: Int) = ct.box(arr(idx)) diff --git a/src/dotty/runtime/vc/VCObjectPrototype.scala b/src/dotty/runtime/vc/VCObjectPrototype.scala index 45982e3404c1..8d0f947f33f2 100644 --- a/src/dotty/runtime/vc/VCObjectPrototype.scala +++ b/src/dotty/runtime/vc/VCObjectPrototype.scala @@ -25,7 +25,7 @@ abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { def box(underlying: Object): T final def unbox(boxed: T) = boxed.underlying override def newArray(len: Int): Array[T] = - new VCArrayObject(this, len).asInstanceOf[Array[T]] + new VCObjectArray(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Object) = underlying final def hashCode$extension(underlying: Object) = underlying.hashCode() @@ -33,7 +33,7 @@ abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Object): String } -final class VCArrayObject[T <: VCObjectPrototype](val ct: VCObjectCompanion[T], sz: Int) extends VCArrayPrototype[T] { +final class VCObjectArray[T <: VCObjectPrototype](val ct: VCObjectCompanion[T], sz: Int) extends VCArrayPrototype[T] { val arr = new Array[Object](sz) def apply(idx: Int) = ct.box(arr(idx)) diff --git a/src/dotty/runtime/vc/VCShortPrototype.scala b/src/dotty/runtime/vc/VCShortPrototype.scala index e39a5d630e71..ac2bc7449417 100644 --- a/src/dotty/runtime/vc/VCShortPrototype.scala +++ b/src/dotty/runtime/vc/VCShortPrototype.scala @@ -25,7 +25,7 @@ abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { def box(underlying: Short): T final def unbox(boxed: T) = boxed.underlying override def newArray(len: Int): Array[T] = - new VCArrayShort(this, len).asInstanceOf[Array[T]] + new VCShortArray(this, len).asInstanceOf[Array[T]] final def _1$extension(underlying: Short) = underlying final def hashCode$extension(underlying: Short) = underlying.hashCode() @@ -33,7 +33,7 @@ abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Short): String } -final class VCArrayShort[T <: VCShortPrototype](val ct: VCShortCompanion[T], sz: Int) extends VCArrayPrototype[T] { +final class VCShortArray[T <: VCShortPrototype](val ct: VCShortCompanion[T], sz: Int) extends VCArrayPrototype[T] { val arr = new Array[Short](sz) def apply(idx: Int) = ct.box(arr(idx)) From 63b88728a2377a7b5cd9b7f2012886d35e6f7c7d Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 15:17:20 +0200 Subject: [PATCH 08/16] Extend methods of ScalaRuntime to support arrays of value classes. --- src/scala/runtime/ScalaRunTime/scala.scala | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/scala/runtime/ScalaRunTime/scala.scala b/src/scala/runtime/ScalaRunTime/scala.scala index fde7b7e10cde..305082f6311c 100644 --- a/src/scala/runtime/ScalaRunTime/scala.scala +++ b/src/scala/runtime/ScalaRunTime/scala.scala @@ -9,6 +9,8 @@ package scala package runtime +import dotty.runtime.vc.VCArrayPrototype + import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator } import scala.collection.mutable.WrappedArray import scala.collection.immutable.{ StringLike, NumericRange, List, Stream, Nil, :: } @@ -29,7 +31,8 @@ object ScalaRunTime { x != null && isArrayClass(x.getClass, atLevel) private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = - clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + (clazz.isArray || classOf[VCArrayPrototype[_]].isAssignableFrom(clazz)) && + (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() @@ -47,6 +50,7 @@ object ScalaRunTime { /** Return the class object representing an array with element class `clazz`. */ def arrayClass(clazz: jClass[_]): jClass[_] = { + ??? // Dmitry: I want to see where this method is used to know how to fix it // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] else java.lang.reflect.Array.newInstance(clazz, 0).getClass @@ -81,6 +85,7 @@ object ScalaRunTime { case x: Array[Short] => x(idx).asInstanceOf[Any] case x: Array[Boolean] => x(idx).asInstanceOf[Any] case x: Array[Unit] => x(idx).asInstanceOf[Any] + case x: VCArrayPrototype[_] => x.apply(idx) case null => throw new NullPointerException } } @@ -98,6 +103,7 @@ object ScalaRunTime { case x: Array[Short] => x(idx) = value.asInstanceOf[Short] case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case x: VCArrayPrototype[t] => x.update(idx, value.asInstanceOf[t]) case null => throw new NullPointerException } } @@ -114,6 +120,7 @@ object ScalaRunTime { case x: Array[Short] => x.length case x: Array[Boolean] => x.length case x: Array[Unit] => x.length + case x: VCArrayPrototype[_] => x.length case null => throw new NullPointerException } From 9c09330347fee4361fc9f14abdd630ade21ddbc2 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 15:25:53 +0200 Subject: [PATCH 09/16] Implement clone for VCArrays. Unfortunately needed to sacrifice the immutability of inner field. --- src/dotty/runtime/vc/VCBooleanPrototype.scala | 6 ++++++ src/dotty/runtime/vc/VCBytePrototype.scala | 9 ++++++++- src/dotty/runtime/vc/VCCharPrototype.scala | 9 ++++++++- src/dotty/runtime/vc/VCDoublePrototype.scala | 8 +++++++- src/dotty/runtime/vc/VCFloatPrototype.scala | 8 +++++++- src/dotty/runtime/vc/VCIntPrototype.scala | 8 +++++++- src/dotty/runtime/vc/VCLongPrototype.scala | 8 +++++++- src/dotty/runtime/vc/VCObjectPrototype.scala | 8 +++++++- src/dotty/runtime/vc/VCPrototype.scala | 2 +- src/dotty/runtime/vc/VCShortPrototype.scala | 8 +++++++- .../ScalaRunTime/{scala.scala => ScalaRunTime.scala} | 1 + 11 files changed, 66 insertions(+), 9 deletions(-) rename src/scala/runtime/ScalaRunTime/{scala.scala => ScalaRunTime.scala} (99%) diff --git a/src/dotty/runtime/vc/VCBooleanPrototype.scala b/src/dotty/runtime/vc/VCBooleanPrototype.scala index e2560825b071..c647eaeae9fe 100644 --- a/src/dotty/runtime/vc/VCBooleanPrototype.scala +++ b/src/dotty/runtime/vc/VCBooleanPrototype.scala @@ -42,6 +42,12 @@ final class VCBooleanArray[T <: VCBooleanPrototype](val ct: VCBooleanCompanion[T arr(idx) = ct.unbox(elem) def length: Int = arr.length + override def clone(): VCBooleanArray[T] = { + val t = super.clone().asInstanceOf[VCBooleanArray[T]] + t.arr = this.arr.clone() + t + } + override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCBytePrototype.scala b/src/dotty/runtime/vc/VCBytePrototype.scala index 4549e381f2b9..bf21a1cfbb34 100644 --- a/src/dotty/runtime/vc/VCBytePrototype.scala +++ b/src/dotty/runtime/vc/VCBytePrototype.scala @@ -34,13 +34,20 @@ abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { } final class VCByteArray[T <: VCBytePrototype](val ct: VCByteCompanion[T], sz: Int) extends VCArrayPrototype[T] { - val arr = new Array[Byte](sz) + var arr = new Array[Byte](sz) // mutable for clone def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = arr(idx) = ct.unbox(elem) def length: Int = arr.length + override def clone(): VCByteArray[T] = { + val t = super.clone().asInstanceOf[VCByteArray[T]] + t.arr = this.arr.clone() + t + } + + override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCCharPrototype.scala b/src/dotty/runtime/vc/VCCharPrototype.scala index d12fa4f8a0bd..5b6aae2e4162 100644 --- a/src/dotty/runtime/vc/VCCharPrototype.scala +++ b/src/dotty/runtime/vc/VCCharPrototype.scala @@ -34,13 +34,20 @@ abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { } final class VCCharArray[T <: VCCharPrototype](val ct: VCCharCompanion[T], sz: Int) extends VCArrayPrototype[T] { - val arr = new Array[Char](sz) + var arr = new Array[Char](sz) // mutable for clone def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = arr(idx) = ct.unbox(elem) def length: Int = arr.length + override def clone(): VCCharArray[T] = { + val t = super.clone().asInstanceOf[VCCharArray[T]] + t.arr = this.arr.clone() + t + } + + override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCDoublePrototype.scala b/src/dotty/runtime/vc/VCDoublePrototype.scala index c547699520d7..047b4cbe44ec 100644 --- a/src/dotty/runtime/vc/VCDoublePrototype.scala +++ b/src/dotty/runtime/vc/VCDoublePrototype.scala @@ -34,13 +34,19 @@ abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { } final class VCDoubleArray[T <: VCDoublePrototype](val ct: VCDoubleCompanion[T], sz: Int) extends VCArrayPrototype[T] { - val arr = new Array[Double](sz) + var arr = new Array[Double](sz) // mutable for clone def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = arr(idx) = ct.unbox(elem) def length: Int = arr.length + override def clone(): VCDoubleArray[T] = { + val t = super.clone().asInstanceOf[VCDoubleArray[T]] + t.arr = this.arr.clone() + t + } + override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCFloatPrototype.scala b/src/dotty/runtime/vc/VCFloatPrototype.scala index 9d582c8ef00a..09cefbd9e8e6 100644 --- a/src/dotty/runtime/vc/VCFloatPrototype.scala +++ b/src/dotty/runtime/vc/VCFloatPrototype.scala @@ -34,13 +34,19 @@ abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { } final class VCFloatArray[T <: VCFloatPrototype](val ct: VCFloatCompanion[T], sz: Int) extends VCArrayPrototype[T] { - val arr = new Array[Float](sz) + var arr = new Array[Float](sz) // mutable for clone def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = arr(idx) = ct.unbox(elem) def length: Int = arr.length + override def clone(): VCFloatArray[T] = { + val t = super.clone().asInstanceOf[VCFloatArray[T]] + t.arr = this.arr.clone() + t + } + override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCIntPrototype.scala b/src/dotty/runtime/vc/VCIntPrototype.scala index 48596257bf64..cc781efcfdb3 100644 --- a/src/dotty/runtime/vc/VCIntPrototype.scala +++ b/src/dotty/runtime/vc/VCIntPrototype.scala @@ -34,13 +34,19 @@ abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { } final class VCIntArray[T <: VCIntPrototype](val ct: VCIntCompanion[T], sz: Int) extends VCArrayPrototype[T] { - val arr = new Array[Int](sz) + var arr = new Array[Int](sz) // mutable for clone def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = arr(idx) = ct.unbox(elem) def length: Int = arr.length + override def clone(): VCIntArray[T] = { + val t = super.clone().asInstanceOf[VCIntArray[T]] + t.arr = this.arr.clone() + t + } + override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCLongPrototype.scala b/src/dotty/runtime/vc/VCLongPrototype.scala index ca02b4f3f2e4..4eecddd9bb65 100644 --- a/src/dotty/runtime/vc/VCLongPrototype.scala +++ b/src/dotty/runtime/vc/VCLongPrototype.scala @@ -34,13 +34,19 @@ abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { } final class VCLongArray[T <: VCLongPrototype](val ct: VCLongCompanion[T], sz: Int) extends VCArrayPrototype[T] { - val arr = new Array[Long](sz) + var arr = new Array[Long](sz) // mutable for clone def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = arr(idx) = ct.unbox(elem) def length: Int = arr.length + override def clone(): VCLongArray[T] = { + val t = super.clone().asInstanceOf[VCLongArray[T]] + t.arr = this.arr.clone() + t + } + override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCObjectPrototype.scala b/src/dotty/runtime/vc/VCObjectPrototype.scala index 8d0f947f33f2..ef2c0f0aa25e 100644 --- a/src/dotty/runtime/vc/VCObjectPrototype.scala +++ b/src/dotty/runtime/vc/VCObjectPrototype.scala @@ -34,13 +34,19 @@ abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { } final class VCObjectArray[T <: VCObjectPrototype](val ct: VCObjectCompanion[T], sz: Int) extends VCArrayPrototype[T] { - val arr = new Array[Object](sz) + var arr = new Array[Object](sz) // mutable for clone def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = arr(idx) = ct.unbox(elem) def length: Int = arr.length + override def clone(): VCObjectArray[T] = { + val t = super.clone().asInstanceOf[VCObjectArray[T]] + t.arr = this.arr.clone() + t + } + override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCPrototype.scala b/src/dotty/runtime/vc/VCPrototype.scala index 4ece214e9e26..b9c931bbcbbf 100644 --- a/src/dotty/runtime/vc/VCPrototype.scala +++ b/src/dotty/runtime/vc/VCPrototype.scala @@ -3,7 +3,7 @@ package dotty.runtime.vc abstract class VCPrototype { } -abstract class VCArrayPrototype[T <: VCPrototype] { +abstract class VCArrayPrototype[T <: VCPrototype] extends Cloneable { def apply(idx: Int): Object def update(idx: Int, el: T): Unit def length: Int diff --git a/src/dotty/runtime/vc/VCShortPrototype.scala b/src/dotty/runtime/vc/VCShortPrototype.scala index ac2bc7449417..255f85ca91ae 100644 --- a/src/dotty/runtime/vc/VCShortPrototype.scala +++ b/src/dotty/runtime/vc/VCShortPrototype.scala @@ -34,13 +34,19 @@ abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { } final class VCShortArray[T <: VCShortPrototype](val ct: VCShortCompanion[T], sz: Int) extends VCArrayPrototype[T] { - val arr = new Array[Short](sz) + var arr = new Array[Short](sz) // mutable for clone def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = arr(idx) = ct.unbox(elem) def length: Int = arr.length + override def clone(): VCShortArray[T] = { + val t = super.clone().asInstanceOf[VCShortArray[T]] + t.arr = this.arr.clone() + t + } + override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/scala/runtime/ScalaRunTime/scala.scala b/src/scala/runtime/ScalaRunTime/ScalaRunTime.scala similarity index 99% rename from src/scala/runtime/ScalaRunTime/scala.scala rename to src/scala/runtime/ScalaRunTime/ScalaRunTime.scala index 305082f6311c..b875b4d1e910 100644 --- a/src/scala/runtime/ScalaRunTime/scala.scala +++ b/src/scala/runtime/ScalaRunTime/ScalaRunTime.scala @@ -135,6 +135,7 @@ object ScalaRunTime { case x: Array[Short] => ArrayRuntime.cloneArray(x) case x: Array[Boolean] => ArrayRuntime.cloneArray(x) case x: Array[Unit] => x + case x: VCArrayPrototype[_] => x.clone() case null => throw new NullPointerException } From 6bbf35496c2cb4f4b4fa55ef80b4eaa85e0de63f Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 15:43:06 +0200 Subject: [PATCH 10/16] Implement clone on VCArrays without mutable field. --- src/dotty/runtime/vc/VCBooleanPrototype.scala | 11 ++++++----- src/dotty/runtime/vc/VCBytePrototype.scala | 13 +++++++------ src/dotty/runtime/vc/VCCharPrototype.scala | 13 +++++++------ src/dotty/runtime/vc/VCDoublePrototype.scala | 12 +++++++----- src/dotty/runtime/vc/VCFloatPrototype.scala | 12 +++++++----- src/dotty/runtime/vc/VCIntPrototype.scala | 12 +++++++----- src/dotty/runtime/vc/VCLongPrototype.scala | 12 +++++++----- src/dotty/runtime/vc/VCObjectPrototype.scala | 12 +++++++----- src/dotty/runtime/vc/VCShortPrototype.scala | 12 +++++++----- 9 files changed, 62 insertions(+), 47 deletions(-) diff --git a/src/dotty/runtime/vc/VCBooleanPrototype.scala b/src/dotty/runtime/vc/VCBooleanPrototype.scala index c647eaeae9fe..a651ee820ca1 100644 --- a/src/dotty/runtime/vc/VCBooleanPrototype.scala +++ b/src/dotty/runtime/vc/VCBooleanPrototype.scala @@ -34,8 +34,11 @@ abstract class VCBooleanCompanion[T <: VCBooleanPrototype] extends ClassTag[T] { def productPrefix$extension(underlying: Boolean): String } -final class VCBooleanArray[T <: VCBooleanPrototype](val ct: VCBooleanCompanion[T], sz: Int) extends VCArrayPrototype[T] { - var arr = new Array[Boolean](sz) // mutable for clone() +final class VCBooleanArray[T <: VCBooleanPrototype] private (val arr: Array[Boolean], val ct: VCBooleanCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCBooleanCompanion[T], sz: Int) = + this(new Array[Boolean](sz), ct) + def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = @@ -43,9 +46,7 @@ final class VCBooleanArray[T <: VCBooleanPrototype](val ct: VCBooleanCompanion[T def length: Int = arr.length override def clone(): VCBooleanArray[T] = { - val t = super.clone().asInstanceOf[VCBooleanArray[T]] - t.arr = this.arr.clone() - t + new VCBooleanArray[T](arr.clone(), ct) } override def toString: String = { diff --git a/src/dotty/runtime/vc/VCBytePrototype.scala b/src/dotty/runtime/vc/VCBytePrototype.scala index bf21a1cfbb34..dafd438152c4 100644 --- a/src/dotty/runtime/vc/VCBytePrototype.scala +++ b/src/dotty/runtime/vc/VCBytePrototype.scala @@ -27,14 +27,18 @@ abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { override def newArray(len: Int): Array[T] = new VCByteArray(this, len).asInstanceOf[Array[T]] + final def _1$extension(underlying: Byte) = underlying final def hashCode$extension(underlying: Byte) = underlying.hashCode() final def toString$extension(underlying: Byte) = s"${productPrefix$extension(underlying)}($underlying)" def productPrefix$extension(underlying: Byte): String } -final class VCByteArray[T <: VCBytePrototype](val ct: VCByteCompanion[T], sz: Int) extends VCArrayPrototype[T] { - var arr = new Array[Byte](sz) // mutable for clone +final class VCByteArray[T <: VCBytePrototype] private (val arr: Array[Byte], val ct: VCByteCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCByteCompanion[T], sz: Int) = + this(new Array[Byte](sz), ct) + def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = @@ -42,12 +46,9 @@ final class VCByteArray[T <: VCBytePrototype](val ct: VCByteCompanion[T], sz: In def length: Int = arr.length override def clone(): VCByteArray[T] = { - val t = super.clone().asInstanceOf[VCByteArray[T]] - t.arr = this.arr.clone() - t + new VCByteArray[T](arr.clone(), ct) } - override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCCharPrototype.scala b/src/dotty/runtime/vc/VCCharPrototype.scala index 5b6aae2e4162..338e9c13237f 100644 --- a/src/dotty/runtime/vc/VCCharPrototype.scala +++ b/src/dotty/runtime/vc/VCCharPrototype.scala @@ -27,14 +27,18 @@ abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { override def newArray(len: Int): Array[T] = new VCCharArray(this, len).asInstanceOf[Array[T]] + final def _1$extension(underlying: Char) = underlying final def hashCode$extension(underlying: Char) = underlying.hashCode() final def toString$extension(underlying: Char) = s"${productPrefix$extension(underlying)}($underlying)" def productPrefix$extension(underlying: Char): String } -final class VCCharArray[T <: VCCharPrototype](val ct: VCCharCompanion[T], sz: Int) extends VCArrayPrototype[T] { - var arr = new Array[Char](sz) // mutable for clone +final class VCCharArray[T <: VCCharPrototype] private (val arr: Array[Char], val ct: VCCharCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCCharCompanion[T], sz: Int) = + this(new Array[Char](sz), ct) + def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = @@ -42,12 +46,9 @@ final class VCCharArray[T <: VCCharPrototype](val ct: VCCharCompanion[T], sz: In def length: Int = arr.length override def clone(): VCCharArray[T] = { - val t = super.clone().asInstanceOf[VCCharArray[T]] - t.arr = this.arr.clone() - t + new VCCharArray[T](arr.clone(), ct) } - override def toString: String = { "[" + ct.runtimeClass } diff --git a/src/dotty/runtime/vc/VCDoublePrototype.scala b/src/dotty/runtime/vc/VCDoublePrototype.scala index 047b4cbe44ec..f960acd4e602 100644 --- a/src/dotty/runtime/vc/VCDoublePrototype.scala +++ b/src/dotty/runtime/vc/VCDoublePrototype.scala @@ -27,14 +27,18 @@ abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { override def newArray(len: Int): Array[T] = new VCDoubleArray(this, len).asInstanceOf[Array[T]] + final def _1$extension(underlying: Double) = underlying final def hashCode$extension(underlying: Double) = underlying.hashCode() final def toString$extension(underlying: Double) = s"${productPrefix$extension(underlying)}($underlying)" def productPrefix$extension(underlying: Double): String } -final class VCDoubleArray[T <: VCDoublePrototype](val ct: VCDoubleCompanion[T], sz: Int) extends VCArrayPrototype[T] { - var arr = new Array[Double](sz) // mutable for clone +final class VCDoubleArray[T <: VCDoublePrototype] private (val arr: Array[Double], val ct: VCDoubleCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCDoubleCompanion[T], sz: Int) = + this(new Array[Double](sz), ct) + def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = @@ -42,9 +46,7 @@ final class VCDoubleArray[T <: VCDoublePrototype](val ct: VCDoubleCompanion[T], def length: Int = arr.length override def clone(): VCDoubleArray[T] = { - val t = super.clone().asInstanceOf[VCDoubleArray[T]] - t.arr = this.arr.clone() - t + new VCDoubleArray[T](arr.clone(), ct) } override def toString: String = { diff --git a/src/dotty/runtime/vc/VCFloatPrototype.scala b/src/dotty/runtime/vc/VCFloatPrototype.scala index 09cefbd9e8e6..d2a085d866fa 100644 --- a/src/dotty/runtime/vc/VCFloatPrototype.scala +++ b/src/dotty/runtime/vc/VCFloatPrototype.scala @@ -27,14 +27,18 @@ abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { override def newArray(len: Int): Array[T] = new VCFloatArray(this, len).asInstanceOf[Array[T]] + final def _1$extension(underlying: Float) = underlying final def hashCode$extension(underlying: Float) = underlying.hashCode() final def toString$extension(underlying: Float) = s"${productPrefix$extension(underlying)}($underlying)" def productPrefix$extension(underlying: Float): String } -final class VCFloatArray[T <: VCFloatPrototype](val ct: VCFloatCompanion[T], sz: Int) extends VCArrayPrototype[T] { - var arr = new Array[Float](sz) // mutable for clone +final class VCFloatArray[T <: VCFloatPrototype] private (val arr: Array[Float], val ct: VCFloatCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCFloatCompanion[T], sz: Int) = + this(new Array[Float](sz), ct) + def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = @@ -42,9 +46,7 @@ final class VCFloatArray[T <: VCFloatPrototype](val ct: VCFloatCompanion[T], sz: def length: Int = arr.length override def clone(): VCFloatArray[T] = { - val t = super.clone().asInstanceOf[VCFloatArray[T]] - t.arr = this.arr.clone() - t + new VCFloatArray[T](arr.clone(), ct) } override def toString: String = { diff --git a/src/dotty/runtime/vc/VCIntPrototype.scala b/src/dotty/runtime/vc/VCIntPrototype.scala index cc781efcfdb3..bd788026e1ed 100644 --- a/src/dotty/runtime/vc/VCIntPrototype.scala +++ b/src/dotty/runtime/vc/VCIntPrototype.scala @@ -27,14 +27,18 @@ abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { override def newArray(len: Int): Array[T] = new VCIntArray(this, len).asInstanceOf[Array[T]] + final def _1$extension(underlying: Int) = underlying final def hashCode$extension(underlying: Int) = underlying.hashCode() final def toString$extension(underlying: Int) = s"${productPrefix$extension(underlying)}($underlying)" def productPrefix$extension(underlying: Int): String } -final class VCIntArray[T <: VCIntPrototype](val ct: VCIntCompanion[T], sz: Int) extends VCArrayPrototype[T] { - var arr = new Array[Int](sz) // mutable for clone +final class VCIntArray[T <: VCIntPrototype] private (val arr: Array[Int], val ct: VCIntCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCIntCompanion[T], sz: Int) = + this(new Array[Int](sz), ct) + def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = @@ -42,9 +46,7 @@ final class VCIntArray[T <: VCIntPrototype](val ct: VCIntCompanion[T], sz: Int) def length: Int = arr.length override def clone(): VCIntArray[T] = { - val t = super.clone().asInstanceOf[VCIntArray[T]] - t.arr = this.arr.clone() - t + new VCIntArray[T](arr.clone(), ct) } override def toString: String = { diff --git a/src/dotty/runtime/vc/VCLongPrototype.scala b/src/dotty/runtime/vc/VCLongPrototype.scala index 4eecddd9bb65..eb7e5a6d284e 100644 --- a/src/dotty/runtime/vc/VCLongPrototype.scala +++ b/src/dotty/runtime/vc/VCLongPrototype.scala @@ -27,14 +27,18 @@ abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { override def newArray(len: Int): Array[T] = new VCLongArray(this, len).asInstanceOf[Array[T]] + final def _1$extension(underlying: Long) = underlying final def hashCode$extension(underlying: Long) = underlying.hashCode() final def toString$extension(underlying: Long) = s"${productPrefix$extension(underlying)}($underlying)" def productPrefix$extension(underlying: Long): String } -final class VCLongArray[T <: VCLongPrototype](val ct: VCLongCompanion[T], sz: Int) extends VCArrayPrototype[T] { - var arr = new Array[Long](sz) // mutable for clone +final class VCLongArray[T <: VCLongPrototype] private (val arr: Array[Long], val ct: VCLongCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCLongCompanion[T], sz: Int) = + this(new Array[Long](sz), ct) + def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = @@ -42,9 +46,7 @@ final class VCLongArray[T <: VCLongPrototype](val ct: VCLongCompanion[T], sz: In def length: Int = arr.length override def clone(): VCLongArray[T] = { - val t = super.clone().asInstanceOf[VCLongArray[T]] - t.arr = this.arr.clone() - t + new VCLongArray[T](arr.clone(), ct) } override def toString: String = { diff --git a/src/dotty/runtime/vc/VCObjectPrototype.scala b/src/dotty/runtime/vc/VCObjectPrototype.scala index ef2c0f0aa25e..01a0da5ee13b 100644 --- a/src/dotty/runtime/vc/VCObjectPrototype.scala +++ b/src/dotty/runtime/vc/VCObjectPrototype.scala @@ -27,14 +27,18 @@ abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { override def newArray(len: Int): Array[T] = new VCObjectArray(this, len).asInstanceOf[Array[T]] + final def _1$extension(underlying: Object) = underlying final def hashCode$extension(underlying: Object) = underlying.hashCode() final def toString$extension(underlying: Object) = s"${productPrefix$extension(underlying)}($underlying)" def productPrefix$extension(underlying: Object): String } -final class VCObjectArray[T <: VCObjectPrototype](val ct: VCObjectCompanion[T], sz: Int) extends VCArrayPrototype[T] { - var arr = new Array[Object](sz) // mutable for clone +final class VCObjectArray[T <: VCObjectPrototype] private (val arr: Array[Object], val ct: VCObjectCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCObjectCompanion[T], sz: Int) = + this(new Array[Object](sz), ct) + def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = @@ -42,9 +46,7 @@ final class VCObjectArray[T <: VCObjectPrototype](val ct: VCObjectCompanion[T], def length: Int = arr.length override def clone(): VCObjectArray[T] = { - val t = super.clone().asInstanceOf[VCObjectArray[T]] - t.arr = this.arr.clone() - t + new VCObjectArray[T](arr.clone(), ct) } override def toString: String = { diff --git a/src/dotty/runtime/vc/VCShortPrototype.scala b/src/dotty/runtime/vc/VCShortPrototype.scala index 255f85ca91ae..94bf36908fc7 100644 --- a/src/dotty/runtime/vc/VCShortPrototype.scala +++ b/src/dotty/runtime/vc/VCShortPrototype.scala @@ -27,14 +27,18 @@ abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { override def newArray(len: Int): Array[T] = new VCShortArray(this, len).asInstanceOf[Array[T]] + final def _1$extension(underlying: Short) = underlying final def hashCode$extension(underlying: Short) = underlying.hashCode() final def toString$extension(underlying: Short) = s"${productPrefix$extension(underlying)}($underlying)" def productPrefix$extension(underlying: Short): String } -final class VCShortArray[T <: VCShortPrototype](val ct: VCShortCompanion[T], sz: Int) extends VCArrayPrototype[T] { - var arr = new Array[Short](sz) // mutable for clone +final class VCShortArray[T <: VCShortPrototype] private (val arr: Array[Short], val ct: VCShortCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCShortCompanion[T], sz: Int) = + this(new Array[Short](sz), ct) + def apply(idx: Int) = ct.box(arr(idx)) def update(idx: Int, elem: T) = @@ -42,9 +46,7 @@ final class VCShortArray[T <: VCShortPrototype](val ct: VCShortCompanion[T], sz: def length: Int = arr.length override def clone(): VCShortArray[T] = { - val t = super.clone().asInstanceOf[VCShortArray[T]] - t.arr = this.arr.clone() - t + new VCShortArray[T](arr.clone(), ct) } override def toString: String = { From cb8fa8278ce690a800e6454d3fcd2058100e0d71 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 16:00:10 +0200 Subject: [PATCH 11/16] It seems one cannot define clone member in scala trait. Do it in Java. [error] /Users/dark/workspace/dotty/src/dotty/runtime/vc/VCPrototype.scala:10: overriding method clone in class VCArrayPrototype of type ()Object; [error] method clone in class Object of type ()Object has weaker access privileges; it should be public; [error] (Note that method clone in class VCArrayPrototype of type ()Object is abstract, [error] and is therefore overridden by concrete method clone in class Object of type ()Object) [error] abstract class VCArrayPrototype[T <: VCPrototype] extends Object with Cloneable { --- src/dotty/runtime/vc/VCArrayClone.java | 9 +++++++++ src/dotty/runtime/vc/VCPrototype.scala | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/dotty/runtime/vc/VCArrayClone.java diff --git a/src/dotty/runtime/vc/VCArrayClone.java b/src/dotty/runtime/vc/VCArrayClone.java new file mode 100644 index 000000000000..0b0fa40ce743 --- /dev/null +++ b/src/dotty/runtime/vc/VCArrayClone.java @@ -0,0 +1,9 @@ +package dotty.runtime.vc; + +/** + * Exists for the sole reason of Scala not accepting such trait + */ + +interface VCArrayClone { + Object clone(); +} diff --git a/src/dotty/runtime/vc/VCPrototype.scala b/src/dotty/runtime/vc/VCPrototype.scala index b9c931bbcbbf..a916548645fb 100644 --- a/src/dotty/runtime/vc/VCPrototype.scala +++ b/src/dotty/runtime/vc/VCPrototype.scala @@ -3,7 +3,8 @@ package dotty.runtime.vc abstract class VCPrototype { } -abstract class VCArrayPrototype[T <: VCPrototype] extends Cloneable { + +abstract class VCArrayPrototype[T <: VCPrototype] extends Object with Cloneable with VCArrayClone { def apply(idx: Int): Object def update(idx: Int, el: T): Unit def length: Int From 744ffb5d7b5325c2ac14a27c493a6c2749e741d4 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 1 May 2015 16:28:52 +0200 Subject: [PATCH 12/16] Introduce VCArray.clone in scala. It can be done with non-abstract rhs of method. --- src/dotty/runtime/vc/VCArrayClone.java | 9 --------- src/dotty/runtime/vc/VCPrototype.scala | 3 ++- 2 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 src/dotty/runtime/vc/VCArrayClone.java diff --git a/src/dotty/runtime/vc/VCArrayClone.java b/src/dotty/runtime/vc/VCArrayClone.java deleted file mode 100644 index 0b0fa40ce743..000000000000 --- a/src/dotty/runtime/vc/VCArrayClone.java +++ /dev/null @@ -1,9 +0,0 @@ -package dotty.runtime.vc; - -/** - * Exists for the sole reason of Scala not accepting such trait - */ - -interface VCArrayClone { - Object clone(); -} diff --git a/src/dotty/runtime/vc/VCPrototype.scala b/src/dotty/runtime/vc/VCPrototype.scala index a916548645fb..61ed93b92130 100644 --- a/src/dotty/runtime/vc/VCPrototype.scala +++ b/src/dotty/runtime/vc/VCPrototype.scala @@ -4,8 +4,9 @@ abstract class VCPrototype { } -abstract class VCArrayPrototype[T <: VCPrototype] extends Object with Cloneable with VCArrayClone { +abstract class VCArrayPrototype[T <: VCPrototype] extends Object with Cloneable { def apply(idx: Int): Object def update(idx: Int, el: T): Unit def length: Int + override def clone: Object = super.clone() } From 0e71743b1622716a99f4783ac5cb41c5012f5a49 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 5 May 2015 19:46:15 +0200 Subject: [PATCH 13/16] Implement implicit defs that return class tags for value classes. --- src/dotty/runtime/vc/VCBooleanPrototype.scala | 2 ++ src/dotty/runtime/vc/VCBytePrototype.scala | 2 ++ src/dotty/runtime/vc/VCCharPrototype.scala | 2 ++ src/dotty/runtime/vc/VCDoublePrototype.scala | 2 ++ src/dotty/runtime/vc/VCFloatPrototype.scala | 2 ++ src/dotty/runtime/vc/VCIntPrototype.scala | 2 ++ src/dotty/runtime/vc/VCLongPrototype.scala | 2 ++ src/dotty/runtime/vc/VCObjectPrototype.scala | 2 ++ src/dotty/runtime/vc/VCShortPrototype.scala | 2 ++ 9 files changed, 18 insertions(+) diff --git a/src/dotty/runtime/vc/VCBooleanPrototype.scala b/src/dotty/runtime/vc/VCBooleanPrototype.scala index a651ee820ca1..9c90fb304bbc 100644 --- a/src/dotty/runtime/vc/VCBooleanPrototype.scala +++ b/src/dotty/runtime/vc/VCBooleanPrototype.scala @@ -24,6 +24,8 @@ abstract class VCBooleanCasePrototype(underlying: Boolean) extends VCBooleanProt abstract class VCBooleanCompanion[T <: VCBooleanPrototype] extends ClassTag[T] { def box(underlying: Boolean): T final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this override def newArray(len: Int): Array[T] = new VCBooleanArray(this, len).asInstanceOf[Array[T]] diff --git a/src/dotty/runtime/vc/VCBytePrototype.scala b/src/dotty/runtime/vc/VCBytePrototype.scala index dafd438152c4..a8a24dab0e89 100644 --- a/src/dotty/runtime/vc/VCBytePrototype.scala +++ b/src/dotty/runtime/vc/VCBytePrototype.scala @@ -24,6 +24,8 @@ abstract class VCByteCasePrototype(underlying: Byte) extends VCBytePrototype(und abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { def box(underlying: Byte): T final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this override def newArray(len: Int): Array[T] = new VCByteArray(this, len).asInstanceOf[Array[T]] diff --git a/src/dotty/runtime/vc/VCCharPrototype.scala b/src/dotty/runtime/vc/VCCharPrototype.scala index 338e9c13237f..796821f56186 100644 --- a/src/dotty/runtime/vc/VCCharPrototype.scala +++ b/src/dotty/runtime/vc/VCCharPrototype.scala @@ -24,6 +24,8 @@ abstract class VCCharCasePrototype(underlying: Char) extends VCCharPrototype(und abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { def box(underlying: Char): T final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this override def newArray(len: Int): Array[T] = new VCCharArray(this, len).asInstanceOf[Array[T]] diff --git a/src/dotty/runtime/vc/VCDoublePrototype.scala b/src/dotty/runtime/vc/VCDoublePrototype.scala index f960acd4e602..2a3f90f07eaf 100644 --- a/src/dotty/runtime/vc/VCDoublePrototype.scala +++ b/src/dotty/runtime/vc/VCDoublePrototype.scala @@ -24,6 +24,8 @@ abstract class VCDoubleCasePrototype(underlying: Double) extends VCDoublePrototy abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { def box(underlying: Double): T final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this override def newArray(len: Int): Array[T] = new VCDoubleArray(this, len).asInstanceOf[Array[T]] diff --git a/src/dotty/runtime/vc/VCFloatPrototype.scala b/src/dotty/runtime/vc/VCFloatPrototype.scala index d2a085d866fa..c3e1101105c7 100644 --- a/src/dotty/runtime/vc/VCFloatPrototype.scala +++ b/src/dotty/runtime/vc/VCFloatPrototype.scala @@ -24,6 +24,8 @@ abstract class VCFloatCasePrototype(underlying: Float) extends VCFloatPrototype( abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { def box(underlying: Float): T final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this override def newArray(len: Int): Array[T] = new VCFloatArray(this, len).asInstanceOf[Array[T]] diff --git a/src/dotty/runtime/vc/VCIntPrototype.scala b/src/dotty/runtime/vc/VCIntPrototype.scala index bd788026e1ed..44f746ed4b9c 100644 --- a/src/dotty/runtime/vc/VCIntPrototype.scala +++ b/src/dotty/runtime/vc/VCIntPrototype.scala @@ -24,6 +24,8 @@ abstract class VCIntCasePrototype(underlying: Int) extends VCIntPrototype(underl abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { def box(underlying: Int): T final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this override def newArray(len: Int): Array[T] = new VCIntArray(this, len).asInstanceOf[Array[T]] diff --git a/src/dotty/runtime/vc/VCLongPrototype.scala b/src/dotty/runtime/vc/VCLongPrototype.scala index eb7e5a6d284e..83690bcfdd09 100644 --- a/src/dotty/runtime/vc/VCLongPrototype.scala +++ b/src/dotty/runtime/vc/VCLongPrototype.scala @@ -24,6 +24,8 @@ abstract class VCLongCasePrototype(underlying: Long) extends VCLongPrototype(und abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { def box(underlying: Long): T final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this override def newArray(len: Int): Array[T] = new VCLongArray(this, len).asInstanceOf[Array[T]] diff --git a/src/dotty/runtime/vc/VCObjectPrototype.scala b/src/dotty/runtime/vc/VCObjectPrototype.scala index 01a0da5ee13b..fd0c8728a523 100644 --- a/src/dotty/runtime/vc/VCObjectPrototype.scala +++ b/src/dotty/runtime/vc/VCObjectPrototype.scala @@ -24,6 +24,8 @@ abstract class VCObjectCasePrototype(underlying: Object) extends VCObjectPrototy abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { def box(underlying: Object): T final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this override def newArray(len: Int): Array[T] = new VCObjectArray(this, len).asInstanceOf[Array[T]] diff --git a/src/dotty/runtime/vc/VCShortPrototype.scala b/src/dotty/runtime/vc/VCShortPrototype.scala index 94bf36908fc7..519e6d5c8235 100644 --- a/src/dotty/runtime/vc/VCShortPrototype.scala +++ b/src/dotty/runtime/vc/VCShortPrototype.scala @@ -24,6 +24,8 @@ abstract class VCShortCasePrototype(underlying: Short) extends VCShortPrototype( abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { def box(underlying: Short): T final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this override def newArray(len: Int): Array[T] = new VCShortArray(this, len).asInstanceOf[Array[T]] From a40da8fc916baa1c068598bb4e50a684b89e5b2c Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 5 May 2015 19:53:07 +0200 Subject: [PATCH 14/16] Merge all VC prototypes into single file --- src/dotty/runtime/vc/VCBooleanPrototype.scala | 60 --- src/dotty/runtime/vc/VCBytePrototype.scala | 60 --- src/dotty/runtime/vc/VCCharPrototype.scala | 60 --- src/dotty/runtime/vc/VCDoublePrototype.scala | 60 --- src/dotty/runtime/vc/VCFloatPrototype.scala | 60 --- src/dotty/runtime/vc/VCIntPrototype.scala | 60 --- src/dotty/runtime/vc/VCLongPrototype.scala | 60 --- src/dotty/runtime/vc/VCObjectPrototype.scala | 60 --- src/dotty/runtime/vc/VCPrototype.scala | 474 ++++++++++++++++++ src/dotty/runtime/vc/VCShortPrototype.scala | 60 --- 10 files changed, 474 insertions(+), 540 deletions(-) delete mode 100644 src/dotty/runtime/vc/VCBooleanPrototype.scala delete mode 100644 src/dotty/runtime/vc/VCBytePrototype.scala delete mode 100644 src/dotty/runtime/vc/VCCharPrototype.scala delete mode 100644 src/dotty/runtime/vc/VCDoublePrototype.scala delete mode 100644 src/dotty/runtime/vc/VCFloatPrototype.scala delete mode 100644 src/dotty/runtime/vc/VCIntPrototype.scala delete mode 100644 src/dotty/runtime/vc/VCLongPrototype.scala delete mode 100644 src/dotty/runtime/vc/VCObjectPrototype.scala delete mode 100644 src/dotty/runtime/vc/VCShortPrototype.scala diff --git a/src/dotty/runtime/vc/VCBooleanPrototype.scala b/src/dotty/runtime/vc/VCBooleanPrototype.scala deleted file mode 100644 index 9c90fb304bbc..000000000000 --- a/src/dotty/runtime/vc/VCBooleanPrototype.scala +++ /dev/null @@ -1,60 +0,0 @@ -package dotty.runtime.vc - -import scala.reflect.ClassTag - -import scala.runtime.Statics - -abstract class VCBooleanPrototype(val underlying: Boolean) extends VCPrototype {} - -abstract class VCBooleanCasePrototype(underlying: Boolean) extends VCBooleanPrototype(underlying) with Product1[Boolean] { - - final def _1: Boolean = underlying - - override final def hashCode(): Int = { - underlying.hashCode() - } - - override final def toString: String = { - s"$productPrefix($underlying)" - } - - // subclasses are expected to implement equals, productPrefix, and canEqual -} - -abstract class VCBooleanCompanion[T <: VCBooleanPrototype] extends ClassTag[T] { - def box(underlying: Boolean): T - final def unbox(boxed: T) = boxed.underlying - - implicit def classTag: this.type = this - override def newArray(len: Int): Array[T] = - new VCBooleanArray(this, len).asInstanceOf[Array[T]] - - - final def _1$extension(underlying: Boolean) = underlying - final def hashCode$extension(underlying: Boolean) = underlying.hashCode() - final def toString$extension(underlying: Boolean) = s"${productPrefix$extension(underlying)}($underlying)" - def productPrefix$extension(underlying: Boolean): String -} - -final class VCBooleanArray[T <: VCBooleanPrototype] private (val arr: Array[Boolean], val ct: VCBooleanCompanion[T]) - extends VCArrayPrototype[T] { - def this(ct: VCBooleanCompanion[T], sz: Int) = - this(new Array[Boolean](sz), ct) - - def apply(idx: Int) = - ct.box(arr(idx)) - def update(idx: Int, elem: T) = - arr(idx) = ct.unbox(elem) - def length: Int = arr.length - - override def clone(): VCBooleanArray[T] = { - new VCBooleanArray[T](arr.clone(), ct) - } - - override def toString: String = { - "[" + ct.runtimeClass - } - - // Todo: what was the reason for 255 classes in my original proposal? arr.toString! - // todo: need to discuss do we want to be compatible with ugly format of jvm here? -} diff --git a/src/dotty/runtime/vc/VCBytePrototype.scala b/src/dotty/runtime/vc/VCBytePrototype.scala deleted file mode 100644 index a8a24dab0e89..000000000000 --- a/src/dotty/runtime/vc/VCBytePrototype.scala +++ /dev/null @@ -1,60 +0,0 @@ -package dotty.runtime.vc - -import scala.reflect.ClassTag - -import scala.runtime.Statics - -abstract class VCBytePrototype(val underlying: Byte) extends VCPrototype {} - -abstract class VCByteCasePrototype(underlying: Byte) extends VCBytePrototype(underlying) with Product1[Byte] { - - final def _1: Byte = underlying - - override final def hashCode(): Int = { - underlying.hashCode() - } - - override final def toString: String = { - s"$productPrefix($underlying)" - } - - // subclasses are expected to implement equals, productPrefix, and canEqual -} - -abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { - def box(underlying: Byte): T - final def unbox(boxed: T) = boxed.underlying - - implicit def classTag: this.type = this - override def newArray(len: Int): Array[T] = - new VCByteArray(this, len).asInstanceOf[Array[T]] - - - final def _1$extension(underlying: Byte) = underlying - final def hashCode$extension(underlying: Byte) = underlying.hashCode() - final def toString$extension(underlying: Byte) = s"${productPrefix$extension(underlying)}($underlying)" - def productPrefix$extension(underlying: Byte): String -} - -final class VCByteArray[T <: VCBytePrototype] private (val arr: Array[Byte], val ct: VCByteCompanion[T]) - extends VCArrayPrototype[T] { - def this(ct: VCByteCompanion[T], sz: Int) = - this(new Array[Byte](sz), ct) - - def apply(idx: Int) = - ct.box(arr(idx)) - def update(idx: Int, elem: T) = - arr(idx) = ct.unbox(elem) - def length: Int = arr.length - - override def clone(): VCByteArray[T] = { - new VCByteArray[T](arr.clone(), ct) - } - - override def toString: String = { - "[" + ct.runtimeClass - } - - // Todo: what was the reason for 255 classes in my original proposal? arr.toString! - // todo: need to discuss do we want to be compatible with ugly format of jvm here? -} diff --git a/src/dotty/runtime/vc/VCCharPrototype.scala b/src/dotty/runtime/vc/VCCharPrototype.scala deleted file mode 100644 index 796821f56186..000000000000 --- a/src/dotty/runtime/vc/VCCharPrototype.scala +++ /dev/null @@ -1,60 +0,0 @@ -package dotty.runtime.vc - -import scala.reflect.ClassTag - -import scala.runtime.Statics - -abstract class VCCharPrototype(val underlying: Char) extends VCPrototype {} - -abstract class VCCharCasePrototype(underlying: Char) extends VCCharPrototype(underlying) with Product1[Char] { - - final def _1: Char = underlying - - override final def hashCode(): Int = { - underlying.hashCode() - } - - override final def toString: String = { - s"$productPrefix($underlying)" - } - - // subclasses are expected to implement equals, productPrefix, and canEqual -} - -abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { - def box(underlying: Char): T - final def unbox(boxed: T) = boxed.underlying - - implicit def classTag: this.type = this - override def newArray(len: Int): Array[T] = - new VCCharArray(this, len).asInstanceOf[Array[T]] - - - final def _1$extension(underlying: Char) = underlying - final def hashCode$extension(underlying: Char) = underlying.hashCode() - final def toString$extension(underlying: Char) = s"${productPrefix$extension(underlying)}($underlying)" - def productPrefix$extension(underlying: Char): String -} - -final class VCCharArray[T <: VCCharPrototype] private (val arr: Array[Char], val ct: VCCharCompanion[T]) - extends VCArrayPrototype[T] { - def this(ct: VCCharCompanion[T], sz: Int) = - this(new Array[Char](sz), ct) - - def apply(idx: Int) = - ct.box(arr(idx)) - def update(idx: Int, elem: T) = - arr(idx) = ct.unbox(elem) - def length: Int = arr.length - - override def clone(): VCCharArray[T] = { - new VCCharArray[T](arr.clone(), ct) - } - - override def toString: String = { - "[" + ct.runtimeClass - } - - // Todo: what was the reason for 255 classes in my original proposal? arr.toString! - // todo: need to discuss do we want to be compatible with ugly format of jvm here? -} diff --git a/src/dotty/runtime/vc/VCDoublePrototype.scala b/src/dotty/runtime/vc/VCDoublePrototype.scala deleted file mode 100644 index 2a3f90f07eaf..000000000000 --- a/src/dotty/runtime/vc/VCDoublePrototype.scala +++ /dev/null @@ -1,60 +0,0 @@ -package dotty.runtime.vc - -import scala.reflect.ClassTag - -import scala.runtime.Statics - -abstract class VCDoublePrototype(val underlying: Double) extends VCPrototype {} - -abstract class VCDoubleCasePrototype(underlying: Double) extends VCDoublePrototype(underlying) with Product1[Double] { - - final def _1: Double = underlying - - override final def hashCode(): Int = { - underlying.hashCode() - } - - override final def toString: String = { - s"$productPrefix($underlying)" - } - - // subclasses are expected to implement equals, productPrefix, and canEqual -} - -abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { - def box(underlying: Double): T - final def unbox(boxed: T) = boxed.underlying - - implicit def classTag: this.type = this - override def newArray(len: Int): Array[T] = - new VCDoubleArray(this, len).asInstanceOf[Array[T]] - - - final def _1$extension(underlying: Double) = underlying - final def hashCode$extension(underlying: Double) = underlying.hashCode() - final def toString$extension(underlying: Double) = s"${productPrefix$extension(underlying)}($underlying)" - def productPrefix$extension(underlying: Double): String -} - -final class VCDoubleArray[T <: VCDoublePrototype] private (val arr: Array[Double], val ct: VCDoubleCompanion[T]) - extends VCArrayPrototype[T] { - def this(ct: VCDoubleCompanion[T], sz: Int) = - this(new Array[Double](sz), ct) - - def apply(idx: Int) = - ct.box(arr(idx)) - def update(idx: Int, elem: T) = - arr(idx) = ct.unbox(elem) - def length: Int = arr.length - - override def clone(): VCDoubleArray[T] = { - new VCDoubleArray[T](arr.clone(), ct) - } - - override def toString: String = { - "[" + ct.runtimeClass - } - - // Todo: what was the reason for 255 classes in my original proposal? arr.toString! - // todo: need to discuss do we want to be compatible with ugly format of jvm here? -} diff --git a/src/dotty/runtime/vc/VCFloatPrototype.scala b/src/dotty/runtime/vc/VCFloatPrototype.scala deleted file mode 100644 index c3e1101105c7..000000000000 --- a/src/dotty/runtime/vc/VCFloatPrototype.scala +++ /dev/null @@ -1,60 +0,0 @@ -package dotty.runtime.vc - -import scala.reflect.ClassTag - -import scala.runtime.Statics - -abstract class VCFloatPrototype(val underlying: Float) extends VCPrototype {} - -abstract class VCFloatCasePrototype(underlying: Float) extends VCFloatPrototype(underlying) with Product1[Float] { - - final def _1: Float = underlying - - override final def hashCode(): Int = { - underlying.hashCode() - } - - override final def toString: String = { - s"$productPrefix($underlying)" - } - - // subclasses are expected to implement equals, productPrefix, and canEqual -} - -abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { - def box(underlying: Float): T - final def unbox(boxed: T) = boxed.underlying - - implicit def classTag: this.type = this - override def newArray(len: Int): Array[T] = - new VCFloatArray(this, len).asInstanceOf[Array[T]] - - - final def _1$extension(underlying: Float) = underlying - final def hashCode$extension(underlying: Float) = underlying.hashCode() - final def toString$extension(underlying: Float) = s"${productPrefix$extension(underlying)}($underlying)" - def productPrefix$extension(underlying: Float): String -} - -final class VCFloatArray[T <: VCFloatPrototype] private (val arr: Array[Float], val ct: VCFloatCompanion[T]) - extends VCArrayPrototype[T] { - def this(ct: VCFloatCompanion[T], sz: Int) = - this(new Array[Float](sz), ct) - - def apply(idx: Int) = - ct.box(arr(idx)) - def update(idx: Int, elem: T) = - arr(idx) = ct.unbox(elem) - def length: Int = arr.length - - override def clone(): VCFloatArray[T] = { - new VCFloatArray[T](arr.clone(), ct) - } - - override def toString: String = { - "[" + ct.runtimeClass - } - - // Todo: what was the reason for 255 classes in my original proposal? arr.toString! - // todo: need to discuss do we want to be compatible with ugly format of jvm here? -} diff --git a/src/dotty/runtime/vc/VCIntPrototype.scala b/src/dotty/runtime/vc/VCIntPrototype.scala deleted file mode 100644 index 44f746ed4b9c..000000000000 --- a/src/dotty/runtime/vc/VCIntPrototype.scala +++ /dev/null @@ -1,60 +0,0 @@ -package dotty.runtime.vc - -import scala.reflect.ClassTag - -import scala.runtime.Statics - -abstract class VCIntPrototype(val underlying: Int) extends VCPrototype {} - -abstract class VCIntCasePrototype(underlying: Int) extends VCIntPrototype(underlying) with Product1[Int] { - - final def _1: Int = underlying - - override final def hashCode(): Int = { - underlying.hashCode() - } - - override final def toString: String = { - s"$productPrefix($underlying)" - } - - // subclasses are expected to implement equals, productPrefix, and canEqual -} - -abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { - def box(underlying: Int): T - final def unbox(boxed: T) = boxed.underlying - - implicit def classTag: this.type = this - override def newArray(len: Int): Array[T] = - new VCIntArray(this, len).asInstanceOf[Array[T]] - - - final def _1$extension(underlying: Int) = underlying - final def hashCode$extension(underlying: Int) = underlying.hashCode() - final def toString$extension(underlying: Int) = s"${productPrefix$extension(underlying)}($underlying)" - def productPrefix$extension(underlying: Int): String -} - -final class VCIntArray[T <: VCIntPrototype] private (val arr: Array[Int], val ct: VCIntCompanion[T]) - extends VCArrayPrototype[T] { - def this(ct: VCIntCompanion[T], sz: Int) = - this(new Array[Int](sz), ct) - - def apply(idx: Int) = - ct.box(arr(idx)) - def update(idx: Int, elem: T) = - arr(idx) = ct.unbox(elem) - def length: Int = arr.length - - override def clone(): VCIntArray[T] = { - new VCIntArray[T](arr.clone(), ct) - } - - override def toString: String = { - "[" + ct.runtimeClass - } - - // Todo: what was the reason for 255 classes in my original proposal? arr.toString! - // todo: need to discuss do we want to be compatible with ugly format of jvm here? -} diff --git a/src/dotty/runtime/vc/VCLongPrototype.scala b/src/dotty/runtime/vc/VCLongPrototype.scala deleted file mode 100644 index 83690bcfdd09..000000000000 --- a/src/dotty/runtime/vc/VCLongPrototype.scala +++ /dev/null @@ -1,60 +0,0 @@ -package dotty.runtime.vc - -import scala.reflect.ClassTag - -import scala.runtime.Statics - -abstract class VCLongPrototype(val underlying: Long) extends VCPrototype {} - -abstract class VCLongCasePrototype(underlying: Long) extends VCLongPrototype(underlying) with Product1[Long] { - - final def _1: Long = underlying - - override final def hashCode(): Int = { - underlying.hashCode() - } - - override final def toString: String = { - s"$productPrefix($underlying)" - } - - // subclasses are expected to implement equals, productPrefix, and canEqual -} - -abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { - def box(underlying: Long): T - final def unbox(boxed: T) = boxed.underlying - - implicit def classTag: this.type = this - override def newArray(len: Int): Array[T] = - new VCLongArray(this, len).asInstanceOf[Array[T]] - - - final def _1$extension(underlying: Long) = underlying - final def hashCode$extension(underlying: Long) = underlying.hashCode() - final def toString$extension(underlying: Long) = s"${productPrefix$extension(underlying)}($underlying)" - def productPrefix$extension(underlying: Long): String -} - -final class VCLongArray[T <: VCLongPrototype] private (val arr: Array[Long], val ct: VCLongCompanion[T]) - extends VCArrayPrototype[T] { - def this(ct: VCLongCompanion[T], sz: Int) = - this(new Array[Long](sz), ct) - - def apply(idx: Int) = - ct.box(arr(idx)) - def update(idx: Int, elem: T) = - arr(idx) = ct.unbox(elem) - def length: Int = arr.length - - override def clone(): VCLongArray[T] = { - new VCLongArray[T](arr.clone(), ct) - } - - override def toString: String = { - "[" + ct.runtimeClass - } - - // Todo: what was the reason for 255 classes in my original proposal? arr.toString! - // todo: need to discuss do we want to be compatible with ugly format of jvm here? -} diff --git a/src/dotty/runtime/vc/VCObjectPrototype.scala b/src/dotty/runtime/vc/VCObjectPrototype.scala deleted file mode 100644 index fd0c8728a523..000000000000 --- a/src/dotty/runtime/vc/VCObjectPrototype.scala +++ /dev/null @@ -1,60 +0,0 @@ -package dotty.runtime.vc - -import scala.reflect.ClassTag - -import scala.runtime.Statics - -abstract class VCObjectPrototype(val underlying: Object) extends VCPrototype {} - -abstract class VCObjectCasePrototype(underlying: Object) extends VCObjectPrototype(underlying) with Product1[Object] { - - final def _1: Object = underlying - - override final def hashCode(): Int = { - underlying.hashCode() - } - - override final def toString: String = { - s"$productPrefix($underlying)" - } - - // subclasses are expected to implement equals, productPrefix, and canEqual -} - -abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { - def box(underlying: Object): T - final def unbox(boxed: T) = boxed.underlying - - implicit def classTag: this.type = this - override def newArray(len: Int): Array[T] = - new VCObjectArray(this, len).asInstanceOf[Array[T]] - - - final def _1$extension(underlying: Object) = underlying - final def hashCode$extension(underlying: Object) = underlying.hashCode() - final def toString$extension(underlying: Object) = s"${productPrefix$extension(underlying)}($underlying)" - def productPrefix$extension(underlying: Object): String -} - -final class VCObjectArray[T <: VCObjectPrototype] private (val arr: Array[Object], val ct: VCObjectCompanion[T]) - extends VCArrayPrototype[T] { - def this(ct: VCObjectCompanion[T], sz: Int) = - this(new Array[Object](sz), ct) - - def apply(idx: Int) = - ct.box(arr(idx)) - def update(idx: Int, elem: T) = - arr(idx) = ct.unbox(elem) - def length: Int = arr.length - - override def clone(): VCObjectArray[T] = { - new VCObjectArray[T](arr.clone(), ct) - } - - override def toString: String = { - "[" + ct.runtimeClass - } - - // Todo: what was the reason for 255 classes in my original proposal? arr.toString! - // todo: need to discuss do we want to be compatible with ugly format of jvm here? -} diff --git a/src/dotty/runtime/vc/VCPrototype.scala b/src/dotty/runtime/vc/VCPrototype.scala index 61ed93b92130..0a3abe5a25e6 100644 --- a/src/dotty/runtime/vc/VCPrototype.scala +++ b/src/dotty/runtime/vc/VCPrototype.scala @@ -1,5 +1,7 @@ package dotty.runtime.vc +import scala.reflect.ClassTag + abstract class VCPrototype { } @@ -10,3 +12,475 @@ abstract class VCArrayPrototype[T <: VCPrototype] extends Object with Cloneable def length: Int override def clone: Object = super.clone() } + + +abstract class VCFloatPrototype(val underlying: Float) extends VCPrototype {} + +abstract class VCFloatCasePrototype(underlying: Float) extends VCFloatPrototype(underlying) with Product1[Float] { + + final def _1: Float = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } +} + +abstract class VCFloatCompanion[T <: VCFloatPrototype] extends ClassTag[T] { + def box(underlying: Float): T + final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this + override def newArray(len: Int): Array[T] = + new VCFloatArray(this, len).asInstanceOf[Array[T]] + + + final def _1$extension(underlying: Float) = underlying + final def hashCode$extension(underlying: Float) = underlying.hashCode() + final def toString$extension(underlying: Float) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Float): String +} + +final class VCFloatArray[T <: VCFloatPrototype] private (val arr: Array[Float], val ct: VCFloatCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCFloatCompanion[T], sz: Int) = + this(new Array[Float](sz), ct) + + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def clone(): VCFloatArray[T] = { + new VCFloatArray[T](arr.clone(), ct) + } + + override def toString: String = { + "[" + ct.runtimeClass + } +} + + +abstract class VCObjectPrototype(val underlying: Object) extends VCPrototype {} + +abstract class VCObjectCasePrototype(underlying: Object) extends VCObjectPrototype(underlying) with Product1[Object] { + + final def _1: Object = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } +} + +abstract class VCObjectCompanion[T <: VCObjectPrototype] extends ClassTag[T] { + def box(underlying: Object): T + final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this + override def newArray(len: Int): Array[T] = + new VCObjectArray(this, len).asInstanceOf[Array[T]] + + + final def _1$extension(underlying: Object) = underlying + final def hashCode$extension(underlying: Object) = underlying.hashCode() + final def toString$extension(underlying: Object) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Object): String +} + +final class VCObjectArray[T <: VCObjectPrototype] private (val arr: Array[Object], val ct: VCObjectCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCObjectCompanion[T], sz: Int) = + this(new Array[Object](sz), ct) + + def apply(idx: Int) = + ct.box(arr(idx)) + + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + + def length: Int = arr.length + + override def clone(): VCObjectArray[T] = { + new VCObjectArray[T](arr.clone(), ct) + } + + override def toString: String = { + "[" + ct.runtimeClass + } +} + + +abstract class VCShortPrototype(val underlying: Short) extends VCPrototype {} + +abstract class VCShortCasePrototype(underlying: Short) extends VCShortPrototype(underlying) with Product1[Short] { + + final def _1: Short = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } +} + +abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { + def box(underlying: Short): T + final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this + override def newArray(len: Int): Array[T] = + new VCShortArray(this, len).asInstanceOf[Array[T]] + + + final def _1$extension(underlying: Short) = underlying + final def hashCode$extension(underlying: Short) = underlying.hashCode() + final def toString$extension(underlying: Short) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Short): String +} + +final class VCShortArray[T <: VCShortPrototype] private (val arr: Array[Short], val ct: VCShortCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCShortCompanion[T], sz: Int) = + this(new Array[Short](sz), ct) + + def apply(idx: Int) = + ct.box(arr(idx)) + + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + + def length: Int = arr.length + + override def clone(): VCShortArray[T] = { + new VCShortArray[T](arr.clone(), ct) + } + + override def toString: String = { + "[" + ct.runtimeClass + } + +} + + +abstract class VCLongPrototype(val underlying: Long) extends VCPrototype {} + +abstract class VCLongCasePrototype(underlying: Long) extends VCLongPrototype(underlying) with Product1[Long] { + + final def _1: Long = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } +} + +abstract class VCLongCompanion[T <: VCLongPrototype] extends ClassTag[T] { + def box(underlying: Long): T + final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this + override def newArray(len: Int): Array[T] = + new VCLongArray(this, len).asInstanceOf[Array[T]] + + + final def _1$extension(underlying: Long) = underlying + final def hashCode$extension(underlying: Long) = underlying.hashCode() + final def toString$extension(underlying: Long) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Long): String +} + +final class VCLongArray[T <: VCLongPrototype] private (val arr: Array[Long], val ct: VCLongCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCLongCompanion[T], sz: Int) = + this(new Array[Long](sz), ct) + + def apply(idx: Int) = + ct.box(arr(idx)) + + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + + def length: Int = arr.length + + override def clone(): VCLongArray[T] = { + new VCLongArray[T](arr.clone(), ct) + } + + override def toString: String = { + "[" + ct.runtimeClass + } +} + + +abstract class VCIntPrototype(val underlying: Int) extends VCPrototype {} + +abstract class VCIntCasePrototype(underlying: Int) extends VCIntPrototype(underlying) with Product1[Int] { + + final def _1: Int = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } +} + +abstract class VCIntCompanion[T <: VCIntPrototype] extends ClassTag[T] { + def box(underlying: Int): T + final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this + override def newArray(len: Int): Array[T] = + new VCIntArray(this, len).asInstanceOf[Array[T]] + + + final def _1$extension(underlying: Int) = underlying + final def hashCode$extension(underlying: Int) = underlying.hashCode() + final def toString$extension(underlying: Int) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Int): String +} + +final class VCIntArray[T <: VCIntPrototype] private (val arr: Array[Int], val ct: VCIntCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCIntCompanion[T], sz: Int) = + this(new Array[Int](sz), ct) + + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def clone(): VCIntArray[T] = { + new VCIntArray[T](arr.clone(), ct) + } + + override def toString: String = { + "[" + ct.runtimeClass + } +} + + +abstract class VCDoublePrototype(val underlying: Double) extends VCPrototype {} + +abstract class VCDoubleCasePrototype(underlying: Double) extends VCDoublePrototype(underlying) with Product1[Double] { + + final def _1: Double = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } +} + +abstract class VCDoubleCompanion[T <: VCDoublePrototype] extends ClassTag[T] { + def box(underlying: Double): T + final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this + override def newArray(len: Int): Array[T] = + new VCDoubleArray(this, len).asInstanceOf[Array[T]] + + + final def _1$extension(underlying: Double) = underlying + final def hashCode$extension(underlying: Double) = underlying.hashCode() + final def toString$extension(underlying: Double) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Double): String +} + +final class VCDoubleArray[T <: VCDoublePrototype] private (val arr: Array[Double], val ct: VCDoubleCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCDoubleCompanion[T], sz: Int) = + this(new Array[Double](sz), ct) + + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def clone(): VCDoubleArray[T] = { + new VCDoubleArray[T](arr.clone(), ct) + } + + override def toString: String = { + "[" + ct.runtimeClass + } +} + + +abstract class VCBooleanPrototype(val underlying: Boolean) extends VCPrototype {} + +abstract class VCBooleanCasePrototype(underlying: Boolean) extends VCBooleanPrototype(underlying) with Product1[Boolean] { + + final def _1: Boolean = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } +} + +abstract class VCBooleanCompanion[T <: VCBooleanPrototype] extends ClassTag[T] { + def box(underlying: Boolean): T + final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this + override def newArray(len: Int): Array[T] = + new VCBooleanArray(this, len).asInstanceOf[Array[T]] + + + final def _1$extension(underlying: Boolean) = underlying + final def hashCode$extension(underlying: Boolean) = underlying.hashCode() + final def toString$extension(underlying: Boolean) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Boolean): String +} + +final class VCBooleanArray[T <: VCBooleanPrototype] private (val arr: Array[Boolean], val ct: VCBooleanCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCBooleanCompanion[T], sz: Int) = + this(new Array[Boolean](sz), ct) + + def apply(idx: Int) = + ct.box(arr(idx)) + + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + + def length: Int = arr.length + + override def clone(): VCBooleanArray[T] = { + new VCBooleanArray[T](arr.clone(), ct) + } + + override def toString: String = { + "[" + ct.runtimeClass + } +} + + +abstract class VCCharPrototype(val underlying: Char) extends VCPrototype {} + +abstract class VCCharCasePrototype(underlying: Char) extends VCCharPrototype(underlying) with Product1[Char] { + + final def _1: Char = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } + + // subclasses are expected to implement equals, productPrefix, and canEqual +} + +abstract class VCCharCompanion[T <: VCCharPrototype] extends ClassTag[T] { + def box(underlying: Char): T + final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this + override def newArray(len: Int): Array[T] = + new VCCharArray(this, len).asInstanceOf[Array[T]] + + + final def _1$extension(underlying: Char) = underlying + final def hashCode$extension(underlying: Char) = underlying.hashCode() + final def toString$extension(underlying: Char) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Char): String +} + +final class VCCharArray[T <: VCCharPrototype] private (val arr: Array[Char], val ct: VCCharCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCCharCompanion[T], sz: Int) = + this(new Array[Char](sz), ct) + + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def clone(): VCCharArray[T] = { + new VCCharArray[T](arr.clone(), ct) + } + + override def toString: String = { + "[" + ct.runtimeClass + } +} + + +abstract class VCBytePrototype(val underlying: Byte) extends VCPrototype {} + +abstract class VCByteCasePrototype(underlying: Byte) extends VCBytePrototype(underlying) with Product1[Byte] { + + final def _1: Byte = underlying + + override final def hashCode(): Int = { + underlying.hashCode() + } + + override final def toString: String = { + s"$productPrefix($underlying)" + } +} + +abstract class VCByteCompanion[T <: VCBytePrototype] extends ClassTag[T] { + def box(underlying: Byte): T + final def unbox(boxed: T) = boxed.underlying + + implicit def classTag: this.type = this + override def newArray(len: Int): Array[T] = + new VCByteArray(this, len).asInstanceOf[Array[T]] + + + final def _1$extension(underlying: Byte) = underlying + final def hashCode$extension(underlying: Byte) = underlying.hashCode() + final def toString$extension(underlying: Byte) = s"${productPrefix$extension(underlying)}($underlying)" + def productPrefix$extension(underlying: Byte): String +} + +final class VCByteArray[T <: VCBytePrototype] private (val arr: Array[Byte], val ct: VCByteCompanion[T]) + extends VCArrayPrototype[T] { + def this(ct: VCByteCompanion[T], sz: Int) = + this(new Array[Byte](sz), ct) + + def apply(idx: Int) = + ct.box(arr(idx)) + def update(idx: Int, elem: T) = + arr(idx) = ct.unbox(elem) + def length: Int = arr.length + + override def clone(): VCByteArray[T] = { + new VCByteArray[T](arr.clone(), ct) + } + + override def toString: String = { + "[" + ct.runtimeClass + } + +} + diff --git a/src/dotty/runtime/vc/VCShortPrototype.scala b/src/dotty/runtime/vc/VCShortPrototype.scala deleted file mode 100644 index 519e6d5c8235..000000000000 --- a/src/dotty/runtime/vc/VCShortPrototype.scala +++ /dev/null @@ -1,60 +0,0 @@ -package dotty.runtime.vc - -import scala.reflect.ClassTag - -import scala.runtime.Statics - -abstract class VCShortPrototype(val underlying: Short) extends VCPrototype {} - -abstract class VCShortCasePrototype(underlying: Short) extends VCShortPrototype(underlying) with Product1[Short] { - - final def _1: Short = underlying - - override final def hashCode(): Int = { - underlying.hashCode() - } - - override final def toString: String = { - s"$productPrefix($underlying)" - } - - // subclasses are expected to implement equals, productPrefix, and canEqual -} - -abstract class VCShortCompanion[T <: VCShortPrototype] extends ClassTag[T] { - def box(underlying: Short): T - final def unbox(boxed: T) = boxed.underlying - - implicit def classTag: this.type = this - override def newArray(len: Int): Array[T] = - new VCShortArray(this, len).asInstanceOf[Array[T]] - - - final def _1$extension(underlying: Short) = underlying - final def hashCode$extension(underlying: Short) = underlying.hashCode() - final def toString$extension(underlying: Short) = s"${productPrefix$extension(underlying)}($underlying)" - def productPrefix$extension(underlying: Short): String -} - -final class VCShortArray[T <: VCShortPrototype] private (val arr: Array[Short], val ct: VCShortCompanion[T]) - extends VCArrayPrototype[T] { - def this(ct: VCShortCompanion[T], sz: Int) = - this(new Array[Short](sz), ct) - - def apply(idx: Int) = - ct.box(arr(idx)) - def update(idx: Int, elem: T) = - arr(idx) = ct.unbox(elem) - def length: Int = arr.length - - override def clone(): VCShortArray[T] = { - new VCShortArray[T](arr.clone(), ct) - } - - override def toString: String = { - "[" + ct.runtimeClass - } - - // Todo: what was the reason for 255 classes in my original proposal? arr.toString! - // todo: need to discuss do we want to be compatible with ugly format of jvm here? -} From 5ae3e10f28db0b7945c27032e5154716c35d82ce Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 5 May 2015 20:07:55 +0200 Subject: [PATCH 15/16] Add primitive ClassTags to DottyPredef --- src/dotty/DottyPredef.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/dotty/DottyPredef.scala b/src/dotty/DottyPredef.scala index 4b68e4029638..7f0a4914a41e 100644 --- a/src/dotty/DottyPredef.scala +++ b/src/dotty/DottyPredef.scala @@ -8,4 +8,20 @@ object DottyPredef { /** implicits for ClassTag and TypeTag. Should be implemented with macros */ implicit def classTag[T]: ClassTag[T] = scala.Predef.??? implicit def typeTag[T]: TypeTag[T] = scala.Predef.??? + + implicit val IntClassTag = ClassTag.Int + implicit val ByteClassTag = ClassTag.Byte + implicit val ShortClassTag = ClassTag.Short + implicit val CharClassTag = ClassTag.Char + implicit val LongClassTag = ClassTag.Long + implicit val FloatClassTag = ClassTag.Float + implicit val DoubleClassTag = ClassTag.Double + implicit val BooleanClassTag = ClassTag.Boolean + implicit val UnitClassTag = ClassTag.Unit + implicit val AnyClassTag = ClassTag.Any + implicit val AnyRefClassTag = ClassTag.AnyRef + implicit val AnyValClassTag = ClassTag.AnyVal + implicit val ObjectClassTag = ClassTag.Object + implicit val NullClassTag = ClassTag.Null + implicit val NothingClassTag = ClassTag.Nothing } From c0d265a52c34ddfd77f4237d215a085675b25a57 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 5 May 2015 20:12:15 +0200 Subject: [PATCH 16/16] Give implicit ClassTags in DottyPredef explicit types. --- src/dotty/DottyPredef.scala | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/dotty/DottyPredef.scala b/src/dotty/DottyPredef.scala index 7f0a4914a41e..7c8098bd1763 100644 --- a/src/dotty/DottyPredef.scala +++ b/src/dotty/DottyPredef.scala @@ -8,20 +8,18 @@ object DottyPredef { /** implicits for ClassTag and TypeTag. Should be implemented with macros */ implicit def classTag[T]: ClassTag[T] = scala.Predef.??? implicit def typeTag[T]: TypeTag[T] = scala.Predef.??? - - implicit val IntClassTag = ClassTag.Int - implicit val ByteClassTag = ClassTag.Byte - implicit val ShortClassTag = ClassTag.Short - implicit val CharClassTag = ClassTag.Char - implicit val LongClassTag = ClassTag.Long - implicit val FloatClassTag = ClassTag.Float - implicit val DoubleClassTag = ClassTag.Double - implicit val BooleanClassTag = ClassTag.Boolean - implicit val UnitClassTag = ClassTag.Unit - implicit val AnyClassTag = ClassTag.Any - implicit val AnyRefClassTag = ClassTag.AnyRef - implicit val AnyValClassTag = ClassTag.AnyVal - implicit val ObjectClassTag = ClassTag.Object - implicit val NullClassTag = ClassTag.Null - implicit val NothingClassTag = ClassTag.Nothing + + + /** ClassTags for final classes */ + implicit val IntClassTag: ClassTag[Int] = ClassTag.Int + implicit val ByteClassTag: ClassTag[Byte] = ClassTag.Byte + implicit val ShortClassTag: ClassTag[Short] = ClassTag.Short + implicit val CharClassTag: ClassTag[Char] = ClassTag.Char + implicit val LongClassTag: ClassTag[Long] = ClassTag.Long + implicit val FloatClassTag: ClassTag[Float] = ClassTag.Float + implicit val DoubleClassTag: ClassTag[Double] = ClassTag.Double + implicit val BooleanClassTag: ClassTag[Boolean] = ClassTag.Boolean + implicit val UnitClassTag: ClassTag[Unit] = ClassTag.Unit + implicit val NullClassTag: ClassTag[Null] = ClassTag.Null + implicit val NothingClassTag: ClassTag[Nothing] = ClassTag.Nothing }