diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2006-08-22 13:38:09 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2006-08-22 13:38:09 +0000 |
commit | 9954eafffd5e60676238369ab0ed5797c92b4a7b (patch) | |
tree | 7243c9c091b45b898ce67f4f5bdb006fd77c69eb | |
parent | b795edec9259e36caa9a4c4ac7e69becae0be613 (diff) | |
download | scala-9954eafffd5e60676238369ab0ed5797c92b4a7b.tar.gz scala-9954eafffd5e60676238369ab0ed5797c92b4a7b.tar.bz2 scala-9954eafffd5e60676238369ab0ed5797c92b4a7b.zip |
Fixed bug #680 and #455 (duplicates) by carryin...
Fixed bug #680 and #455 (duplicates) by carrying more typing context to
the backend for method calls.
-rw-r--r-- | lib/fjbg.jar.desired.sha1 | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | 8 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 21 |
4 files changed, 25 insertions, 11 deletions
diff --git a/lib/fjbg.jar.desired.sha1 b/lib/fjbg.jar.desired.sha1 index b8280737c4..b8f5f85e0e 100644 --- a/lib/fjbg.jar.desired.sha1 +++ b/lib/fjbg.jar.desired.sha1 @@ -1 +1 @@ -d2d42638b37667d365da5ae5be1db85fc03a177e ?fjbg.jar +94369a61b6b74a56c7f74f8a3552bc77314175fc ?fjbg.jar diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 05c7618b0f..257a89cc28 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -731,7 +731,13 @@ abstract class GenICode extends SubComponent { ctx1 = genLoadArguments(args, fun.symbol.info.paramTypes, ctx1) - ctx1.bb.emit(CALL_METHOD(sym, invokeStyle), tree.pos) + val hostClass = fun match { + case Select(qualifier, _) if (qualifier.tpe.symbol != definitions.ArrayClass) => qualifier.tpe.symbol; + case _ => sym.owner; + } + if (settings.debug.value && hostClass != sym.owner) + log("Set more precise host class for " + sym.fullNameString + " host: " + hostClass); + ctx1.bb.emit(CALL_METHOD(sym, invokeStyle) setHostClass hostClass, tree.pos) generatedType = if (sym.isClassConstructor) UNIT else toTypeKind(sym.info.resultType); diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala index 856e91283b..5d08f3e102 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala @@ -282,7 +282,10 @@ trait Opcodes requires ICodes { case class CALL_METHOD(method: Symbol, style: InvokeStyle) extends Instruction { /** Returns a string representation of this instruction */ override def toString(): String = - "CALL_METHOD " + method.fullNameString +" ("+style.toString()+")"; + "CALL_METHOD " + hostClass.fullNameString + method.fullNameString +" ("+style.toString()+")"; + + var hostClass: Symbol = method.owner; + def setHostClass(cls: Symbol): this.type = { hostClass = cls; this } override def consumed = { var result = method.tpe.paramTypes.length; diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 12a56d5dc8..124290f425 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -694,21 +694,19 @@ abstract class GenJVM extends SubComponent { case CALL_PRIMITIVE(primitive) => genPrimitive(primitive, instr.pos); - // TODO: reference the type of the receiver instead of the - // method owner. - case CALL_METHOD(method, style) => - val owner = javaName(method.owner); // + (if (method.owner.isModuleClass) "$" else ""); + case call @ CALL_METHOD(method, style) => + val owner: String = javaName(method.owner); + //reference the type of the receiver instead of the method owner (if not an interface!) + val dynamicOwner = if (needsInterfaceCall(call.hostClass)) owner else javaName(call.hostClass); style match { case Dynamic => - if (method.owner.hasFlag(Flags.INTERFACE) || - (method.owner.hasFlag(Flags.JAVA) && - method.owner.isNonBottomSubClass(definitions.AttributeClass))) + if (needsInterfaceCall(method.owner)) jcode.emitINVOKEINTERFACE(owner, javaName(method), javaType(method).asInstanceOf[JMethodType]) else - jcode.emitINVOKEVIRTUAL(owner, + jcode.emitINVOKEVIRTUAL(dynamicOwner, javaName(method), javaType(method).asInstanceOf[JMethodType]); @@ -1229,6 +1227,13 @@ abstract class GenJVM extends SubComponent { def isStaticSymbol(s: Symbol): Boolean = s.hasFlag(Flags.STATIC) || s.hasFlag(Flags.STATICMEMBER) || s.owner.isImplClass; + /** Calls to methods in 'sym' need invokeinterface? */ + def needsInterfaceCall(sym: Symbol): Boolean = + sym.hasFlag(Flags.INTERFACE) || + (sym.hasFlag(Flags.JAVA) && + sym.isNonBottomSubClass(definitions.AttributeClass)) + + def javaType(t: TypeKind): JType = t match { case UNIT => JType.VOID; case BOOL => JType.BOOLEAN; |