aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/pickling/PickleFormat.scala113
-rw-r--r--src/dotty/tools/dotc/core/pickling/TastyBuffer.scala38
-rw-r--r--src/dotty/tools/dotc/core/pickling/TastyReader.scala32
-rw-r--r--src/dotty/tools/dotc/core/pickling/TreePickler.scala19
4 files changed, 128 insertions, 74 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/PickleFormat.scala b/src/dotty/tools/dotc/core/pickling/PickleFormat.scala
index 10420e723..e4bd95af2 100644
--- a/src/dotty/tools/dotc/core/pickling/PickleFormat.scala
+++ b/src/dotty/tools/dotc/core/pickling/PickleFormat.scala
@@ -14,7 +14,9 @@ can be dropped without changing the grammar.
Micro-syntax:
LongNat = Digit* StopDigit // big endian, value fits in a Long without overflow
+ LongInt = LongNat // big endian 2's complement, value fits in a Long without overflow
Nat = LongNat // value fits in an Int without overflow
+ Int = LongInt // value fits in an Int without overflow
Digit = 0 | ... | 127
StopDigit = 128 | ... | 255 // value = digit - 128
@@ -103,23 +105,17 @@ Standard-Section: "ASTs" Tree*
Constant = UNITconst
FALSEconst
TRUEconst
- BYTEconst Nat
- BYTEneg NegNat
- SHORTconst Nat
- SHORTneg NegNat
+ BYTEconst Int
+ SHORTconst Int
CHARconst Nat
- INTconst Nat
- INTneg NegNat
- LONGconst LongNat
- LONGneg NegLongNat
- FLOATconst LongNat
- DOUBLEconst LongNat
+ INTconst Int
+ LONGconst LongInt
+ FLOATconst Int
+ DOUBLEconst LongInt
STRINGconst NameRef
NULLconst
CLASSconst Length Type
ENUMconst Length Path
- NegNat = Nat // negValue = -natValue - 1
- NegLongNat = LongNat // negValue = -natValue - 1
Type = Path
TYPEREFdirect sym_ASTRef
@@ -186,8 +182,9 @@ Note: Tree tags are grouped into 4 categories that determine what follows, and t
Standard Section: "Positions" startPos_Index endPos_Index
Index = Length Assoc*
- Assoc = Delta ASTRef // largest tree starting/ending at offset
- Delta = Nat // # chars from last offset or start of file
+ Assoc = offset_Delta addr_Delta // largest tree starting/ending at offset
+ Delta = Int // difference between consecutive offsets / tree addresses,
+ // First offset/address is always assumed to be 0
**************************************************************************************/
@@ -195,7 +192,7 @@ object PickleFormat {
final val header = "5CA1AB1F"
final val MajorVersion = 0
- final val MinorVersion = 3
+ final val MinorVersion = 4
// Name tags
@@ -211,38 +208,38 @@ object PickleFormat {
final val EMPTYTREE = 0
final val NOTYPE = 1
- final val UNITconst = 3
- final val FALSEconst = 4
- final val TRUEconst = 5
- final val NULLconst = 6
- final val PRIVATE = 7
- final val INTERNAL = 8
- final val PROTECTED = 9
- final val ABSTRACT = 10
- final val FINAL = 11
- final val SEALED = 12
- final val CASE = 13
- final val IMPLICIT = 14
- final val LAZY = 15
- final val OVERRIDE = 16
- final val INLINE = 17
- final val ABSOVERRIDE = 18
- final val STATIC = 19
- final val MODULE = 20
- final val LOCAL = 21
- final val SYNTHETIC = 22
- final val ARTIFACT = 23
- final val MUTABLE = 24
- final val LABEL = 25
- final val FIELDaccessor = 26
- final val PARAMaccessor = 27
- final val CASEaccessor = 28
- final val COVARIANT = 29
- final val CONTRAVARIANT = 30
- final val SCALA2X = 31
- final val DEFAULTparameterized = 32
- final val DEFAULTinit = 33
- final val INSUPERCALL = 34
+ final val UNITconst = 2
+ final val FALSEconst = 3
+ final val TRUEconst = 4
+ final val NULLconst = 5
+ final val PRIVATE = 6
+ final val INTERNAL = 7
+ final val PROTECTED = 8
+ final val ABSTRACT = 9
+ final val FINAL = 10
+ final val SEALED = 11
+ final val CASE = 12
+ final val IMPLICIT = 13
+ final val LAZY = 14
+ final val OVERRIDE = 15
+ final val INLINE = 16
+ final val ABSOVERRIDE = 17
+ final val STATIC = 18
+ final val MODULE = 19
+ final val LOCAL = 20
+ final val SYNTHETIC = 21
+ final val ARTIFACT = 22
+ final val MUTABLE = 23
+ final val LABEL = 24
+ final val FIELDaccessor = 25
+ final val PARAMaccessor = 26
+ final val CASEaccessor = 27
+ final val COVARIANT = 28
+ final val CONTRAVARIANT = 29
+ final val SCALA2X = 30
+ final val DEFAULTparameterized = 31
+ final val DEFAULTinit = 32
+ final val INSUPERCALL = 33
final val SHARED = 64
final val TERMREFdirect = 65
@@ -251,17 +248,13 @@ object PickleFormat {
final val TYPEREFstatic = 68
final val SKOLEMtype = 69
final val BYTEconst = 70
- final val BYTEneg = 71
- final val SHORTconst = 72
- final val SHORTneg = 73
- final val CHARconst = 74
- final val INTconst = 75
- final val INTneg = 76
- final val LONGconst = 77
- final val LONGneg = 78
- final val FLOATconst = 79
- final val DOUBLEconst = 80
- final val STRINGconst = 81
+ final val SHORTconst = 71
+ final val CHARconst = 72
+ final val INTconst = 73
+ final val LONGconst = 74
+ final val FLOATconst = 75
+ final val DOUBLEconst = 76
+ final val STRINGconst = 77
final val IDENT = 100
final val SELECT = 101
@@ -381,14 +374,10 @@ object PickleFormat {
case TYPEREFstatic => "TYPEREFstatic"
case SKOLEMtype => "SKOLEMtype"
case BYTEconst => "BYTEconst"
- case BYTEneg => "BYTEneg"
case SHORTconst => "SHORTconst"
- case SHORTneg => "SHORTneg"
case CHARconst => "CHARconst"
case INTconst => "INTconst"
- case INTneg => "INTneg"
case LONGconst => "LONGconst"
- case LONGneg => "LONGneg"
case FLOATconst => "FLOATconst"
case DOUBLEconst => "DOUBLEconst"
case STRINGconst => "STRINGconst"
diff --git a/src/dotty/tools/dotc/core/pickling/TastyBuffer.scala b/src/dotty/tools/dotc/core/pickling/TastyBuffer.scala
index 1c0f6e24f..61dce9efb 100644
--- a/src/dotty/tools/dotc/core/pickling/TastyBuffer.scala
+++ b/src/dotty/tools/dotc/core/pickling/TastyBuffer.scala
@@ -60,6 +60,12 @@ class TastyBuffer(initialSize: Int) {
def writeNat(x: Int): Unit =
writeLongNat(x.toLong & 0x00000000FFFFFFFFL)
+ /** Write a natural number in 2's complement big endian format, base 128.
+ * All but the last digits have bit 0x80 set.
+ */
+ def writeInt(x: Int): Unit =
+ writeLongInt(x)
+
/**
* Like writeNat, but for longs. Note that the
* binary representation of LongNat is identical to Nat
@@ -67,15 +73,38 @@ class TastyBuffer(initialSize: Int) {
* Int.MAX_VALUE.
*/
def writeLongNat(x: Long): Unit = {
- def writeNatPrefix(x: Long): Unit = {
+ def writePrefix(x: Long): Unit = {
val y = x >>> 7
- if (y != 0L) writeNatPrefix(y)
+ if (y != 0L) writePrefix(y)
writeByte((x & 0x7f).toInt)
}
val y = x >>> 7
- if (y != 0L) writeNatPrefix(y)
+ if (y != 0L) writePrefix(y)
writeByte(((x & 0x7f) | 0x80).toInt)
}
+
+ /** Like writeInt, but for longs */
+ def writeLongInt(x: Long): Unit = {
+ def writePrefix(x: Long): Unit = {
+ val y = x >> 7
+ if (y != 0L - ((x >> 6) & 1)) writePrefix(y)
+ writeByte((x & 0x7f).toInt)
+ }
+ val y = x >> 7
+ if (y != 0L - ((x >> 6) & 1)) writePrefix(y)
+ writeByte(((x & 0x7f) | 0x80).toInt)
+ }
+
+ /** Write an uncompressed Long stored in 8 bytes in big endian format */
+ def writeUncompressedLong(x: Long): Unit = {
+ var y = x
+ val bytes = new Array[Byte](8)
+ for (i <- 7 to 0 by -1) {
+ bytes(i) = (y & 0xff).toByte
+ y = y >>> 8
+ }
+ writeBytes(bytes, 8)
+ }
// -- Address handling --------------------------------------------
@@ -140,6 +169,9 @@ class TastyBuffer(initialSize: Int) {
/** Fill reserved space at address `at` with address `target` */
def fillAddr(at: Addr, target: Addr) =
putNat(at, target.index, AddrWidth)
+
+ /** Write address without leading zeroes */
+ def writeAddr(addr: Addr): Unit = writeNat(addr.index)
// -- Finalization --------------------------------------------
diff --git a/src/dotty/tools/dotc/core/pickling/TastyReader.scala b/src/dotty/tools/dotc/core/pickling/TastyReader.scala
index 4e1acf9a9..1b3c82f79 100644
--- a/src/dotty/tools/dotc/core/pickling/TastyReader.scala
+++ b/src/dotty/tools/dotc/core/pickling/TastyReader.scala
@@ -65,6 +65,11 @@ class TastyReader(val bytes: Array[Byte], start: Int, end: Int, val base: Int =
* All but the last digits have bit 0x80 set.
*/
def readNat(): Int = readLongNat.toInt
+
+ /** Read an integer number in 2's complement big endian format, base 128.
+ * All but the last digits have bit 0x80 set.
+ */
+ def readInt(): Int = readLongInt.toInt
/** Read a natural number fitting in a Long in big endian format, base 128.
* All but the last digits have bit 0x80 set.
@@ -79,7 +84,28 @@ class TastyReader(val bytes: Array[Byte], start: Int, end: Int, val base: Int =
} while ((b & 0x80) == 0)
x
}
-
+
+ /** Read a long integer number in 2's complement big endian format, base 128. */
+ def readLongInt(): Long = {
+ var b = bytes(bp)
+ var x = (b << 1).toByte >> 1 // sign extend with bit 6.
+ bp += 1
+ while ((b & 0x80) == 0) {
+ b = bytes(bp)
+ x = (x << 7) | (b & 0x7f)
+ bp += 1
+ }
+ x
+ }
+
+ /** Read an uncompressed Long stored in 8 bytes in big endian format */
+ def readUncompressedLong(): Long = {
+ var x = 0
+ for (i <- 0 to 7)
+ x = (x << 8) | (readByte() & 0xff)
+ x
+ }
+
/** Read a natural number and return as a NameRef */
def readNameRef() = NameRef(readNat())
@@ -103,6 +129,10 @@ class TastyReader(val bytes: Array[Byte], start: Int, end: Int, val base: Int =
buf.toList
}
+ /** If before given `end` address, the result of `op`, otherwise `default` */
+ def ifBefore[T](end: Addr)(op: => T, default: T): T =
+ if (bp < index(end)) op else default
+
/** Perform `op` while cindition `cond` holds and collect results in a list. */
def collectWhile[T](cond: => Boolean)(op: => T): List[T] = {
val buf = new mutable.ListBuffer[T]
diff --git a/src/dotty/tools/dotc/core/pickling/TreePickler.scala b/src/dotty/tools/dotc/core/pickling/TreePickler.scala
index 3284b1a30..cc81ae7ae 100644
--- a/src/dotty/tools/dotc/core/pickling/TreePickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/TreePickler.scala
@@ -77,22 +77,26 @@ class TreePickler(pickler: TastyPickler, picklePositions: Boolean) {
case BooleanTag =>
writeByte(if (c.booleanValue) TRUEconst else FALSEconst)
case ByteTag =>
- pickleNum(BYTEconst, BYTEneg)
+ writeByte(BYTEconst)
+ writeInt(c.byteValue)
case ShortTag =>
- pickleNum(SHORTconst, SHORTneg)
+ writeByte(SHORTconst)
+ writeInt(c.shortValue)
case CharTag =>
writeByte(CHARconst)
writeNat(c.charValue)
case IntTag =>
- pickleNum(INTconst, INTneg)
+ writeByte(INTconst)
+ writeInt(c.intValue)
case LongTag =>
- pickleNum(LONGconst, LONGneg)
+ writeByte(LONGconst)
+ writeLongInt(c.longValue)
case FloatTag =>
writeByte(FLOATconst)
- writeNat(java.lang.Float.floatToRawIntBits(c.floatValue))
+ writeInt(java.lang.Float.floatToRawIntBits(c.floatValue))
case DoubleTag =>
writeByte(DOUBLEconst)
- writeLongNat(java.lang.Double.doubleToRawLongBits(c.doubleValue))
+ writeLongInt(java.lang.Double.doubleToRawLongBits(c.doubleValue))
case StringTag =>
writeByte(STRINGconst)
writeNat(nameIndex(c.stringValue).index)
@@ -111,8 +115,7 @@ class TreePickler(pickler: TastyPickler, picklePositions: Boolean) {
val tpe = tpe0.stripTypeVar
val prev = pickledTypes.get(tpe)
if (prev == null) {
- val addr = currentAddr
- pickledTypes.put(tpe, addr)
+ pickledTypes.put(tpe, currentAddr)
pickleNewType(tpe, richTypes)
}
else {