diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2014-08-12 16:12:15 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2014-08-19 17:50:02 +0200 |
commit | f73f026bf250e6eb3c22c2b1975d4fdc2f23eab6 (patch) | |
tree | b1d49a853c90740c6e4b15b0c8365c72b702970d /src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala | |
parent | bdc3ff97e7f869b393de7e4deb53535a93738ad1 (diff) | |
download | scala-f73f026bf250e6eb3c22c2b1975d4fdc2f23eab6.tar.gz scala-f73f026bf250e6eb3c22c2b1975d4fdc2f23eab6.tar.bz2 scala-f73f026bf250e6eb3c22c2b1975d4fdc2f23eab6.zip |
Remove Tracked, add type information to ClassBType
Before this change, a ClassBType was just a name. The `exemplars` map
stored a Tracked instance for every ClassBType. Tracked stored
type information that is required later in the backend when things
may run concurrently. In particular: superclass, interfaces, flags
and information for emitting the InnerClass attribute. Now we put all
the information stored in Tracked directly in the ClassBType.
There is still one hash map: `classBTypeFromInternalNameMap` maps
a JVM internal class name (e.g. "scala/Predef$") to the corresponding
ClassBType. This map is used during bytecode generation, when the
ASM framework computes stack map frames.
In order to compute stack map frames, the ASM framework needs to be
able to get the LUB of two types. The default implementation uses
reflection to get type information, however that doesn't work in our
case: the classes we compile are not on the classpath. So instead,
the backend overwrites the method `getCommonSuperClass` of the
ClassWriter. This method receives two class internal names and
computes their LUB. This is done by looking up the ClassBTypes in the
`classBTypeFromInternalNameMap` and invoking `jvmWiseLUB`.
This commit was reviwed in https://github.com/scala/scala/pull/3855.
It consists of all commits labelled [squash-after-review], squashed
into one.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 2d1030121e..542ff48c33 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -92,7 +92,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { val thrownKind = tpeTK(expr) // `throw null` is valid although scala.Null (as defined in src/libray-aux) isn't a subtype of Throwable. // Similarly for scala.Nothing (again, as defined in src/libray-aux). - assert(thrownKind.isNullType || thrownKind.isNothingType || exemplars.get(thrownKind).isSubtypeOf(ThrowableReference)) + assert(thrownKind.isNullType || thrownKind.isNothingType || thrownKind.asClassBType.isSubtypeOf(ThrowableReference)) genLoad(expr, thrownKind) lineNumber(expr) emit(asm.Opcodes.ATHROW) // ICode enters here into enterIgnoreMode, we'll rely instead on DCE at ClassNode level. @@ -123,7 +123,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { // binary operation case rarg :: Nil => - resKind = maxType(tpeTK(larg), tpeTK(rarg)) + resKind = tpeTK(larg).maxType(tpeTK(rarg)) if (scalaPrimitives.isShiftOp(code) || scalaPrimitives.isBitwiseOp(code)) { assert(resKind.isIntegralType || (resKind == BOOL), s"$resKind incompatible with arithmetic modulo operation.") @@ -321,7 +321,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) generatedType = if (tree.symbol == ArrayClass) ObjectReference - else ClassBType(thisName) // inner class (if any) for claszSymbol already tracked. + else classBTypeFromSymbol(claszSymbol) } case Select(Ident(nme.EMPTY_PACKAGE_NAME), module) => @@ -459,9 +459,10 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { case ClazzTag => val toPush: BType = { - val kind = toTypeKind(const.typeValue) - if (kind.isPrimitive) classLiteral(kind) - else kind + toTypeKind(const.typeValue) match { + case kind: PrimitiveBType => boxedClassOfPrimitive(kind) + case kind => kind + } } mnode.visitLdcInsn(toPush.toASMType) @@ -558,7 +559,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { abort(s"Erasure should have added an unboxing operation to prevent this cast. Tree: $app") } else if (r.isPrimitive) { - bc isInstance classLiteral(r) + bc isInstance boxedClassOfPrimitive(r.asPrimitiveBType) } else { assert(r.isRef, r) // ensure that it's not a method @@ -619,7 +620,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { } case rt: ClassBType => - assert(exemplar(ctor.owner).c == rt, s"Symbol ${ctor.owner.fullName} is different from $rt") + assert(classBTypeFromSymbol(ctor.owner) == rt, s"Symbol ${ctor.owner.fullName} is different from $rt") mnode.visitTypeInsn(asm.Opcodes.NEW, rt.internalName) bc dup generatedType genLoadArguments(args, paramTKs(app)) @@ -632,16 +633,16 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isBox(fun.symbol) => val nativeKind = tpeTK(expr) genLoad(expr, nativeKind) - val MethodNameAndType(mname, mdesc) = asmBoxTo(nativeKind) - bc.invokestatic(BoxesRunTime.internalName, mname, mdesc) + val MethodNameAndType(mname, methodType) = asmBoxTo(nativeKind) + bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor) generatedType = boxResultType(fun.symbol) // was toTypeKind(fun.symbol.tpe.resultType) case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isUnbox(fun.symbol) => genLoad(expr) val boxType = unboxResultType(fun.symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) generatedType = boxType - val MethodNameAndType(mname, mdesc) = asmUnboxTo(boxType) - bc.invokestatic(BoxesRunTime.internalName, mname, mdesc) + val MethodNameAndType(mname, methodType) = asmUnboxTo(boxType) + bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor) case app @ Apply(fun, args) => val sym = fun.symbol @@ -807,7 +808,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { } def adapt(from: BType, to: BType) { - if (!conforms(from, to)) { + if (!from.conformsTo(to)) { to match { case UNIT => bc drop from case _ => bc.emitT2T(from, to) @@ -948,7 +949,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { def genCallMethod(method: Symbol, style: InvokeStyle, hostClass0: Symbol = null, pos: Position = NoPosition) { val siteSymbol = claszSymbol - val hostSymbol = if (hostClass0 == null) method.owner else hostClass0; + val hostSymbol = if (hostClass0 == null) method.owner else hostClass0; val methodOwner = method.owner // info calls so that types are up to date; erasure may add lateINTERFACE to traits hostSymbol.info ; methodOwner.info @@ -966,8 +967,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { || methodOwner == definitions.ObjectClass ) val receiver = if (useMethodOwner) methodOwner else hostSymbol - val bmOwner = asmClassType(receiver) - val jowner = bmOwner.internalName + val jowner = internalName(receiver) val jname = method.javaSimpleName.toString val bmType = asmMethodType(method) val mdescr = bmType.descriptor @@ -1100,7 +1100,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { genCZJUMP(success, failure, op, ObjectReference) } else { - val tk = maxType(tpeTK(l), tpeTK(r)) + val tk = tpeTK(l).maxType(tpeTK(r)) genLoad(l, tk) genLoad(r, tk) genCJUMP(success, failure, op, tk) @@ -1206,7 +1206,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { genCZJUMP(success, failure, icodes.NE, BOOL) } else { // l == r -> if (l eq null) r eq null else l.equals(r) - val eqEqTempLocal = locals.makeLocal(AnyRefReference, nme.EQEQ_LOCAL_VAR.toString) + val eqEqTempLocal = locals.makeLocal(ObjectReference, nme.EQEQ_LOCAL_VAR.toString) val lNull = new asm.Label val lNonNull = new asm.Label |