summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
blob: acb950929f1cc0cc974825a23c6635e3d1f84b67 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
package scala.tools.nsc
package backend.jvm

import scala.tools.asm
import scala.tools.nsc.backend.jvm.BTypes.InternalName

/**
 * Core BTypes and some other definitions. The initialization of these definitions requires access
 * to symbols / types (global).
 *
 * The symbols used to initialize the ClassBTypes may change from one compiler run to the next. To
 * make sure the definitions are consistent with the symbols in the current run, the
 * `initializeCoreBTypes` method in BTypesFromSymbols creates a new instance of CoreBTypes in each
 * compiler run.
 *
 * The class BTypesFromSymbols does not directly reference CoreBTypes, but CoreBTypesProxy. The
 * reason is that having a `var bTypes: CoreBTypes` would not allow `import bTypes._`. Instead, the
 * proxy class holds a `CoreBTypes` in a variable field and forwards to this instance.
 *
 * The definitions in `CoreBTypes` need to be lazy vals to break an initialization cycle. When
 * creating a new instance to assign to the proxy, the `classBTypeFromSymbol` invoked in the
 * constructor will actually go through the proxy. The lazy vals make sure the instance is assigned
 * in the proxy before the fields are initialized.
 *
 * Note: if we did not re-create the core BTypes on each compiler run, BType.classBTypeFromInternalNameMap
 * could not be a perRunCache anymore: the classes defined here need to be in that map, they are
 * added when the ClassBTypes are created. The per run cache removes them, so they would be missing
 * in the second run.
 */
class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) {
  import bTypes._
  import global._
  import rootMirror.{requiredClass, getRequiredClass, getClassIfDefined}
  import definitions._

  /**
   * Maps primitive types to their corresponding PrimitiveBType. The map is defined lexically above
   * the first use of `classBTypeFromSymbol` because that method looks at the map.
   */
  lazy val primitiveTypeToBType: Map[Symbol, PrimitiveBType] = Map(
    UnitClass    -> UNIT,
    BooleanClass -> BOOL,
    CharClass    -> CHAR,
    ByteClass    -> BYTE,
    ShortClass   -> SHORT,
    IntClass     -> INT,
    LongClass    -> LONG,
    FloatClass   -> FLOAT,
    DoubleClass  -> DOUBLE)

  /**
   * Map from primitive types to their boxed class type. Useful when pushing class literals onto the
   * operand stack (ldc instruction taking a class literal), see genConstant.
   */
  lazy val boxedClassOfPrimitive: Map[PrimitiveBType, ClassBType] = Map(
    UNIT   -> classBTypeFromSymbol(requiredClass[java.lang.Void]),
    BOOL   -> classBTypeFromSymbol(BoxedBooleanClass),
    BYTE   -> classBTypeFromSymbol(BoxedByteClass),
    SHORT  -> classBTypeFromSymbol(BoxedShortClass),
    CHAR   -> classBTypeFromSymbol(BoxedCharacterClass),
    INT    -> classBTypeFromSymbol(BoxedIntClass),
    LONG   -> classBTypeFromSymbol(BoxedLongClass),
    FLOAT  -> classBTypeFromSymbol(BoxedFloatClass),
    DOUBLE -> classBTypeFromSymbol(BoxedDoubleClass))

  lazy val boxedClasses: Set[ClassBType] = boxedClassOfPrimitive.values.toSet

  /**
   * Maps the method symbol for a box method to the boxed type of the result. For example, the
   * method symbol for `Byte.box()` is mapped to the ClassBType `java/lang/Byte`.
   */
  lazy val boxResultType: Map[Symbol, ClassBType] = {
    for ((valueClassSym, boxMethodSym) <- currentRun.runDefinitions.boxMethod)
    yield boxMethodSym -> boxedClassOfPrimitive(primitiveTypeToBType(valueClassSym))
  }

  /**
   * Maps the method symbol for an unbox method to the primitive type of the result.
   * For example, the method symbol for `Byte.unbox()`) is mapped to the PrimitiveBType BYTE. */
  lazy val unboxResultType: Map[Symbol, PrimitiveBType] = {
    for ((valueClassSym, unboxMethodSym) <- currentRun.runDefinitions.unboxMethod)
    yield unboxMethodSym -> primitiveTypeToBType(valueClassSym)
  }

