From 096bc3b7be59909521799e6c648dc4f7c2327e8d Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 6 Nov 2015 11:14:16 +0100 Subject: Remove the rest of ICodes The only pieces of ICodes that were still used - An enum representing bytecode comparisons, re-implemented - The `icodes.IClass` class, which remains for sbt compatibility (https://github.com/scala/scala/pull/4588) --- .../scala/tools/nsc/CompilationUnits.scala | 4 +- src/compiler/scala/tools/nsc/Global.scala | 9 +- .../scala/tools/nsc/backend/icode/ICodes.scala | 17 ---- .../scala/tools/nsc/backend/icode/Members.scala | 40 -------- .../scala/tools/nsc/backend/icode/Primitives.scala | 110 --------------------- .../tools/nsc/backend/jvm/BCodeBodyBuilder.scala | 47 +++++---- .../scala/tools/nsc/backend/jvm/BCodeHelpers.scala | 14 +++ .../tools/nsc/backend/jvm/BCodeIdiomatic.scala | 51 +++------- 8 files changed, 62 insertions(+), 230 deletions(-) delete mode 100644 src/compiler/scala/tools/nsc/backend/icode/ICodes.scala delete mode 100644 src/compiler/scala/tools/nsc/backend/icode/Members.scala delete mode 100644 src/compiler/scala/tools/nsc/backend/icode/Primitives.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index 6be1fda1b5..34b07a2651 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -117,9 +117,7 @@ trait CompilationUnits { global: Global => */ def targetPos: Position = NoPosition - /** The icode representation of classes in this compilation unit. - * It is empty up to phase 'icode'. - */ + /** For sbt compatibility (https://github.com/scala/scala/pull/4588) */ val icode: LinkedHashSet[icodes.IClass] = new LinkedHashSet @deprecated("Call global.reporter.echo directly instead.", "2.11.2") diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 77910c8a8b..6a309bab99 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -25,7 +25,6 @@ import ast.parser._ import typechecker._ import transform.patmat.PatternMatching import transform._ -import backend.icode.ICodes import backend.{ ScalaPrimitives, JavaPlatform } import backend.jvm.GenBCode import scala.language.postfixOps @@ -137,10 +136,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter) val global: Global.this.type = Global.this } with ConstantFolder - /** ICode generator */ - object icodes extends { - val global: Global.this.type = Global.this - } with ICodes + /** For sbt compatibility (https://github.com/scala/scala/pull/4588) */ + object icodes { + class IClass(val symbol: Symbol) + } /** Scala primitives, used in genicode */ object scalaPrimitives extends { diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala deleted file mode 100644 index 3a53126d1c..0000000000 --- a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* NSC -- new scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.tools.nsc -package backend -package icode - -/** Glue together ICode parts. - * - * @author Iulian Dragos - */ -abstract class ICodes extends AnyRef with Members with Primitives { - val global: Global -} - diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala deleted file mode 100644 index 4df21626f8..0000000000 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* NSC -- new scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Martin Odersky - */ - -package scala -package tools.nsc -package backend -package icode - -import scala.collection.{ mutable, immutable } -import scala.reflect.internal.Flags -import scala.reflect.internal.util.{ SourceFile, NoSourceFile } - -trait Members { - self: ICodes => - - import global._ - - /** Common interface for IClass/IField/IMethod. */ - trait IMember extends Ordered[IMember] { - def symbol: Symbol - - def compare(other: IMember) = - if (symbol eq other.symbol) 0 - else if (symbol isLess other.symbol) -1 - else 1 - - override def equals(other: Any): Boolean = - other match { - case other: IMember => (this compare other) == 0 - case _ => false - } - - override def hashCode = symbol.## - } - - /** Represent a class in ICode */ - class IClass(val symbol: Symbol) extends IMember -} diff --git a/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala b/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala deleted file mode 100644 index 2785f893ad..0000000000 --- a/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala +++ /dev/null @@ -1,110 +0,0 @@ -/* NSC -- new scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Martin Odersky - */ - - -package scala.tools.nsc -package backend -package icode - -trait Primitives { self: ICodes => - - /** This class represents a test operation. */ - sealed abstract class TestOp { - - /** Returns the negation of this operation. */ - def negate(): TestOp - - /** Returns a string representation of this operation. */ - override def toString(): String - - /** used only from GenASM */ - def opcodeIF(): Int - - /** used only from GenASM */ - def opcodeIFICMP(): Int - } - - /** An equality test */ - case object EQ extends TestOp { - def negate() = NE - override def toString() = "EQ" - override def opcodeIF() = scala.tools.asm.Opcodes.IFEQ - override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPEQ - } - - /** A non-equality test */ - case object NE extends TestOp { - def negate() = EQ - override def toString() = "NE" - override def opcodeIF() = scala.tools.asm.Opcodes.IFNE - override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPNE - } - - /** A less-than test */ - case object LT extends TestOp { - def negate() = GE - override def toString() = "LT" - override def opcodeIF() = scala.tools.asm.Opcodes.IFLT - override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPLT - } - - /** A greater-than-or-equal test */ - case object GE extends TestOp { - def negate() = LT - override def toString() = "GE" - override def opcodeIF() = scala.tools.asm.Opcodes.IFGE - override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPGE - } - - /** A less-than-or-equal test */ - case object LE extends TestOp { - def negate() = GT - override def toString() = "LE" - override def opcodeIF() = scala.tools.asm.Opcodes.IFLE - override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPLE - } - - /** A greater-than test */ - case object GT extends TestOp { - def negate() = LE - override def toString() = "GT" - override def opcodeIF() = scala.tools.asm.Opcodes.IFGT - override def opcodeIFICMP() = scala.tools.asm.Opcodes.IF_ICMPGT - } - - /** This class represents an arithmetic operation. */ - class ArithmeticOp { - - /** Returns a string representation of this operation. */ - override def toString(): String = this match { - case ADD => "ADD" - case SUB => "SUB" - case MUL => "MUL" - case DIV => "DIV" - case REM => "REM" - case NOT => "NOT" - case _ => throw new RuntimeException("ArithmeticOp unknown case") - } - } - - /** An arithmetic addition operation */ - case object ADD extends ArithmeticOp - - /** An arithmetic subtraction operation */ - case object SUB extends ArithmeticOp - - /** An arithmetic multiplication operation */ - case object MUL extends ArithmeticOp - - /** An arithmetic division operation */ - case object DIV extends ArithmeticOp - - /** An arithmetic remainder operation */ - case object REM extends ArithmeticOp - - /** Bitwise negation. */ - case object NOT extends ArithmeticOp -} - diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 09f0684501..86c509fae4 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -17,6 +17,7 @@ import scala.tools.asm import GenBCode._ import BackendReporting._ import scala.tools.asm.tree.MethodInsnNode +import scala.tools.nsc.backend.jvm.BCodeHelpers.TestOp /* * @@ -34,7 +35,6 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { * Functionality to build the body of ASM MethodNode, except for `synchronized` and `try` expressions. */ abstract class PlainBodyBuilder(cunit: CompilationUnit) extends PlainSkelBuilder(cunit) { - import icodes.TestOp import invokeStyles._ /* If the selector type has a member with the right name, @@ -120,7 +120,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { code match { case POS => () // nothing case NEG => bc.neg(resKind) - case NOT => bc.genPrimitiveArithmetic(icodes.NOT, resKind) + case NOT => bc.genPrimitiveNot(resKind) case _ => abort(s"Unknown unary operation: ${fun.symbol.fullName} code: $code") } @@ -1104,10 +1104,10 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { (tk: @unchecked) match { case LONG => emit(asm.Opcodes.LCMP) case FLOAT => - if (op == icodes.LT || op == icodes.LE) emit(asm.Opcodes.FCMPG) + if (op == TestOp.LT || op == TestOp.LE) emit(asm.Opcodes.FCMPG) else emit(asm.Opcodes.FCMPL) case DOUBLE => - if (op == icodes.LT || op == icodes.LE) emit(asm.Opcodes.DCMPG) + if (op == TestOp.LT || op == TestOp.LE) emit(asm.Opcodes.DCMPG) else emit(asm.Opcodes.DCMPL) } bc.emitIF(op, success) @@ -1122,8 +1122,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { } else if (tk.isRef) { // REFERENCE(_) | ARRAY(_) // @unchecked because references aren't compared with GT, GE, LT, LE. (op : @unchecked) match { - case icodes.EQ => bc emitIFNULL success - case icodes.NE => bc emitIFNONNULL success + case TestOp.EQ => bc emitIFNULL success + case TestOp.NE => bc emitIFNONNULL success } } else { (tk: @unchecked) match { @@ -1132,11 +1132,11 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { emit(asm.Opcodes.LCMP) case FLOAT => emit(asm.Opcodes.FCONST_0) - if (op == icodes.LT || op == icodes.LE) emit(asm.Opcodes.FCMPG) + if (op == TestOp.LT || op == TestOp.LE) emit(asm.Opcodes.FCMPG) else emit(asm.Opcodes.FCMPL) case DOUBLE => emit(asm.Opcodes.DCONST_0) - if (op == icodes.LT || op == icodes.LE) emit(asm.Opcodes.DCMPG) + if (op == TestOp.LT || op == TestOp.LE) emit(asm.Opcodes.DCMPG) else emit(asm.Opcodes.DCMPL) } bc.emitIF(op, success) @@ -1144,9 +1144,16 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { bc goTo failure } - val testOpForPrimitive: Array[TestOp] = Array( - icodes.EQ, icodes.NE, icodes.EQ, icodes.NE, icodes.LT, icodes.LE, icodes.GE, icodes.GT - ) + def testOpForPrimitive(primitiveCode: Int) = (primitiveCode: @switch) match { + case scalaPrimitives.ID => TestOp.EQ + case scalaPrimitives.NI => TestOp.NE + case scalaPrimitives.EQ => TestOp.EQ + case scalaPrimitives.NE => TestOp.NE + case scalaPrimitives.LT => TestOp.LT + case scalaPrimitives.LE => TestOp.LE + case scalaPrimitives.GE => TestOp.GE + case scalaPrimitives.GT => TestOp.GT + } /** Some useful equality helpers. */ def isNull(t: Tree) = PartialFunction.cond(t) { case Literal(Constant(null)) => true } @@ -1162,7 +1169,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { private def genCond(tree: Tree, success: asm.Label, failure: asm.Label) { def genComparisonOp(l: Tree, r: Tree, code: Int) { - val op: TestOp = testOpForPrimitive(code - scalaPrimitives.ID) + val op: TestOp = testOpForPrimitive(code) // special-case reference (in)equality test for null (null eq x, x eq null) var nonNullSide: Tree = null if (scalaPrimitives.isReferenceEqualityOp(code) && @@ -1181,7 +1188,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { def default() = { genLoad(tree, BOOL) - genCZJUMP(success, failure, icodes.NE, BOOL) + genCZJUMP(success, failure, TestOp.NE, BOOL) } lineNumber(tree) @@ -1259,23 +1266,23 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(l, ObjectRef) genLoad(r, ObjectRef) genCallMethod(equalsMethod, Static(onInstance = false), pos) - genCZJUMP(success, failure, icodes.NE, BOOL) + genCZJUMP(success, failure, TestOp.NE, BOOL) } else { if (isNull(l)) { // null == expr -> expr eq null genLoad(r, ObjectRef) - genCZJUMP(success, failure, icodes.EQ, ObjectRef) + genCZJUMP(success, failure, TestOp.EQ, ObjectRef) } else if (isNull(r)) { // expr == null -> expr eq null genLoad(l, ObjectRef) - genCZJUMP(success, failure, icodes.EQ, ObjectRef) + genCZJUMP(success, failure, TestOp.EQ, ObjectRef) } else if (isNonNullExpr(l)) { // SI-7852 Avoid null check if L is statically non-null. genLoad(l, ObjectRef) genLoad(r, ObjectRef) genCallMethod(Object_equals, Dynamic, pos) - genCZJUMP(success, failure, icodes.NE, BOOL) + genCZJUMP(success, failure, TestOp.NE, BOOL) } else { // l == r -> if (l eq null) r eq null else l.equals(r) val eqEqTempLocal = locals.makeLocal(ObjectRef, nme.EQEQ_LOCAL_VAR.toString) @@ -1286,17 +1293,17 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(r, ObjectRef) locals.store(eqEqTempLocal) bc dup ObjectRef - genCZJUMP(lNull, lNonNull, icodes.EQ, ObjectRef) + genCZJUMP(lNull, lNonNull, TestOp.EQ, ObjectRef) markProgramPoint(lNull) bc drop ObjectRef locals.load(eqEqTempLocal) - genCZJUMP(success, failure, icodes.EQ, ObjectRef) + genCZJUMP(success, failure, TestOp.EQ, ObjectRef) markProgramPoint(lNonNull) locals.load(eqEqTempLocal) genCallMethod(Object_equals, Dynamic, pos) - genCZJUMP(success, failure, icodes.NE, BOOL) + genCZJUMP(success, failure, TestOp.NE, BOOL) } } } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index 1e93903bd2..39aaa1bee7 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -1352,4 +1352,18 @@ object BCodeHelpers { asm.Opcodes.ACC_ABSTRACT | asm.Opcodes.ACC_SYNTHETIC | asm.Opcodes.ACC_ANNOTATION | asm.Opcodes.ACC_ENUM } + + class TestOp(val op: Int) extends AnyVal { + def opcodeIF = asm.Opcodes.IFEQ + op + def opcodeIFICMP = asm.Opcodes.IF_ICMPEQ + op + } + + object TestOp { + val EQ = new TestOp(0) + val NE = new TestOp(1) + val LT = new TestOp(2) + val GE = new TestOp(3) + val GT = new TestOp(4) + val LE = new TestOp(5) + } } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala index cef57cd539..4a10756468 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala @@ -12,6 +12,7 @@ import scala.annotation.switch import scala.collection.mutable import GenBCode._ import scala.tools.asm.tree.MethodInsnNode +import scala.tools.nsc.backend.jvm.BCodeHelpers.TestOp /* * A high-level facade to the ASM API for bytecode generation. @@ -109,37 +110,17 @@ abstract class BCodeIdiomatic extends SubComponent { final def emit(opc: Int) { jmethod.visitInsn(opc) } - /* - * can-multi-thread - */ - final def genPrimitiveArithmetic(op: icodes.ArithmeticOp, kind: BType) { - - import icodes.{ ADD, SUB, MUL, DIV, REM, NOT } - - op match { - - case ADD => add(kind) - case SUB => sub(kind) - case MUL => mul(kind) - case DIV => div(kind) - case REM => rem(kind) - - case NOT => - if (kind.isIntSizedType) { - emit(Opcodes.ICONST_M1) - emit(Opcodes.IXOR) - } else if (kind == LONG) { - jmethod.visitLdcInsn(new java.lang.Long(-1)) - jmethod.visitInsn(Opcodes.LXOR) - } else { - abort(s"Impossible to negate an $kind") - } - - case _ => - abort(s"Unknown arithmetic primitive $op") + final def genPrimitiveNot(bType: BType): Unit = { + if (bType.isIntSizedType) { + emit(Opcodes.ICONST_M1) + emit(Opcodes.IXOR) + } else if (bType == LONG) { + jmethod.visitLdcInsn(new java.lang.Long(-1)) + jmethod.visitInsn(Opcodes.LXOR) + } else { + abort(s"Impossible to negate a $bType") } - - } // end of method genPrimitiveArithmetic() + } /* * can-multi-thread @@ -415,13 +396,13 @@ abstract class BCodeIdiomatic extends SubComponent { // can-multi-thread final def goTo(label: asm.Label) { jmethod.visitJumpInsn(Opcodes.GOTO, label) } // can-multi-thread - final def emitIF(cond: icodes.TestOp, label: asm.Label) { jmethod.visitJumpInsn(cond.opcodeIF, label) } + final def emitIF(cond: TestOp, label: asm.Label) { jmethod.visitJumpInsn(cond.opcodeIF, label) } // can-multi-thread - final def emitIF_ICMP(cond: icodes.TestOp, label: asm.Label) { jmethod.visitJumpInsn(cond.opcodeIFICMP, label) } + final def emitIF_ICMP(cond: TestOp, label: asm.Label) { jmethod.visitJumpInsn(cond.opcodeIFICMP, label) } // can-multi-thread - final def emitIF_ACMP(cond: icodes.TestOp, label: asm.Label) { - assert((cond == icodes.EQ) || (cond == icodes.NE), cond) - val opc = (if (cond == icodes.EQ) Opcodes.IF_ACMPEQ else Opcodes.IF_ACMPNE) + final def emitIF_ACMP(cond: TestOp, label: asm.Label) { + assert((cond == TestOp.EQ) || (cond == TestOp.NE), cond) + val opc = (if (cond == TestOp.EQ) Opcodes.IF_ACMPEQ else Opcodes.IF_ACMPNE) jmethod.visitJumpInsn(opc, label) } // can-multi-thread -- cgit v1.2.3