@@ -17,6 +17,7 @@ import scala.tools.asm
17
17
import GenBCode ._
18
18
import BackendReporting ._
19
19
import scala .tools .asm .tree .MethodInsnNode
20
+ import scala .tools .nsc .backend .jvm .BCodeHelpers .TestOp
20
21
21
22
/*
22
23
*
@@ -34,7 +35,6 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
34
35
* Functionality to build the body of ASM MethodNode, except for `synchronized` and `try` expressions.
35
36
*/
36
37
abstract class PlainBodyBuilder (cunit : CompilationUnit ) extends PlainSkelBuilder (cunit) {
37
- import icodes .TestOp
38
38
import invokeStyles ._
39
39
40
40
/* If the selector type has a member with the right name,
@@ -120,7 +120,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
120
120
code match {
121
121
case POS => () // nothing
122
122
case NEG => bc.neg(resKind)
123
- case NOT => bc.genPrimitiveArithmetic(icodes. NOT , resKind)
123
+ case NOT => bc.genPrimitiveNot( resKind)
124
124
case _ => abort(s " Unknown unary operation: ${fun.symbol.fullName} code: $code" )
125
125
}
126
126
@@ -1104,10 +1104,10 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
1104
1104
(tk : @ unchecked) match {
1105
1105
case LONG => emit(asm.Opcodes .LCMP )
1106
1106
case FLOAT =>
1107
- if (op == icodes .LT || op == icodes .LE ) emit(asm.Opcodes .FCMPG )
1107
+ if (op == TestOp .LT || op == TestOp .LE ) emit(asm.Opcodes .FCMPG )
1108
1108
else emit(asm.Opcodes .FCMPL )
1109
1109
case DOUBLE =>
1110
- if (op == icodes .LT || op == icodes .LE ) emit(asm.Opcodes .DCMPG )
1110
+ if (op == TestOp .LT || op == TestOp .LE ) emit(asm.Opcodes .DCMPG )
1111
1111
else emit(asm.Opcodes .DCMPL )
1112
1112
}
1113
1113
bc.emitIF(op, success)
@@ -1122,8 +1122,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
1122
1122
} else if (tk.isRef) { // REFERENCE(_) | ARRAY(_)
1123
1123
// @unchecked because references aren't compared with GT, GE, LT, LE.
1124
1124
(op : @ unchecked) match {
1125
- case icodes .EQ => bc emitIFNULL success
1126
- case icodes .NE => bc emitIFNONNULL success
1125
+ case TestOp .EQ => bc emitIFNULL success
1126
+ case TestOp .NE => bc emitIFNONNULL success
1127
1127
}
1128
1128
} else {
1129
1129
(tk : @ unchecked) match {
@@ -1132,21 +1132,28 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
1132
1132
emit(asm.Opcodes .LCMP )
1133
1133
case FLOAT =>
1134
1134
emit(asm.Opcodes .FCONST_0 )
1135
- if (op == icodes .LT || op == icodes .LE ) emit(asm.Opcodes .FCMPG )
1135
+ if (op == TestOp .LT || op == TestOp .LE ) emit(asm.Opcodes .FCMPG )
1136
1136
else emit(asm.Opcodes .FCMPL )
1137
1137
case DOUBLE =>
1138
1138
emit(asm.Opcodes .DCONST_0 )
1139
- if (op == icodes .LT || op == icodes .LE ) emit(asm.Opcodes .DCMPG )
1139
+ if (op == TestOp .LT || op == TestOp .LE ) emit(asm.Opcodes .DCMPG )
1140
1140
else emit(asm.Opcodes .DCMPL )
1141
1141
}
1142
1142
bc.emitIF(op, success)
1143
1143
}
1144
1144
bc goTo failure
1145
1145
}
1146
1146
1147
- val testOpForPrimitive : Array [TestOp ] = Array (
1148
- icodes.EQ , icodes.NE , icodes.EQ , icodes.NE , icodes.LT , icodes.LE , icodes.GE , icodes.GT
1149
- )
1147
+ def testOpForPrimitive (primitiveCode : Int ) = (primitiveCode : @ switch) match {
1148
+ case scalaPrimitives.ID => TestOp .EQ
1149
+ case scalaPrimitives.NI => TestOp .NE
1150
+ case scalaPrimitives.EQ => TestOp .EQ
1151
+ case scalaPrimitives.NE => TestOp .NE
1152
+ case scalaPrimitives.LT => TestOp .LT
1153
+ case scalaPrimitives.LE => TestOp .LE
1154
+ case scalaPrimitives.GE => TestOp .GE
1155
+ case scalaPrimitives.GT => TestOp .GT
1156
+ }
1150
1157
1151
1158
/** Some useful equality helpers. */
1152
1159
def isNull (t : Tree ) = PartialFunction .cond(t) { case Literal (Constant (null )) => true }
@@ -1162,7 +1169,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
1162
1169
private def genCond (tree : Tree , success : asm.Label , failure : asm.Label ) {
1163
1170
1164
1171
def genComparisonOp (l : Tree , r : Tree , code : Int ) {
1165
- val op : TestOp = testOpForPrimitive(code - scalaPrimitives. ID )
1172
+ val op : TestOp = testOpForPrimitive(code)
1166
1173
// special-case reference (in)equality test for null (null eq x, x eq null)
1167
1174
var nonNullSide : Tree = null
1168
1175
if (scalaPrimitives.isReferenceEqualityOp(code) &&
@@ -1181,7 +1188,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
1181
1188
1182
1189
def default () = {
1183
1190
genLoad(tree, BOOL )
1184
- genCZJUMP(success, failure, icodes .NE , BOOL )
1191
+ genCZJUMP(success, failure, TestOp .NE , BOOL )
1185
1192
}
1186
1193
1187
1194
lineNumber(tree)
@@ -1259,23 +1266,23 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
1259
1266
genLoad(l, ObjectRef )
1260
1267
genLoad(r, ObjectRef )
1261
1268
genCallMethod(equalsMethod, Static (onInstance = false ), pos)
1262
- genCZJUMP(success, failure, icodes .NE , BOOL )
1269
+ genCZJUMP(success, failure, TestOp .NE , BOOL )
1263
1270
}
1264
1271
else {
1265
1272
if (isNull(l)) {
1266
1273
// null == expr -> expr eq null
1267
1274
genLoad(r, ObjectRef )
1268
- genCZJUMP(success, failure, icodes .EQ , ObjectRef )
1275
+ genCZJUMP(success, failure, TestOp .EQ , ObjectRef )
1269
1276
} else if (isNull(r)) {
1270
1277
// expr == null -> expr eq null
1271
1278
genLoad(l, ObjectRef )
1272
- genCZJUMP(success, failure, icodes .EQ , ObjectRef )
1279
+ genCZJUMP(success, failure, TestOp .EQ , ObjectRef )
1273
1280
} else if (isNonNullExpr(l)) {
1274
1281
// SI-7852 Avoid null check if L is statically non-null.
1275
1282
genLoad(l, ObjectRef )
1276
1283
genLoad(r, ObjectRef )
1277
1284
genCallMethod(Object_equals , Dynamic , pos)
1278
- genCZJUMP(success, failure, icodes .NE , BOOL )
1285
+ genCZJUMP(success, failure, TestOp .NE , BOOL )
1279
1286
} else {
1280
1287
// l == r -> if (l eq null) r eq null else l.equals(r)
1281
1288
val eqEqTempLocal = locals.makeLocal(ObjectRef , nme.EQEQ_LOCAL_VAR .toString)
@@ -1286,17 +1293,17 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
1286
1293
genLoad(r, ObjectRef )
1287
1294
locals.store(eqEqTempLocal)
1288
1295
bc dup ObjectRef
1289
- genCZJUMP(lNull, lNonNull, icodes .EQ , ObjectRef )
1296
+ genCZJUMP(lNull, lNonNull, TestOp .EQ , ObjectRef )
1290
1297
1291
1298
markProgramPoint(lNull)
1292
1299
bc drop ObjectRef
1293
1300
locals.load(eqEqTempLocal)
1294
- genCZJUMP(success, failure, icodes .EQ , ObjectRef )
1301
+ genCZJUMP(success, failure, TestOp .EQ , ObjectRef )
1295
1302
1296
1303
markProgramPoint(lNonNull)
1297
1304
locals.load(eqEqTempLocal)
1298
1305
genCallMethod(Object_equals , Dynamic , pos)
1299
- genCZJUMP(success, failure, icodes .NE , BOOL )
1306
+ genCZJUMP(success, failure, TestOp .NE , BOOL )
1300
1307
}
1301
1308
}
1302
1309
}
0 commit comments