  /*
   * RT_NOTHING and RT_NULL exist at run-time only. They are the bytecode-level manifestation (in
   * method signatures only) of what shows up as NothingClass (scala.Nothing) resp. NullClass
   * (scala.Null) in Scala ASTs.
   *
   * Therefore, when RT_NOTHING or RT_NULL are to be emitted, a mapping is needed: the internal
   * names of NothingClass and NullClass can't be emitted as-is.
   */
  lazy val srNothingRef : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.Nothing$])
  lazy val srNullRef    : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.Null$])

  lazy val ObjectRef                 : ClassBType = classBTypeFromSymbol(ObjectClass)
  lazy val StringRef                 : ClassBType = classBTypeFromSymbol(StringClass)
  lazy val PredefRef                 : ClassBType = classBTypeFromSymbol(PredefModule.moduleClass)
  lazy val jlStringBuilderRef        : ClassBType = classBTypeFromSymbol(JavaStringBuilderClass)
  lazy val jlStringBufferRef         : ClassBType = classBTypeFromSymbol(JavaStringBufferClass)
  lazy val jlCharSequenceRef         : ClassBType = classBTypeFromSymbol(JavaCharSequenceClass)
  lazy val jlThrowableRef            : ClassBType = classBTypeFromSymbol(ThrowableClass)
  lazy val jlCloneableRef            : ClassBType = classBTypeFromSymbol(JavaCloneableClass)        // java/lang/Cloneable
  lazy val jiSerializableRef         : ClassBType = classBTypeFromSymbol(JavaSerializableClass)     // java/io/Serializable
  lazy val jlClassCastExceptionRef   : ClassBType = classBTypeFromSymbol(ClassCastExceptionClass)   // java/lang/ClassCastException
  lazy val juMapRef                  : ClassBType = classBTypeFromSymbol(JavaUtilMap)               // java/util/Map
  lazy val juHashMapRef              : ClassBType = classBTypeFromSymbol(JavaUtilHashMap)           // java/util/HashMap
  lazy val sbScalaBeanInfoRef        : ClassBType = classBTypeFromSymbol(requiredClass[scala.beans.ScalaBeanInfo])
  lazy val jliSerializedLambdaRef    : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.invoke.SerializedLambda])
  lazy val jliMethodHandleRef        : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.invoke.MethodHandle])
  lazy val jliMethodHandlesRef       : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.invoke.MethodHandles])
  lazy val jliMethodHandlesLookupRef : ClassBType = classBTypeFromSymbol(exitingPickler(getRequiredClass("java.lang.invoke.MethodHandles.Lookup"))) // didn't find a reliable non-stringly-typed way that works for inner classes in the backend
  lazy val jliMethodTypeRef          : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.invoke.MethodType])
  lazy val jliCallSiteRef            : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.invoke.CallSite])
  lazy val jliLambdaMetafactoryRef   : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.invoke.LambdaMetafactory])
  lazy val srBoxesRunTimeRef         : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.BoxesRunTime])
  lazy val srSymbolLiteral           : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.SymbolLiteral])
  lazy val srStructuralCallSite      : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.StructuralCallSite])
  lazy val srLambdaDeserialize       : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.LambdaDeserialize])
  lazy val srBoxedUnitRef            : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.BoxedUnit])

  private def methodNameAndType(cls: Symbol, name: Name, static: Boolean = false, filterOverload: Symbol => Boolean = _ => true): MethodNameAndType = {
    val holder = if (static) cls.companionModule.moduleClass else cls
    val method = holder.info.member(name).suchThat(filterOverload)
    assert(!method.isOverloaded, method)
    MethodNameAndType(name.toString, methodBTypeFromSymbol(method))
  }

  private def srBoxesRuntimeMethods(getName: (String, String) => String): Map[BType, MethodNameAndType] = {
    ScalaValueClassesNoUnit.map(primitive => {
      val bType = primitiveTypeToBType(primitive)
      val name = newTermName(getName(primitive.name.toString, boxedClass(primitive).name.toString))
      (bType, methodNameAndType(BoxesRunTimeClass, name))
    })(collection.breakOut)
  }

  // Z -> MethodNameAndType(boxToBoolean,(Z)Ljava/lang/Boolean;)
  lazy val srBoxesRuntimeBoxToMethods: Map[BType, MethodNameAndType] = srBoxesRuntimeMethods((primitive, boxed) => "boxTo" + boxed)

  // Z -> MethodNameAndType(unboxToBoolean,(Ljava/lang/Object;)Z)
  lazy val srBoxesRuntimeUnboxToMethods: Map[BType, MethodNameAndType] = srBoxesRuntimeMethods((primitive, boxed) => "unboxTo" + primitive)

  def singleParamOfClass(cls: Symbol) = (s: Symbol) => s.paramss match {
    case List(List(param)) => param.info.typeSymbol == cls
    case _ => false
  }

  // java/lang/Boolean -> MethodNameAndType(valueOf,(Z)Ljava/lang/Boolean;)
  lazy val javaBoxMethods: Map[InternalName, MethodNameAndType] = {
    ScalaValueClassesNoUnit.map(primitive => {
      val boxed = boxedClass(primitive)
      val method = methodNameAndType(boxed, newTermName("valueOf"), static = true, filterOverload = singleParamOfClass(primitive))
      (classBTypeFromSymbol(boxed).internalName, method)
    })(collection.breakOut)
  }

  // java/lang/Boolean -> MethodNameAndType(booleanValue,()Z)
  lazy val javaUnboxMethods: Map[InternalName, MethodNameAndType] = {
    ScalaValueClassesNoUnit.map(primitive => {
      val boxed = boxedClass(primitive)
      val name = primitive.name.toString.toLowerCase + "Value"
      (classBTypeFromSymbol(boxed).internalName, methodNameAndType(boxed, newTermName(name)))
    })(collection.breakOut)
  }

  private def predefBoxingMethods(getName: (String, String) => String): Map[String, MethodBType] = {
    ScalaValueClassesNoUnit.map(primitive => {
      val boxed = boxedClass(primitive)
      val name = getName(primitive.name.toString, boxed.name.toString)
      (name, methodNameAndType(PredefModule.moduleClass, newTermName(name)).methodType)
    })(collection.breakOut)
  }

  // boolean2Boolean -> (Z)Ljava/lang/Boolean;
  lazy val predefAutoBoxMethods: Map[String, MethodBType] = predefBoxingMethods((primitive, boxed) => primitive.toLowerCase + "2" + boxed)

  // Boolean2boolean -> (Ljava/lang/Boolean;)Z
  lazy val predefAutoUnboxMethods: Map[String, MethodBType] = predefBoxingMethods((primitive, boxed) => boxed + "2" + primitive.toLowerCase)

  private def staticRefMethods(name: Name): Map[InternalName, MethodNameAndType] = {
    allRefClasses.map(refClass =>
      (classBTypeFromSymbol(refClass).internalName, methodNameAndType(refClass, name, static = true)))(collection.breakOut)
  }

  // scala/runtime/BooleanRef -> MethodNameAndType(create,(Z)Lscala/runtime/BooleanRef;)
  lazy val srRefCreateMethods: Map[InternalName, MethodNameAndType] = staticRefMethods(nme.create)

  // scala/runtime/BooleanRef -> MethodNameAndType(zero,()Lscala/runtime/BooleanRef;)
  lazy val srRefZeroMethods: Map[InternalName, MethodNameAndType] = staticRefMethods(nme.zero)

  // java/lang/Boolean -> MethodNameAndType(<init>,(Z)V)
  lazy val primitiveBoxConstructors: Map[InternalName, MethodNameAndType] = {
    ScalaValueClassesNoUnit.map(primitive => {
      val boxed = boxedClass(primitive)
      (classBTypeFromSymbol(boxed).internalName, methodNameAndType(boxed, nme.CONSTRUCTOR, filterOverload = singleParamOfClass(primitive)))
    })(collection.breakOut)
  }

  private def nonOverloadedConstructors(classes: Iterable[Symbol]): Map[InternalName, MethodNameAndType] = {
    classes.map(cls => (classBTypeFromSymbol(cls).internalName, methodNameAndType(cls, nme.CONSTRUCTOR)))(collection.breakOut)
  }

  // scala/runtime/BooleanRef -> MethodNameAndType(<init>,(Z)V)
  lazy val srRefConstructors: Map[InternalName, MethodNameAndType] = nonOverloadedConstructors(allRefClasses)

  private def specializedSubclasses(cls: Symbol): List[Symbol] = {
    exitingSpecialize(cls.info) // the `transformInfo` method of specialization adds specialized subclasses to the `specializedClass` map
    specializeTypes.specializedClass.collect({
      case ((`cls`, _), specCls) => specCls
    }).toList
  }

  // scala/Tuple3 -> MethodNameAndType(<init>,(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V)
  // scala/Tuple2$mcZC$sp -> MethodNameAndType(<init>,(ZC)V)
  lazy val tupleClassConstructors: Map[InternalName, MethodNameAndType] = {
    val tupleClassSymbols = TupleClass.seq ++ specializedSubclasses(TupleClass(1)) ++ specializedSubclasses(TupleClass(2))
    nonOverloadedConstructors(tupleClassSymbols)
  }

  lazy val typeOfArrayOp: Map[Int, BType] = {
    import scalaPrimitives._
    Map(
      (List(ZARRAY_LENGTH, ZARRAY_GET, ZARRAY_SET) map (_ -> BOOL))   ++
        (List(BARRAY_LENGTH, BARRAY_GET, BARRAY_SET) map (_ -> BYTE))   ++
        (List(SARRAY_LENGTH, SARRAY_GET, SARRAY_SET) map (_ -> SHORT))  ++
        (List(CARRAY_LENGTH, CARRAY_GET, CARRAY_SET) map (_ -> CHAR))   ++
        (List(IARRAY_LENGTH, IARRAY_GET, IARRAY_SET) map (_ -> INT))    ++
        (List(LARRAY_LENGTH, LARRAY_GET, LARRAY_SET) map (_ -> LONG))   ++
        (List(FARRAY_LENGTH, FARRAY_GET, FARRAY_SET) map (_ -> FLOAT))  ++
        (List(DARRAY_LENGTH, DARRAY_GET, DARRAY_SET) map (_ -> DOUBLE)) ++
        (List(OARRAY_LENGTH, OARRAY_GET, OARRAY_SET) map (_ -> ObjectRef)) : _*
    )
  }

  lazy val hashMethodSym: Symbol = getMember(RuntimeStaticsModule, nme.anyHash)

  // TODO @lry avoiding going through through missingHook for every line in the REPL: https://github.com/scala/scala/commit/8d962ed4ddd310cc784121c426a2e3f56a112540
  lazy val AndroidParcelableInterface : Symbol = getClassIfDefined("android.os.Parcelable")
  lazy val AndroidCreatorClass        : Symbol = getClassIfDefined("android.os.Parcelable$Creator")

  lazy val BeanInfoAttr: Symbol = requiredClass[scala.beans.BeanInfo]

  /* The Object => String overload. */
  lazy val String_valueOf: Symbol = {
    getMember(StringModule, nme.valueOf) filter (sym => sym.info.paramTypes match {
      case List(pt) => pt.typeSymbol == ObjectClass
      case _        => false
    })
  }

  lazy val lambdaMetaFactoryMetafactoryHandle =
    new asm.Handle(asm.Opcodes.H_INVOKESTATIC,
      coreBTypes.jliLambdaMetafactoryRef.internalName, sn.Metafactory.toString,
      MethodBType(
        List(
          coreBTypes.jliMethodHandlesLookupRef,
          coreBTypes.StringRef,
          coreBTypes.jliMethodTypeRef,
          coreBTypes.jliMethodTypeRef,
          coreBTypes.jliMethodHandleRef,
          coreBTypes.jliMethodTypeRef),
        coreBTypes.jliCallSiteRef
      ).descriptor,
      /* itf = */ coreBTypes.jliLambdaMetafactoryRef.isInterface.get)

  lazy val lambdaMetaFactoryAltMetafactoryHandle =
    new asm.Handle(asm.Opcodes.H_INVOKESTATIC,
      coreBTypes.jliLambdaMetafactoryRef.internalName, sn.AltMetafactory.toString,
      MethodBType(
        List(
          coreBTypes.jliMethodHandlesLookupRef,
          coreBTypes.StringRef,
          coreBTypes.jliMethodTypeRef,
          ArrayBType(ObjectRef)),
        coreBTypes.jliCallSiteRef
      ).descriptor,
      /* itf = */ coreBTypes.jliLambdaMetafactoryRef.isInterface.get)

  lazy val lambdaDeserializeBootstrapHandle =
    new scala.tools.asm.Handle(scala.tools.asm.Opcodes.H_INVOKESTATIC,
      coreBTypes.srLambdaDeserialize.internalName, sn.Bootstrap.toString,
      MethodBType(
        List(
          coreBTypes.jliMethodHandlesLookupRef,
          coreBTypes.StringRef,
          coreBTypes.jliMethodTypeRef,
          ArrayBType(jliMethodHandleRef)
        ),
        coreBTypes.jliCallSiteRef
      ).descriptor,
      /* itf = */ coreBTypes.srLambdaDeserialize.isInterface.get)
}

