Re: [Ikvm-developers] Type mapping & interface inheritance question
Brought to you by:
jfrijters
|
From: David J. <ju...@or...> - 2004-09-11 18:44:54
|
OK, so there is another interface between IA & IB, but it should still work.
I've managed to reproduce the problem with simple test interfaces/classes.
It seems to compile when IA,IA2 & IB are implemented in C# and compiled with
mcs, but not when implemented in Java and ikvmc'd.
The mcs error is:
Main.cs(7) error CS1502: The best overloaded match for method 'void F.f
(IA)' has some invalid arguments
Main.cs(7) error CS1503: Argument 0: Cannot convert from 'C' to 'IA'
Main.cs(7) error CS1501: No overload for method `f' takes `1' arguments
Main.cs(7) error CS8006: Could not find any applicable function for this
argument list
Compilation failed: 4 error(s), 0 warnings
I'll paste all the C#/Java and monodis output of the IL code
from both mcs & ikvmc for comparison (sorry about the length).
Thanks for taking time to check it out.
-David.
// IA.java:
public interface IA
{
void methodA();
}
// IA2.java:
public interface IA2 extends IA
{
void methodA2();
}
// IB.java:
public interface IB extends IA2
{
void methodB();
}
// F.java:
public class F
{
public void f(IA a) {}
}
// C.cs:
public class C : IB
{
public void methodA() {}
public void methodA2() {}
public void methodB() {}
}
// Main.cs
public class MainClass
{
public static void Main()
{
F f = new F();
C c = new C();
f.f(c);
}
}
The IA.cs, IA2.cs & IB.cs are just analogues to their .java
counterparts, I won't
paste them in.
Now, monodis output of AA2BF.dll which was created from a AA2BF.jar
containing
the .class files output from Sun's javac using ikvmc.
.assembly extern IKVM.GNU.Classpath
{
.ver 0:9:1713:20439
}
.assembly extern IKVM.Runtime
{
.ver 0:9:1714:29037
}
.assembly 'AA2BF'
{
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module AA2BF // GUID = {5B662C24-8A4F-4ADE-93E5-0B301484E265}
.custom instance void class
[IKVM.Runtime]IKVM.Attributes.JavaModuleAttribute::.ctor() = (01 00 00
00 ) // ....
.class interface public auto ansi abstract beforefieldinit IA
{
// method line 1
.method public virtual abstract
instance default void methodA () cil managed
{
// Method begins at RVA 0x0
} // end of method IA::instance default void methodA ()
} // end of class IA
.class interface public auto ansi abstract beforefieldinit IA2
implements IA {
.custom instance void class
[IKVM.Runtime]IKVM.Attributes.ImplementsAttribute::.ctor(string[]) =
(01 00 01 00 00 00 02 49 41 00 00 ) // .......IA..
// method line 2
.method public virtual abstract
instance default void methodA2 () cil managed
{
// Method begins at RVA 0x0
} // end of method IA2::instance default void methodA2 ()
} // end of class IA2
.class public auto ansi beforefieldinit F
extends [IKVM.GNU.Classpath]java.lang.Object
{
// method line 3
.method public specialname rtspecialname
instance default void .ctor () cil managed
{
// Method begins at RVA 0x20ec
// Code size 9 (0x9)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void class
[IKVM.GNU.Classpath]java.lang.Object::.ctor()
IL_0006: ret
IL_0007: br.s IL_0007
} // end of method F::instance default void .ctor ()
// method line 4
.method public virtual newslot
instance default void f (class IA ) cil managed
{
// Method begins at RVA 0x20f6
// Code size 3 (0x3)
.maxstack 8
IL_0000: ret
IL_0001: br.s IL_0001
} // end of method F::instance default void f (class IA )
} // end of class F
.class interface public auto ansi abstract beforefieldinit IB
implements IA2 {
.custom instance void class
[IKVM.Runtime]IKVM.Attributes.ImplementsAttribute::.ctor(string[]) =
(01 00 01 00 00 00 03 49 41 32 00 00 ) // .......IA2..
// method line 5
.method public virtual abstract
instance default void methodB () cil managed
{
// Method begins at RVA 0x0
} // end of method IB::instance default void methodB ()
} // end of class IB
=======
For comparison, the monodis output of AA2BF.dll generated from the C#
implementations:
.assembly extern mscorlib
{
.ver 1:0:5000:0
}
.assembly 'AA2BF'
{
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module AA2BF.dll // GUID = {626E2C5C-24B9-4861-AF8B-A0ACB44A0E25}
.class interface public auto ansi abstract IA
{
// method line 1
.method public virtual hidebysig newslot abstract
instance default void methodA () cil managed
{
// Method begins at RVA 0x0
} // end of method IA::instance default void methodA ()
} // end of class IA
.class interface public auto ansi abstract IA2
implements IA {
// method line 2
.method public virtual hidebysig newslot abstract
instance default void methodA2 () cil managed
{
// Method begins at RVA 0x0
} // end of method IA2::instance default void methodA2 ()
} // end of class IA2
.class interface public auto ansi abstract IB
implements IA {
// method line 3
.method public virtual hidebysig newslot abstract
instance default void methodB () cil managed
{
// Method begins at RVA 0x0
} // end of method IB::instance default void methodB ()
} // end of class IB
.class public auto ansi beforefieldinit F
extends [mscorlib]System.Object
{
// method line 4
.method public hidebysig specialname rtspecialname
instance default void .ctor () cil managed
{
// Method begins at RVA 0x20ec
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void valuetype [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method F::instance default void .ctor ()
// method line 5
.method public hidebysig
instance default void f (class IA a) cil managed
{
.param [1]
// Method begins at RVA 0x20f4
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method F::instance default void f (class IA a)
} // end of class F
=====
Here is some IL code from main.exe that was sucessfully compiled from
the C# implementations.
Q: Why does class C explicitly reference implementing IA & IB, but not IA2?
Also, another anomaly (mcs bug?), if I remove the implementation of
method 'methodA2()'
from class C, Main still compiles fine (it instantiates a C despite the
fact that there is no
implementation for IA2.methodA2()!) - or am I missing something here?
.assembly extern mscorlib
{
.ver 1:0:5000:0
}
.assembly extern AA2BF
{
.ver 0:0:0:0
}
.assembly 'main'
{
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module main.exe // GUID = {276CAC31-0ECC-40E1-9859-5988D49C3C7E}
.class public auto ansi beforefieldinit C
extends [mscorlib]System.Object
implements [AA2BF]IB, [AA2BF]IA {
// method line 1
.method public hidebysig specialname rtspecialname
instance default void .ctor () cil managed
{
// Method begins at RVA 0x20ec
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void valuetype
[mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method C::instance default void .ctor ()
// method line 2
.method public final virtual hidebysig newslot
instance default void methodA () cil managed
{
// Method begins at RVA 0x20f4
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method C::instance default void methodA ()
// method line 3
.method public hidebysig
instance default void methodA2 () cil managed
{
// Method begins at RVA 0x20f6
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method C::instance default void methodA2 ()
// method line 4
.method public final virtual hidebysig newslot
instance default void methodB () cil managed
{
// Method begins at RVA 0x20f8
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method C::instance default void methodB ()
} // end of class C
.class public auto ansi beforefieldinit MainClass
extends [mscorlib]System.Object
{
// method line 5
.method public hidebysig specialname rtspecialname
instance default void .ctor () cil managed
{
// Method begins at RVA 0x20fa
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void valuetype
[mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method MainClass::instance default void .ctor ()
// method line 6
.method public static hidebysig
default void Main () cil managed
{
// Method begins at RVA 0x2102
.entrypoint
// Code size 20 (0x14)
.maxstack 3
.locals init (
class [AA2BF]F V_0,
class C V_1)
IL_0000: newobj instance void class [AA2BF]F::.ctor()
IL_0005: stloc.0
IL_0006: newobj instance void class C::.ctor()
IL_000b: stloc.1
IL_000c: ldloc.0
IL_000d: ldloc.1
IL_000e: callvirt instance void class [AA2BF]F::f(class [AA2BF]IA)
IL_0013: ret
} // end of method MainClass::default void Main ()
} // end of class MainClass
|