@@ -17,7 +17,7 @@ import scala.tools.asm
1717import GenBCode ._
1818import BackendReporting ._
1919import scala .tools .asm .tree .MethodInsnNode
20- import scala .tools .nsc .backend .jvm .BCodeHelpers .TestOp
20+ import scala .tools .nsc .backend .jvm .BCodeHelpers .{ InvokeStyle , TestOp }
2121
2222/*
2323 *
@@ -35,8 +35,6 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
3535 * Functionality to build the body of ASM MethodNode, except for `synchronized` and `try` expressions.
3636 */
3737 abstract class PlainBodyBuilder (cunit : CompilationUnit ) extends PlainSkelBuilder (cunit) {
38- import invokeStyles ._
39-
4038 /* If the selector type has a member with the right name,
4139 * it is the host class; otherwise the symbol's owner.
4240 */
@@ -581,8 +579,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
581579 // to call super constructors explicitly and/or use their 'returned' value.
582580 // therefore, we can ignore this fact, and generate code that leaves nothing
583581 // on the stack (contrary to what the type in the AST says).
584- case Apply (fun @ Select (Super (_, mix ), _), args) =>
585- val invokeStyle = SuperCall (mix)
582+ case Apply (fun @ Select (Super (_, _ ), _), args) =>
583+ val invokeStyle = InvokeStyle . Super
586584 // if (fun.symbol.isConstructor) Static(true) else SuperCall(mix);
587585 mnode.visitVarInsn(asm.Opcodes .ALOAD , 0 )
588586 genLoadArguments(args, paramTKs(app))
@@ -628,7 +626,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
628626 mnode.visitTypeInsn(asm.Opcodes .NEW , rt.internalName)
629627 bc dup generatedType
630628 genLoadArguments(args, paramTKs(app))
631- genCallMethod(ctor, Static (onInstance = true ) , app.pos)
629+ genCallMethod(ctor, InvokeStyle . Special , app.pos)
632630
633631 case _ =>
634632 abort(s " Cannot instantiate $tpt of kind: $generatedType" )
@@ -666,9 +664,9 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
666664 def genNormalMethodCall () {
667665
668666 val invokeStyle =
669- if (sym.isStaticMember) Static (onInstance = false )
670- else if (sym.isPrivate || sym.isClassConstructor) Static (onInstance = true )
671- else Dynamic
667+ if (sym.isStaticMember) InvokeStyle . Static
668+ else if (sym.isPrivate || sym.isClassConstructor) InvokeStyle . Special
669+ else InvokeStyle . Virtual
672670
673671 if (invokeStyle.hasInstance) {
674672 genLoadQualifier(fun)
@@ -695,7 +693,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
695693
696694 case _ =>
697695 }
698- if ((targetTypeKind != null ) && (sym == definitions.Array_clone ) && invokeStyle.isDynamic ) {
696+ if ((targetTypeKind != null ) && (sym == definitions.Array_clone ) && invokeStyle.isVirtual ) {
699697 // An invokevirtual points to a CONSTANT_Methodref_info which in turn points to a
700698 // CONSTANT_Class_info of the receiver type.
701699 // The JVMS is not explicit about this, but that receiver type may be an array type
@@ -997,7 +995,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
997995 // Optimization for expressions of the form "" + x. We can avoid the StringBuilder.
998996 case List (Literal (Constant (" " )), arg) =>
999997 genLoad(arg, ObjectRef )
1000- genCallMethod(String_valueOf , Static (onInstance = false ) , arg.pos)
998+ genCallMethod(String_valueOf , InvokeStyle . Static , arg.pos)
1001999 case concatenations =>
10021000 bc.genStartConcat(tree.pos)
10031001 for (elem <- concatenations) {
@@ -1028,7 +1026,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
10281026 // whether to reference the type of the receiver or
10291027 // the type of the method owner
10301028 val useMethodOwner = (
1031- style != Dynamic
1029+ ! style.isVirtual
10321030 || hostSymbol.isBottomClass
10331031 || methodOwner == definitions.ObjectClass
10341032 )
@@ -1055,11 +1053,9 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
10551053 }
10561054 }
10571055
1058- if (style.isStatic) {
1059- if (style.hasInstance) { bc.invokespecial (jowner, jname, mdescr, pos) }
1060- else { bc.invokestatic (jowner, jname, mdescr, pos) }
1061- }
1062- else if (style.isDynamic) {
1056+ if (style.isStatic) { bc.invokestatic (jowner, jname, mdescr, pos) }
1057+ else if (style.isSpecial) { bc.invokespecial (jowner, jname, mdescr, pos) }
1058+ else if (style.isVirtual) {
10631059 if (needsInterfaceCall(receiver)) { bc.invokeinterface(jowner, jname, mdescr, pos) }
10641060 else { bc.invokevirtual (jowner, jname, mdescr, pos) }
10651061 }
@@ -1075,7 +1071,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
10751071 def genScalaHash (tree : Tree , applyPos : Position ): BType = {
10761072 genLoadModule(ScalaRunTimeModule ) // TODO why load ScalaRunTimeModule if ## has InvokeStyle of Static(false) ?
10771073 genLoad(tree, ObjectRef )
1078- genCallMethod(hashMethodSym, Static (onInstance = false ) , applyPos)
1074+ genCallMethod(hashMethodSym, InvokeStyle . Static , applyPos)
10791075 INT
10801076 }
10811077
@@ -1265,7 +1261,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
12651261 }
12661262 genLoad(l, ObjectRef )
12671263 genLoad(r, ObjectRef )
1268- genCallMethod(equalsMethod, Static (onInstance = false ) , pos)
1264+ genCallMethod(equalsMethod, InvokeStyle . Static , pos)
12691265 genCZJUMP(success, failure, TestOp .NE , BOOL )
12701266 }
12711267 else {
@@ -1281,7 +1277,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
12811277 // SI-7852 Avoid null check if L is statically non-null.
12821278 genLoad(l, ObjectRef )
12831279 genLoad(r, ObjectRef )
1284- genCallMethod(Object_equals , Dynamic , pos)
1280+ genCallMethod(Object_equals , InvokeStyle . Virtual , pos)
12851281 genCZJUMP(success, failure, TestOp .NE , BOOL )
12861282 } else {
12871283 // l == r -> if (l eq null) r eq null else l.equals(r)
@@ -1302,7 +1298,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
13021298
13031299 markProgramPoint(lNonNull)
13041300 locals.load(eqEqTempLocal)
1305- genCallMethod(Object_equals , Dynamic , pos)
1301+ genCallMethod(Object_equals , InvokeStyle . Virtual , pos)
13061302 genCZJUMP(success, failure, TestOp .NE , BOOL )
13071303 }
13081304 }
@@ -1351,54 +1347,4 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
13511347 new asm.Handle (asm.Opcodes .H_INVOKESTATIC ,
13521348 definitions.LambdaMetaFactory .fullName('/' ), sn.AltMetafactory .toString,
13531349 " (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;" )
1354-
1355- object invokeStyles {
1356-
1357- /** This class represents a method invocation style. */
1358- sealed abstract class InvokeStyle {
1359- /** Is this a dynamic method call? */
1360- def isDynamic : Boolean = false
1361-
1362- /** Is this a static method call? */
1363- def isStatic : Boolean = false
1364-
1365- def isSuper : Boolean = false
1366-
1367- /** Is this an instance method call? */
1368- def hasInstance : Boolean = true
1369-
1370- /** Returns a string representation of this style. */
1371- override def toString (): String
1372- }
1373-
1374- /** Virtual calls.
1375- * On JVM, translated to either `invokeinterface` or `invokevirtual`.
1376- */
1377- case object Dynamic extends InvokeStyle {
1378- override def isDynamic = true
1379- override def toString (): String = " dynamic"
1380- }
1381-
1382- /**
1383- * Special invoke:
1384- * Static(true) is used for calls to private members, ie `invokespecial` on JVM.
1385- * Static(false) is used for calls to class-level instance-less static methods, ie `invokestatic` on JVM.
1386- */
1387- case class Static (onInstance : Boolean ) extends InvokeStyle {
1388- override def isStatic = true
1389- override def hasInstance = onInstance
1390- override def toString (): String = {
1391- if (onInstance) " static-instance"
1392- else " static-class"
1393- }
1394- }
1395-
1396- /** Call through super[mix].
1397- * On JVM, translated to `invokespecial`.
1398- */
1399- case class SuperCall (mix : Name ) extends InvokeStyle {
1400- override def isSuper = true
1401- override def toString (): String = { " super(" + mix + " )" }
1402- }
1403- }
14041350}
0 commit comments