/**
 * This trait make some core BTypes available that don't depend on a Global instance. Some core
 * BTypes are required to be accessible in the BTypes trait, which does not have access to Global.
 *
 * BTypes cannot refer to CoreBTypesProxy because some of its members depend on global, for example
 * the type Symbol in
 *   def primitiveTypeMap: Map[Symbol, PrimitiveBType]
 */
trait CoreBTypesProxyGlobalIndependent[BTS <: BTypes] {
  val bTypes: BTS
  import bTypes._

  def boxedClasses: Set[ClassBType]
  def boxedClassOfPrimitive: Map[PrimitiveBType, ClassBType]

  def srNothingRef              : ClassBType
  def srNullRef                 : ClassBType

  def ObjectRef                 : ClassBType
  def StringRef                 : ClassBType
  def PredefRef                 : ClassBType
  def jlCloneableRef            : ClassBType
  def jiSerializableRef         : ClassBType
  def juHashMapRef              : ClassBType
  def juMapRef                  : ClassBType
  def jliCallSiteRef            : ClassBType
  def jliLambdaMetafactoryRef   : ClassBType
  def jliMethodTypeRef          : ClassBType
  def jliSerializedLambdaRef    : ClassBType
  def jliMethodHandleRef        : ClassBType
  def jliMethodHandlesLookupRef : ClassBType
  def srBoxesRunTimeRef         : ClassBType
  def srBoxedUnitRef            : ClassBType

