[Mono-bugs] interface bug.
Iman Habib
pixelpajas@hotmail.com
Tue, 2 Jul 2002 20:53:40 +0200
This is a multi-part message in MIME format.
------=_NextPart_000_000A_01C2220A.8B7FC8A0
Content-Type: multipart/alternative;
boundary="----=_NextPart_001_000B_01C2220A.8B7FC8A0"
------=_NextPart_001_000B_01C2220A.8B7FC8A0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
bug...=20
Now I'm using the "mono for windows" so this mail may be OT
but I think the issue has to do directly with the mono compiler.
Trying to compile this code with mono compiler (mcs) work
and I also executes without any problems with mono Jit or
the interpreter. But the code does not later on run with the
MS Jit.
--- begin test.cs ---
using System;
interface IParentInterface {
void ParentInterfaceMethod();
}
interface IMyInterface : IParentInterface {
void MethodToImplement();
}
class InterfaceImplementer : IMyInterface {
static void Main() {
InterfaceImplementer iImp =3D new InterfaceImplementer();
iImp.MethodToImplement();
iImp.ParentInterfaceMethod();
}
public void MethodToImplement() {
Console.WriteLine("MethodToImplement() called.");
}
public void ParentInterfaceMethod() {
Console.WriteLine("ParentInterfaceMethod() called.");
}
}
--- end test.cs ---
Running it with the MS Jit gives the following error:
"An unhandled exception of type 'System.TypeLoadException' occurred in =
Unknown Module."
"Additional information: Method ParentInterfaceMethod in type =
InterfaceImplementer from assembly ParentInterfaceMethod does not have =
an implementation."
.. now this made me suspicious at the mono compiler since the same =
source compiled
with the MS C# compiler and ran on both Jit's (Mono & MS jit)
So I got a little curios.
The first thing I did was to decompile the source of both compiles
executables with the help of salamander =
(http://www.remotesoft.com/salamander/index.html)
The only difference are these lines when decompiles.
The MS Decompiled version:
public sealed virtual void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
public sealed virtual void ParentInterfaceMethod()
{
Console.WriteLine("ParentInterfaceMethod() called.");
}
The Mono Decompiled version:
public virtual void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
public void ParentInterfaceMethod()
{
Console.WriteLine("ParentInterfaceMethod() called.");
}
Now looking at both versions of the decompiled code the
difference is pretty obvious..=20
but that might not tell the whole story so I also attached
a disassembled il bytecode of both executables.
I used ildasm to disassemble them.
The rest is up to you guys.. =3D)
keep up the good work.
regards
//iman
------=_NextPart_001_000B_01C2220A.8B7FC8A0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2716.2200" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>
<DIV>
<DIV><FONT face=3DArial size=3D2></FONT></DIV></DIV>
<DIV><FONT face=3DArial size=3D2>bug... </FONT></DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV><FONT face=3DArial size=3D2>Now I'm using the "mono for windows" so =
this mail=20
may be OT<BR>but I think the issue has to do directly with the mono=20
compiler.</FONT></DIV>
<DIV> </DIV><FONT face=3DArial size=3D2>
<DIV><BR>Trying to compile this code with mono compiler (mcs) =
work<BR>and I also=20
executes without any problems with mono Jit or<BR>the interpreter. But =
the code=20
does not later on run with the<BR>MS Jit.</DIV>
<DIV> </DIV>
<DIV><BR>--- begin test.cs ---</DIV>
<DIV> </DIV>
<DIV>using System;</DIV>
<DIV> </DIV>
<DIV>interface IParentInterface {<BR> void=20
ParentInterfaceMethod();<BR>}</DIV>
<DIV> </DIV>
<DIV>interface IMyInterface : IParentInterface {<BR> =
void=20
MethodToImplement();<BR>}</DIV>
<DIV> </DIV>
<DIV>class InterfaceImplementer : IMyInterface {<BR> =
static=20
void Main() {<BR> =
InterfaceImplementer=20
iImp =3D new =
InterfaceImplementer();<BR> =20
iImp.MethodToImplement();<BR> =20
iImp.ParentInterfaceMethod();<BR> }</DIV>
<DIV> </DIV>
<DIV> public void MethodToImplement()=20
{<BR> =20
Console.WriteLine("MethodToImplement() called.");<BR> =
}</DIV>
<DIV> </DIV>
<DIV> public void ParentInterfaceMethod()=20
{<BR> =20
Console.WriteLine("ParentInterfaceMethod() =
called.");<BR> =20
}<BR>}</DIV>
<DIV> </DIV>
<DIV><BR>--- end test.cs ---</DIV>
<DIV> </DIV>
<DIV><BR>Running it with the MS Jit gives the following error:</DIV>
<DIV> </DIV>
<DIV>"An unhandled exception of type 'System.TypeLoadException' occurred =
in=20
Unknown Module."<BR>"Additional information: Method =
ParentInterfaceMethod in=20
type InterfaceImplementer from assembly ParentInterfaceMethod does not =
have an=20
implementation."</DIV>
<DIV> </DIV>
<DIV>.. now this made me suspicious at the mono compiler since the same =
source=20
compiled<BR>with the MS C# compiler and ran on both Jit's (Mono & MS =
jit)</DIV>
<DIV> </DIV>
<DIV>So I got a little curios.</DIV>
<DIV> </DIV>
<DIV>The first thing I did was to decompile the source of both=20
compiles<BR>executables with the help of salamander (<A=20
href=3D"http://www.remotesoft.com/salamander/index.html">http://www.remot=
esoft.com/salamander/index.html</A>)</DIV>
<DIV> </DIV>
<DIV>The only difference are these lines when decompiles.</DIV>
<DIV> </DIV>
<DIV><BR>The MS Decompiled version:</DIV>
<DIV> </DIV>
<DIV> public sealed virtual void MethodToImplement()<BR> =20
{<BR> Console.WriteLine("MethodToImplement()=20
called.");<BR> }</DIV>
<DIV> </DIV>
<DIV> public sealed virtual void ParentInterfaceMethod()<BR> =
{<BR> Console.WriteLine("ParentInterfaceMethod()=20
called.");<BR> }</DIV>
<DIV> </DIV>
<DIV><BR>The Mono Decompiled version:</DIV>
<DIV> </DIV>
<DIV> public virtual void MethodToImplement()<BR> =20
{<BR> Console.WriteLine("MethodToImplement()=20
called.");<BR> }</DIV>
<DIV> </DIV>
<DIV> public void ParentInterfaceMethod()<BR> =20
{<BR> Console.WriteLine("ParentInterfaceMethod()=20
called.");<BR> }</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>Now looking at both versions of the decompiled code =
the<BR>difference is=20
pretty obvious.. </DIV>
<DIV> </DIV>
<DIV>but that might not tell the whole story so I also attached<BR>a=20
disassembled il bytecode of both executables.<BR>I used ildasm to =
disassemble=20
them.</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>The rest is up to you guys.. =3D)</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>keep up the good work.</DIV>
<DIV>regards<BR>//iman</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV></FONT> </DIV></FONT></DIV></BODY></HTML>
------=_NextPart_001_000B_01C2220A.8B7FC8A0--
------=_NextPart_000_000A_01C2220A.8B7FC8A0
Content-Type: application/octet-stream;
name="test_ms.il"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="test_ms.il"
=EF=BB=BF
// Microsoft (R) .NET Framework IL Disassembler. Version 1.0.3705.0
// Copyright (C) Microsoft Corporation 1998-2001. All rights reserved.
.assembly extern mscorlib
{
.publickeytoken =3D (B7 7A 5C 56 19 34 E0 89 ) =
// .z\V.4..
.ver 1:0:3300:0
}
.assembly test
{
// --- The following custom attribute is added automatically, do not =
uncomment -------
// .custom instance void =
[mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(bool,
// =
bool) =3D ( 01 00 00 01 00 00 )=20
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module test.exe
// MVID: {AB557AB3-F6F9-473B-BB43-CB02DA0633F9}
.imagebase 0x00400000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
// Image base: 0x02de0000
//
// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D CLASS STRUCTURE =
DECLARATION =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
//
.class interface private abstract auto ansi IParentInterface
{
} // end of class IParentInterface
.class interface private abstract auto ansi IMyInterface
implements IParentInterface
{
} // end of class IMyInterface
.class private auto ansi beforefieldinit InterfaceImplementer
extends [mscorlib]System.Object
implements IMyInterface,
IParentInterface
{
} // end of class InterfaceImplementer
// =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D GLOBAL FIELDS AND =
METHODS =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D CLASS MEMBERS =
DECLARATION =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// note that class flags, 'extends' and 'implements' clauses
// are provided here for information only
.class interface private abstract auto ansi IParentInterface
{
.method public hidebysig newslot virtual abstract=20
instance void ParentInterfaceMethod() cil managed
{
} // end of method IParentInterface::ParentInterfaceMethod
} // end of class IParentInterface
.class interface private abstract auto ansi IMyInterface
implements IParentInterface
{
.method public hidebysig newslot virtual abstract=20
instance void MethodToImplement() cil managed
{
} // end of method IMyInterface::MethodToImplement
} // end of class IMyInterface
.class private auto ansi beforefieldinit InterfaceImplementer
extends [mscorlib]System.Object
implements IMyInterface,
IParentInterface
{
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 19 (0x13)
.maxstack 1
.locals init (class InterfaceImplementer V_0)
IL_0000: newobj instance void InterfaceImplementer::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: callvirt instance void =
InterfaceImplementer::MethodToImplement()
IL_000c: ldloc.0
IL_000d: callvirt instance void =
InterfaceImplementer::ParentInterfaceMethod()
IL_0012: ret
} // end of method InterfaceImplementer::Main
.method public hidebysig newslot final virtual=20
instance void MethodToImplement() cil managed
{
// Code size 11 (0xb)
.maxstack 1
IL_0000: ldstr "MethodToImplement() called."
IL_0005: call void =
[mscorlib]System.Console::WriteLine(string)
IL_000a: ret
} // end of method InterfaceImplementer::MethodToImplement
.method public hidebysig newslot final virtual=20
instance void ParentInterfaceMethod() cil managed
{
// Code size 11 (0xb)
.maxstack 1
IL_0000: ldstr "ParentInterfaceMethod() called."
IL_0005: call void =
[mscorlib]System.Console::WriteLine(string)
IL_000a: ret
} // end of method InterfaceImplementer::ParentInterfaceMethod
.method public hidebysig specialname rtspecialname=20
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method InterfaceImplementer::.ctor
} // end of class InterfaceImplementer
// =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
//*********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file C:\temp\test_ms.res
------=_NextPart_000_000A_01C2220A.8B7FC8A0
Content-Type: application/octet-stream;
name="test_mono.il"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="test_mono.il"
=EF=BB=BF
// Microsoft (R) .NET Framework IL Disassembler. Version 1.0.3705.0
// Copyright (C) Microsoft Corporation 1998-2001. All rights reserved.
.assembly extern mscorlib
{
.ver 0:0:0:0
}
.assembly test
{
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module test.exe
// MVID: {A6614643-2AED-4FAE-A671-7B56A375D200}
.imagebase 0x00400000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
// Image base: 0x02de0000
//
// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D CLASS STRUCTURE =
DECLARATION =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
//
.class interface private abstract auto ansi IParentInterface
{
} // end of class IParentInterface
.class interface private abstract auto ansi IMyInterface
implements IParentInterface
{
} // end of class IMyInterface
.class private auto ansi beforefieldinit InterfaceImplementer
extends [mscorlib]System.Object
implements IMyInterface
{
} // end of class InterfaceImplementer
// =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D GLOBAL FIELDS AND =
METHODS =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D CLASS MEMBERS =
DECLARATION =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// note that class flags, 'extends' and 'implements' clauses
// are provided here for information only
.class interface private abstract auto ansi IParentInterface
{
.method public hidebysig newslot virtual abstract=20
instance void ParentInterfaceMethod() cil managed
{
} // end of method IParentInterface::ParentInterfaceMethod
} // end of class IParentInterface
.class interface private abstract auto ansi IMyInterface
implements IParentInterface
{
.method public hidebysig newslot virtual abstract=20
instance void MethodToImplement() cil managed
{
} // end of method IMyInterface::MethodToImplement
} // end of class IMyInterface
.class private auto ansi beforefieldinit InterfaceImplementer
extends [mscorlib]System.Object
implements IMyInterface
{
.method public hidebysig specialname rtspecialname=20
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method InterfaceImplementer::.ctor
.method private static void Main() cil managed
{
.entrypoint
// Code size 19 (0x13)
.maxstack 3
.locals init (class InterfaceImplementer V_0)
IL_0000: newobj instance void InterfaceImplementer::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: callvirt instance void =
InterfaceImplementer::MethodToImplement()
IL_000c: ldloc.0
IL_000d: callvirt instance void =
InterfaceImplementer::ParentInterfaceMethod()
IL_0012: ret
} // end of method InterfaceImplementer::Main
.method public hidebysig newslot virtual=20
instance void MethodToImplement() cil managed
{
// Code size 11 (0xb)
.maxstack 8
IL_0000: ldstr "MethodToImplement() called."
IL_0005: call void =
[mscorlib]System.Console::WriteLine(string)
IL_000a: ret
} // end of method InterfaceImplementer::MethodToImplement
.method public instance void ParentInterfaceMethod() cil managed
{
// Code size 11 (0xb)
.maxstack 8
IL_0000: ldstr "ParentInterfaceMethod() called."
IL_0005: call void =
[mscorlib]System.Console::WriteLine(string)
IL_000a: ret
} // end of method InterfaceImplementer::ParentInterfaceMethod
} // end of class InterfaceImplementer
// =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
//*********** DISASSEMBLY COMPLETE ***********************
------=_NextPart_000_000A_01C2220A.8B7FC8A0--