summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2006-08-22 13:38:09 +0000
committerIulian Dragos <jaguarul@gmail.com>2006-08-22 13:38:09 +0000
commit9954eafffd5e60676238369ab0ed5797c92b4a7b (patch)
tree7243c9c091b45b898ce67f4f5bdb006fd77c69eb
parentb795edec9259e36caa9a4c4ac7e69becae0be613 (diff)
downloadscala-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.sha12
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala5
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala21
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;