  def srBoxesRuntimeBoxToMethods   : Map[BType, MethodNameAndType]
  def srBoxesRuntimeUnboxToMethods : Map[BType, MethodNameAndType]

  def javaBoxMethods   : Map[InternalName, MethodNameAndType]
  def javaUnboxMethods : Map[InternalName, MethodNameAndType]

  def predefAutoBoxMethods   : Map[String, MethodBType]
  def predefAutoUnboxMethods : Map[String, MethodBType]

  def srRefCreateMethods : Map[InternalName, MethodNameAndType]
  def srRefZeroMethods   : Map[InternalName, MethodNameAndType]

  def primitiveBoxConstructors : Map[InternalName, MethodNameAndType]
  def srRefConstructors        : Map[InternalName, MethodNameAndType]
  def tupleClassConstructors   : Map[InternalName, MethodNameAndType]

  def lambdaMetaFactoryMetafactoryHandle    : asm.Handle
  def lambdaMetaFactoryAltMetafactoryHandle : asm.Handle
  def lambdaDeserializeBootstrapHandle      : asm.Handle
}

/**
 * See comment in class [[CoreBTypes]].
 */
final class CoreBTypesProxy[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) extends CoreBTypesProxyGlobalIndependent[BTFS] {
  import bTypes._
  import global._

