-
-
Save mletterle/2177221 to your computer and use it in GitHub Desktop.
.assembly Test { } | |
.class public TestClass | |
extends [mscorlib]System.Object | |
{ | |
.method specialname static public void Main() cil managed | |
{ | |
.entrypoint | |
newobj instance void AnotherClass2::.ctor() | |
dup | |
callvirt instance void AnotherClass::Method(class AnotherClass) | |
ret | |
} | |
} | |
.class public AnotherClass | |
extends [mscorlib]System.Object | |
{ | |
.method specialname rtspecialname public instance void .ctor() cil managed | |
{ | |
ldarg.0 | |
call instance void [mscorlib]System.Object::.ctor() | |
ret | |
} | |
.method public void Method(class AnotherClass a) cil managed | |
{ | |
ldarg.1 | |
call instance string AnotherClass::Something() | |
call void [mscorlib]System.Console::WriteLine(string) | |
ret | |
} | |
.method public instance string Something() cil managed | |
{ | |
ldstr "AnotherClass" | |
ret | |
} | |
} | |
.class public AnotherClass2 | |
extends [mscorlib]System.Object | |
{ | |
.method specialname rtspecialname public instance void .ctor() cil managed | |
{ | |
ldarg.0 | |
call instance void [mscorlib]System.Object::.ctor() | |
ret | |
} | |
} | |
Oh yes. It doesn't peverify, of course, but it's quite happy to run. It outputs "AnotherClass". It actually does this on both .NET and Mono, which kind of surprised me. Luckily it does sanely break down if you try to save the result of Something() to an instance field. So there's that...
Then it looks like it's following an approach similar to the second case I wrote above. As long as they can pass the method table, they continue flowing.
Did you generate it by hand, or it's a part of a program you're writing. I'm curious to know what scenario this is representing.
It's written by hand. Kinda stumbled over the fact that the runtime doesn't actually seem to enforce the type correctness of arguments being passed to methods, and just eventually got here.
Yes, in most languages most of the type checking usually occurs in previous steps of compilation before generating the IL code, so for efficiency reasons of compilation, it's not redone. .NET would be the same.
I see your point now. I don't know the specifications of .NET CLR for such a case, but it would make sense if it terminates with error. It could also let it flow and check the method table and then terminate when it can't find the implementation on the object's method table. Did you try to compile it?