Skip to content

Commit 1a8daa2

Browse files
committed
Remove GenASM, merge remaining common code snippets
With GenBCode being the default and only supported backend for Java 8, we can get rid of GenASM. This commit also fixes/migrates/moves to pending/deletes tests which depended on GenASM before.
1 parent 4321ea4 commit 1a8daa2

File tree

98 files changed

+861
-4119
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+861
-4119
lines changed

src/compiler/scala/tools/nsc/Global.scala

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import transform._
2828
import backend.icode.{ ICodes, GenICode, ICodeCheckers }
2929
import backend.{ ScalaPrimitives, JavaPlatform }
3030
import backend.jvm.GenBCode
31-
import backend.jvm.GenASM
3231
import backend.opt.{ Inliners, InlineExceptionHandlers, ConstantOptimization, ClosureElimination, DeadCodeElimination }
3332
import backend.icode.analysis._
3433
import scala.language.postfixOps
@@ -633,13 +632,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
633632
val runsRightAfter = None
634633
} with DeadCodeElimination
635634

636-
// phaseName = "jvm", ASM-based version
637-
object genASM extends {
638-
val global: Global.this.type = Global.this
639-
val runsAfter = List("dce")
640-
val runsRightAfter = None
641-
} with GenASM
642-
643635
// phaseName = "bcode"
644636
object genBCode extends {
645637
val global: Global.this.type = Global.this

src/compiler/scala/tools/nsc/backend/JavaPlatform.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,9 @@ trait JavaPlatform extends Platform {
4040
def updateClassPath(subst: Map[ClassPath[AbstractFile], ClassPath[AbstractFile]]) =
4141
currentClassPath = Some(new DeltaClassPath(currentClassPath.get, subst))
4242

43-
private def classEmitPhase =
44-
if (settings.isBCodeActive) genBCode
45-
else genASM
46-
4743
def platformPhases = List(
48-
flatten, // get rid of inner classes
49-
classEmitPhase // generate .class files
44+
flatten, // get rid of inner classes
45+
genBCode // generate .class files
5046
)
5147

5248
lazy val externalEquals = getDecl(BoxesRunTimeClass, nme.equals_)

src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala

Lines changed: 0 additions & 476 deletions
This file was deleted.

src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala

Lines changed: 494 additions & 7 deletions
Large diffs are not rendered by default.

src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
2525
import global._
2626
import bTypes._
2727
import coreBTypes._
28-
import bCodeAsmCommon._
2928

3029
/*
3130
* There's a dedicated PlainClassBuilder for each CompilationUnit,

src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ abstract class BTypes {
126126
/**
127127
* Obtain the BType for a type descriptor or internal name. For class descriptors, the ClassBType
128128
* is constructed by parsing the corresponding classfile.
129-
*
129+
*
130130
* Some JVM operations use either a full descriptor or only an internal name. Example:
131131
* ANEWARRAY java/lang/String // a new array of strings (internal name for the String class)
132132
* ANEWARRAY [Ljava/lang/String; // a new array of array of string (full descriptor for the String class)
@@ -932,7 +932,7 @@ abstract class BTypes {
932932
// the static flag in the InnerClass table has a special meaning, see InnerClass comment
933933
i.flags & ~Opcodes.ACC_STATIC,
934934
if (isStaticNestedClass) Opcodes.ACC_STATIC else 0
935-
) & BCodeAsmCommon.INNER_CLASSES_FLAGS
935+
) & BCodeHelpers.INNER_CLASSES_FLAGS
936936
)
937937
})
938938

@@ -1192,4 +1192,4 @@ object BTypes {
11921192
// no static way (without symbol table instance) to get to nme.ScalaATTR / ScalaSignatureATTR
11931193
val ScalaAttributeName = "Scala"
11941194
val ScalaSigAttributeName = "ScalaSig"
1195-
}
1195+
}

src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ import scala.tools.nsc.settings.ScalaSettings
2828
class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
2929
import global._
3030
import definitions._
31+
import genBCode._
3132

3233
val bCodeICodeCommon: BCodeICodeCommon[global.type] = new BCodeICodeCommon(global)
33-
val bCodeAsmCommon: BCodeAsmCommon[global.type] = new BCodeAsmCommon(global)
34-
import bCodeAsmCommon._
3534

3635
val backendUtils: BackendUtils[this.type] = new BackendUtils(this)
3736

@@ -220,7 +219,101 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
220219
assert(!primitiveTypeMap.contains(sym) || isCompilingPrimitive, sym)
221220
}
222221

222+
def implementedInterfaces(classSym: Symbol): List[Symbol] = {
223+
// Additional interface parents based on annotations and other cues
224+
def newParentForAnnotation(ann: AnnotationInfo): Option[Type] = ann.symbol match {
225+
case RemoteAttr => Some(RemoteInterfaceClass.tpe)
226+
case _ => None
227+
}
228+
229+
// SI-9393: java annotations are interfaces, but the classfile / java source parsers make them look like classes.
230+
def isInterfaceOrTrait(sym: Symbol) = sym.isInterface || sym.isTrait || sym.hasJavaAnnotationFlag
231+
232+
val classParents = {
233+
val parents = classSym.info.parents
234+
// SI-9393: the classfile / java source parsers add Annotation and ClassfileAnnotation to the
235+
// parents of a java annotations. undo this for the backend (where we need classfile-level information).
236+
if (classSym.hasJavaAnnotationFlag) parents.filterNot(c => c.typeSymbol == ClassfileAnnotationClass || c.typeSymbol == AnnotationClass)
237+
else parents
238+
}
239+
240+
val allParents = classParents ++ classSym.annotations.flatMap(newParentForAnnotation)
241+
242+
// We keep the superClass when computing minimizeParents to eliminate more interfaces.
243+
// Example: T can be eliminated from D
244+
// trait T
245+
// class C extends T
246+
// class D extends C with T
247+
val interfaces = erasure.minimizeParents(allParents) match {
248+
case superClass :: ifs if !isInterfaceOrTrait(superClass.typeSymbol) =>
249+
ifs
250+
case ifs =>
251+
// minimizeParents removes the superclass if it's redundant, for example:
252+
// trait A
253+
// class C extends Object with A // minimizeParents removes Object
254+
ifs
255+
}
256+
interfaces.map(_.typeSymbol)
257+
}
258+
259+
/**
260+
* The member classes of a class symbol. Note that the result of this method depends on the
261+
* current phase, for example, after lambdalift, all local classes become member of the enclosing
262+
* class.
263+
*
264+
* Impl classes are always considered top-level, see comment in BTypes.
265+
*/
266+
private def memberClassesForInnerClassTable(classSymbol: Symbol): List[Symbol] = classSymbol.info.decls.collect({
267+
case sym if sym.isClass && !considerAsTopLevelImplementationArtifact(sym) =>
268+
sym
269+
case sym if sym.isModule && !considerAsTopLevelImplementationArtifact(sym) => // impl classes get the lateMODULE flag in mixin
270+
val r = exitingPickler(sym.moduleClass)
271+
assert(r != NoSymbol, sym.fullLocationString)
272+
r
273+
})(collection.breakOut)
274+
223275
private def setClassInfo(classSym: Symbol, classBType: ClassBType): ClassBType = {
276+
/**
277+
* Reconstruct the classfile flags from a Java defined class symbol.
278+
*
279+
* The implementation of this method is slightly different from `javaFlags` in BTypesFromSymbols.
280+
* The javaFlags method is primarily used to map Scala symbol flags to sensible classfile flags
281+
* that are used in the generated classfiles. For example, all classes emitted by the Scala
282+
* compiler have ACC_PUBLIC.
283+
*
284+
* When building a [[ClassBType]] from a Java class symbol, the flags in the type's `info` have
285+
* to correspond exactly to the flags in the classfile. For example, if the class is package
286+
* protected (i.e., it doesn't have the ACC_PUBLIC flag), this needs to be reflected in the
287+
* ClassBType. For example, the inliner needs the correct flags for access checks.
288+
*
289+
* Class flags are listed here:
290+
* https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1-200-E.1
291+
*/
292+
def javaClassfileFlags(classSym: Symbol): Int = {
293+
assert(classSym.isJava, s"Expected Java class symbol, got ${classSym.fullName}")
294+
import asm.Opcodes._
295+
def enumFlags = ACC_ENUM | {
296+
// Java enums have the `ACC_ABSTRACT` flag if they have a deferred method.
297+
// We cannot trust `hasAbstractFlag`: the ClassfileParser adds `ABSTRACT` and `SEALED` to all
298+
// Java enums for exhaustiveness checking.
299+
val hasAbstractMethod = classSym.info.decls.exists(s => s.isMethod && s.isDeferred)
300+
if (hasAbstractMethod) ACC_ABSTRACT else 0
301+
}
302+
GenBCode.mkFlags(
303+
// SI-9393: the classfile / java source parser make java annotation symbols look like classes.
304+
// here we recover the actual classfile flags.
305+
if (classSym.hasJavaAnnotationFlag) ACC_ANNOTATION | ACC_INTERFACE | ACC_ABSTRACT else 0,
306+
if (classSym.isPublic) ACC_PUBLIC else 0,
307+
if (classSym.isFinal) ACC_FINAL else 0,
308+
// see the link above. javac does the same: ACC_SUPER for all classes, but not interfaces.
309+
if (classSym.isInterface) ACC_INTERFACE else ACC_SUPER,
310+
// for Java enums, we cannot trust `hasAbstractFlag` (see comment in enumFlags)
311+
if (!classSym.hasJavaEnumFlag && classSym.hasAbstractFlag) ACC_ABSTRACT else 0,
312+
if (classSym.isArtifact) ACC_SYNTHETIC else 0,
313+
if (classSym.hasJavaEnumFlag) enumFlags else 0
314+
)
315+
}
316+
224317
// Check for isImplClass: trait implementation classes have NoSymbol as superClass
225318
// Check for hasAnnotationFlag for SI-9393: the classfile / java source parsers add
226319
// scala.annotation.Annotation as superclass to java annotations. In reality, java

0 commit comments

Comments
 (0)