  private[this] var _coreBTypes: CoreBTypes[bTypes.type] = _
  def setBTypes(coreBTypes: CoreBTypes[BTFS]): Unit = {
    _coreBTypes = coreBTypes.asInstanceOf[CoreBTypes[bTypes.type]]
  }

  def primitiveTypeToBType: Map[Symbol, PrimitiveBType] = _coreBTypes.primitiveTypeToBType

  def boxedClasses: Set[ClassBType] = _coreBTypes.boxedClasses
  def boxedClassOfPrimitive: Map[PrimitiveBType, ClassBType] = _coreBTypes.boxedClassOfPrimitive

  def boxResultType: Map[Symbol, ClassBType] = _coreBTypes.boxResultType
  def unboxResultType: Map[Symbol, PrimitiveBType] = _coreBTypes.unboxResultType

  def srNothingRef              : ClassBType = _coreBTypes.srNothingRef
  def srNullRef                 : ClassBType = _coreBTypes.srNullRef

  def ObjectRef                 : ClassBType = _coreBTypes.ObjectRef
  def StringRef                 : ClassBType = _coreBTypes.StringRef
  def PredefRef                 : ClassBType = _coreBTypes.PredefRef
  def jlStringBuilderRef        : ClassBType = _coreBTypes.jlStringBuilderRef
  def jlStringBufferRef         : ClassBType = _coreBTypes.jlStringBufferRef
  def jlCharSequenceRef         : ClassBType = _coreBTypes.jlCharSequenceRef
  def jlThrowableRef            : ClassBType = _coreBTypes.jlThrowableRef
  def jlCloneableRef            : ClassBType = _coreBTypes.jlCloneableRef
  def jiSerializableRef         : ClassBType = _coreBTypes.jiSerializableRef
  def jlClassCastExceptionRef   : ClassBType = _coreBTypes.jlClassCastExceptionRef
  def juMapRef                  : ClassBType = _coreBTypes.juMapRef
  def juHashMapRef              : ClassBType = _coreBTypes.juHashMapRef
  def sbScalaBeanInfoRef        : ClassBType = _coreBTypes.sbScalaBeanInfoRef
  def jliSerializedLambdaRef    : ClassBType = _coreBTypes.jliSerializedLambdaRef
  def jliMethodHandleRef        : ClassBType = _coreBTypes.jliMethodHandleRef
  def jliMethodHandlesRef       : ClassBType = _coreBTypes.jliMethodHandlesRef
  def jliMethodHandlesLookupRef : ClassBType = _coreBTypes.jliMethodHandlesLookupRef
  def jliMethodTypeRef          : ClassBType = _coreBTypes.jliMethodTypeRef
  def jliCallSiteRef            : ClassBType = _coreBTypes.jliCallSiteRef
  def jliLambdaMetafactoryRef   : ClassBType = _coreBTypes.jliLambdaMetafactoryRef
  def srBoxesRunTimeRef         : ClassBType = _coreBTypes.srBoxesRunTimeRef
  def srBoxedUnitRef            : ClassBType = _coreBTypes.srBoxedUnitRef

