Skip to content

Commit db8d913

Browse files
authored
Merge pull request scala-js#3802 from sjrd/refactor-type-refs
Use a dedicated `PrimRef` for `TypeRef`s of primitive types.
2 parents 6517d3d + 555d7e0 commit db8d913

File tree

21 files changed

+375
-265
lines changed

21 files changed

+375
-265
lines changed

compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,6 +2726,8 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
27262726
genNew(cls, ctor, genActualArgs(ctor, args))
27272727
case arr: jstpe.ArrayTypeRef =>
27282728
genNewArray(arr, args.map(genExpr))
2729+
case prim: jstpe.PrimRef =>
2730+
abort(s"unexpected primitive type $prim in New at $pos")
27292731
}
27302732
}
27312733
}

compiler/src/main/scala/org/scalajs/nscplugin/JSEncoding.scala

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -245,17 +245,13 @@ trait JSEncoding[G <: Global with Singleton] extends SubComponent {
245245
}
246246

247247
/** Computes the internal name for a type. */
248-
private def internalName(tpe: Type): String = toTypeRef(tpe) match {
249-
case jstpe.ClassRef("sr_Nothing$") => ir.Definitions.NothingClass
250-
case jstpe.ClassRef("sr_Null$") => ir.Definitions.NullClass
251-
case jstpe.ClassRef(cls) => cls
252-
253-
case jstpe.ArrayTypeRef(cls, depth) =>
254-
val builder = new java.lang.StringBuilder(cls.length + depth)
255-
for (i <- 0 until depth)
256-
builder.append('A')
257-
builder.append(cls)
258-
builder.toString()
248+
private def internalName(tpe: Type): String = {
249+
val patchedTypeRef = toTypeRef(tpe) match {
250+
case jstpe.ClassRef("sr_Nothing$") => jstpe.NothingRef
251+
case jstpe.ClassRef("sr_Null$") => jstpe.NullRef
252+
case typeRef => typeRef
253+
}
254+
ir.Definitions.encodeTypeRef(patchedTypeRef)
259255
}
260256

261257
/** mangles names that are illegal in JavaScript by prepending a $

compiler/src/main/scala/org/scalajs/nscplugin/TypeConversions.scala

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,19 @@ trait TypeConversions[G <: Global with Singleton] extends SubComponent {
4040
)
4141
}
4242

43-
private lazy val primitiveClassRefNameMap: Map[Symbol, String] = {
43+
private lazy val primitiveRefMap: Map[Symbol, Types.NonArrayTypeRef] = {
4444
Map(
45-
UnitClass -> Definitions.VoidClass,
46-
BooleanClass -> Definitions.BooleanClass,
47-
CharClass -> Definitions.CharClass,
48-
ByteClass -> Definitions.ByteClass,
49-
ShortClass -> Definitions.ShortClass,
50-
IntClass -> Definitions.IntClass,
51-
LongClass -> Definitions.LongClass,
52-
FloatClass -> Definitions.FloatClass,
53-
DoubleClass -> Definitions.DoubleClass,
54-
NothingClass -> encodeClassFullName(RuntimeNothingClass),
55-
NullClass -> encodeClassFullName(RuntimeNullClass)
45+
UnitClass -> Types.VoidRef,
46+
BooleanClass -> Types.BooleanRef,
47+
CharClass -> Types.CharRef,
48+
ByteClass -> Types.ByteRef,
49+
ShortClass -> Types.ShortRef,
50+
IntClass -> Types.IntRef,
51+
LongClass -> Types.LongRef,
52+
FloatClass -> Types.FloatRef,
53+
DoubleClass -> Types.DoubleRef,
54+
NothingClass -> Types.ClassRef(encodeClassFullName(RuntimeNothingClass)),
55+
NullClass -> Types.ClassRef(encodeClassFullName(RuntimeNullClass))
5656
)
5757
}
5858

@@ -67,16 +67,16 @@ trait TypeConversions[G <: Global with Singleton] extends SubComponent {
6767
def toTypeRef(t: Type): Types.TypeRef = {
6868
val (base, arrayDepth) = convert(t)
6969
if (arrayDepth == 0)
70-
Types.ClassRef(makeClassRefName(base))
70+
makeNonArrayTypeRef(base)
7171
else
7272
makeArrayTypeRef(base, arrayDepth)
7373
}
7474

75-
private def makeClassRefName(sym: Symbol): String =
76-
primitiveClassRefNameMap.getOrElse(sym, encodeClassFullName(sym))
75+
private def makeNonArrayTypeRef(sym: Symbol): Types.NonArrayTypeRef =
76+
primitiveRefMap.getOrElse(sym, Types.ClassRef(encodeClassFullName(sym)))
7777

7878
private def makeArrayTypeRef(base: Symbol, depth: Int): Types.ArrayTypeRef =
79-
Types.ArrayTypeRef(makeClassRefName(base), depth)
79+
Types.ArrayTypeRef(makeNonArrayTypeRef(base), depth)
8080

8181
// The following code was modeled after backend.icode.TypeKinds.toTypeKind
8282

ir/src/main/scala/org/scalajs/ir/Definitions.scala

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,14 @@
1212

1313
package org.scalajs.ir
1414

15+
import scala.annotation.switch
16+
1517
import Types._
1618

1719
object Definitions {
1820
/** `java.lang.Object`, the root of the class hierarchy. */
1921
val ObjectClass = "O"
2022

21-
// Primitive "classes"
22-
val VoidClass = "V"
23-
val BooleanClass = "Z"
24-
val CharClass = "C"
25-
val ByteClass = "B"
26-
val ShortClass = "S"
27-
val IntClass = "I"
28-
val LongClass = "J"
29-
val FloatClass = "F"
30-
val DoubleClass = "D"
31-
val NullClass = "N"
32-
val NothingClass = "E" // think "the Empty type", or "throws an Exception"
33-
34-
/** The set of all primitive classes. */
35-
val PrimitiveClasses: Set[String] = Set(
36-
VoidClass,
37-
BooleanClass,
38-
CharClass,
39-
ByteClass,
40-
ShortClass,
41-
IntClass,
42-
LongClass,
43-
FloatClass,
44-
DoubleClass,
45-
NullClass,
46-
NothingClass
47-
)
48-
4923
// Hijacked classes
5024
val BoxedUnitClass = "jl_Void"
5125
val BoxedBooleanClass = "jl_Boolean"
@@ -189,21 +163,55 @@ object Definitions {
189163
*/
190164
def encodeTypeRef(typeRef: TypeRef): String = {
191165
typeRef match {
166+
case PrimRef(tpe) =>
167+
tpe match {
168+
case NoType => "V"
169+
case BooleanType => "Z"
170+
case CharType => "C"
171+
case ByteType => "B"
172+
case ShortType => "S"
173+
case IntType => "I"
174+
case LongType => "J"
175+
case FloatType => "F"
176+
case DoubleType => "D"
177+
case NullType => "N"
178+
case NothingType => "E"
179+
}
192180
case ClassRef(className) =>
193181
className
194-
case ArrayTypeRef(baseClassName, dimensions) =>
195-
"A" * dimensions + baseClassName
182+
case ArrayTypeRef(base, dimensions) =>
183+
"A" * dimensions + encodeTypeRef(base)
196184
}
197185
}
198186

199187
/** Decodes a [[Types.TypeRef]], such as in an encoded method signature.
200188
*/
201189
def decodeTypeRef(encodedName: String): TypeRef = {
202190
val arrayDepth = encodedName.indexWhere(_ != 'A')
191+
val base = {
192+
if (arrayDepth == encodedName.length() - 1) {
193+
(encodedName.charAt(arrayDepth): @switch) match {
194+
case 'V' => VoidRef
195+
case 'Z' => BooleanRef
196+
case 'C' => CharRef
197+
case 'B' => ByteRef
198+
case 'S' => ShortRef
199+
case 'I' => IntRef
200+
case 'J' => LongRef
201+
case 'F' => FloatRef
202+
case 'D' => DoubleRef
203+
case 'N' => NullRef
204+
case 'E' => NothingRef
205+
case _ => ClassRef(encodedName.substring(arrayDepth))
206+
}
207+
} else {
208+
ClassRef(encodedName.substring(arrayDepth))
209+
}
210+
}
203211
if (arrayDepth == 0)
204-
ClassRef(encodedName)
212+
base
205213
else
206-
ArrayTypeRef(encodedName.substring(arrayDepth), arrayDepth)
214+
ArrayTypeRef(base, arrayDepth)
207215
}
208216

209217
/* Common predicates on encoded names */

ir/src/main/scala/org/scalajs/ir/Hashers.scala

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,20 @@ object Hashers {
502502
}
503503

504504
def mixTypeRef(typeRef: TypeRef): Unit = typeRef match {
505+
case PrimRef(tpe) =>
506+
tpe match {
507+
case NoType => mixTag(TagVoidRef)
508+
case BooleanType => mixTag(TagBooleanRef)
509+
case CharType => mixTag(TagCharRef)
510+
case ByteType => mixTag(TagByteRef)
511+
case ShortType => mixTag(TagShortRef)
512+
case IntType => mixTag(TagIntRef)
513+
case LongType => mixTag(TagLongRef)
514+
case FloatType => mixTag(TagFloatRef)
515+
case DoubleType => mixTag(TagDoubleRef)
516+
case NullType => mixTag(TagNullRef)
517+
case NothingType => mixTag(TagNothingRef)
518+
}
505519
case typeRef: ClassRef =>
506520
mixTag(TagClassRef)
507521
mixClassRef(typeRef)
@@ -514,7 +528,7 @@ object Hashers {
514528
mixString(classRef.className)
515529

516530
def mixArrayTypeRef(arrayTypeRef: ArrayTypeRef): Unit = {
517-
mixString(arrayTypeRef.baseClassName)
531+
mixTypeRef(arrayTypeRef.base)
518532
mixInt(arrayTypeRef.dimensions)
519533
}
520534

@@ -538,10 +552,9 @@ object Hashers {
538552
mixTag(TagClassType)
539553
mixString(className)
540554

541-
case ArrayType(ArrayTypeRef(baseClassName, dimensions)) =>
555+
case ArrayType(arrayTypeRef) =>
542556
mixTag(TagArrayType)
543-
mixString(baseClassName)
544-
mixInt(dimensions)
557+
mixArrayTypeRef(arrayTypeRef)
545558

546559
case RecordType(fields) =>
547560
mixTag(TagRecordType)

ir/src/main/scala/org/scalajs/ir/Printers.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ object Printers {
456456

457457
case NewArray(typeRef, lengths) =>
458458
print("new ")
459-
print(typeRef.baseClassName)
459+
print(typeRef.base)
460460
for (length <- lengths) {
461461
print('[')
462462
print(length)
@@ -967,7 +967,9 @@ object Printers {
967967
}
968968
}
969969

970-
def print(tpe: TypeRef): Unit = tpe match {
970+
def print(typeRef: TypeRef): Unit = typeRef match {
971+
case PrimRef(tpe) =>
972+
print(tpe)
971973
case ClassRef(className) =>
972974
print(className)
973975
case ArrayTypeRef(base, dims) =>

ir/src/main/scala/org/scalajs/ir/Serializers.scala

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,20 @@ object Serializers {
673673
}
674674

675675
def writeTypeRef(typeRef: TypeRef): Unit = typeRef match {
676+
case PrimRef(tpe) =>
677+
tpe match {
678+
case NoType => buffer.writeByte(TagVoidRef)
679+
case BooleanType => buffer.writeByte(TagBooleanRef)
680+
case CharType => buffer.writeByte(TagCharRef)
681+
case ByteType => buffer.writeByte(TagByteRef)
682+
case ShortType => buffer.writeByte(TagShortRef)
683+
case IntType => buffer.writeByte(TagIntRef)
684+
case LongType => buffer.writeByte(TagLongRef)
685+
case FloatType => buffer.writeByte(TagFloatRef)
686+
case DoubleType => buffer.writeByte(TagDoubleRef)
687+
case NullType => buffer.writeByte(TagNullRef)
688+
case NothingType => buffer.writeByte(TagNothingRef)
689+
}
676690
case typeRef: ClassRef =>
677691
buffer.writeByte(TagClassRef)
678692
writeClassRef(typeRef)
@@ -685,7 +699,7 @@ object Serializers {
685699
writeString(cls.className)
686700

687701
def writeArrayTypeRef(typeRef: ArrayTypeRef): Unit = {
688-
writeString(typeRef.baseClassName)
702+
writeTypeRef(typeRef.base)
689703
buffer.writeInt(typeRef.dimensions)
690704
}
691705

@@ -1109,18 +1123,27 @@ object Serializers {
11091123

11101124
def readTypeRef(): TypeRef = {
11111125
readByte() match {
1112-
case TagClassRef =>
1113-
readClassRef()
1114-
case TagArrayTypeRef =>
1115-
readArrayTypeRef()
1126+
case TagVoidRef => VoidRef
1127+
case TagBooleanRef => BooleanRef
1128+
case TagCharRef => CharRef
1129+
case TagByteRef => ByteRef
1130+
case TagShortRef => ShortRef
1131+
case TagIntRef => IntRef
1132+
case TagLongRef => LongRef
1133+
case TagFloatRef => FloatRef
1134+
case TagDoubleRef => DoubleRef
1135+
case TagNullRef => NullRef
1136+
case TagNothingRef => NothingRef
1137+
case TagClassRef => readClassRef()
1138+
case TagArrayTypeRef => readArrayTypeRef()
11161139
}
11171140
}
11181141

11191142
def readClassRef(): ClassRef =
11201143
ClassRef(readString())
11211144

11221145
def readArrayTypeRef(): ArrayTypeRef =
1123-
ArrayTypeRef(readString(), readInt())
1146+
ArrayTypeRef(readTypeRef().asInstanceOf[NonArrayTypeRef], readInt())
11241147

11251148
def readApplyFlags(): ApplyFlags =
11261149
ApplyFlags.fromBits(readInt())

ir/src/main/scala/org/scalajs/ir/Tags.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,18 @@ private[ir] object Tags {
137137

138138
// Tags for TypeRefs
139139

140-
final val TagClassRef = 1
140+
final val TagVoidRef = 1
141+
final val TagBooleanRef = TagVoidRef + 1
142+
final val TagCharRef = TagBooleanRef + 1
143+
final val TagByteRef = TagCharRef + 1
144+
final val TagShortRef = TagByteRef + 1
145+
final val TagIntRef = TagShortRef + 1
146+
final val TagLongRef = TagIntRef + 1
147+
final val TagFloatRef = TagLongRef + 1
148+
final val TagDoubleRef = TagFloatRef + 1
149+
final val TagNullRef = TagDoubleRef + 1
150+
final val TagNothingRef = TagNullRef + 1
151+
final val TagClassRef = TagNothingRef + 1
141152
final val TagArrayTypeRef = TagClassRef + 1
142153

143154
// Tags for JS native loading specs

0 commit comments

Comments
 (0)