  def srBoxesRuntimeBoxToMethods   : Map[BType, MethodNameAndType] = _coreBTypes.srBoxesRuntimeBoxToMethods
  def srBoxesRuntimeUnboxToMethods : Map[BType, MethodNameAndType] = _coreBTypes.srBoxesRuntimeUnboxToMethods

  def javaBoxMethods   : Map[InternalName, MethodNameAndType] = _coreBTypes.javaBoxMethods
  def javaUnboxMethods : Map[InternalName, MethodNameAndType] = _coreBTypes.javaUnboxMethods

  def predefAutoBoxMethods   : Map[String, MethodBType] = _coreBTypes.predefAutoBoxMethods
  def predefAutoUnboxMethods : Map[String, MethodBType] = _coreBTypes.predefAutoUnboxMethods

  def srRefCreateMethods : Map[InternalName, MethodNameAndType] = _coreBTypes.srRefCreateMethods
  def srRefZeroMethods   : Map[InternalName, MethodNameAndType] = _coreBTypes.srRefZeroMethods

  def primitiveBoxConstructors : Map[InternalName, MethodNameAndType] = _coreBTypes.primitiveBoxConstructors
  def srRefConstructors        : Map[InternalName, MethodNameAndType] = _coreBTypes.srRefConstructors
  def tupleClassConstructors   : Map[InternalName, MethodNameAndType] = _coreBTypes.tupleClassConstructors

  def srSymbolLiteral           : ClassBType = _coreBTypes.srSymbolLiteral
  def srStructuralCallSite      : ClassBType = _coreBTypes.srStructuralCallSite
  def srLambdaDeserialize       : ClassBType = _coreBTypes.srLambdaDeserialize

  def typeOfArrayOp: Map[Int, BType] = _coreBTypes.typeOfArrayOp

  // Some symbols. These references should probably be moved to Definitions.

  def hashMethodSym: Symbol = _coreBTypes.hashMethodSym

  def AndroidParcelableInterface : Symbol = _coreBTypes.AndroidParcelableInterface
  def AndroidCreatorClass        : Symbol = _coreBTypes.AndroidCreatorClass

  def BeanInfoAttr: Symbol = _coreBTypes.BeanInfoAttr

  def String_valueOf: Symbol = _coreBTypes.String_valueOf

  def lambdaMetaFactoryMetafactoryHandle    : asm.Handle = _coreBTypes.lambdaMetaFactoryMetafactoryHandle
  def lambdaMetaFactoryAltMetafactoryHandle : asm.Handle = _coreBTypes.lambdaMetaFactoryAltMetafactoryHandle
  def lambdaDeserializeBootstrapHandle      : asm.Handle = _coreBTypes.lambdaDeserializeBootstrapHandle
}