Suppose you have the following Managed C++ class:
__gc class Foo { void foo(int i) {} void foo(long l) {} };
How is this compiled? The problem, of course, is that int and long are both signed 32 bit integers. A type cannot have two methods with exactly the same signature. To solve this problem the CLR has custom modifiers (see Partion II Metadata.doc, section 7.1.1). ILDASM shows the above methods as follows:
[...] void foo(int32 i) [...] [...] void foo(int32 modopt([Microsoft.VisualC]Microsoft.VisualC.IsLongModifier) l) [...]
The long parameter is annotated with the optional modifier Microsoft.VisualC.IsLongModifier. Modifiers are part of the signature, so it is legal to have signatures that differ only by modifier.
Now, suppose IKVM.NET is compiling the following Java class:
class Foo { Bar foo(Bar o) {} Baz foo(Baz o) {} }
Also suppose that Bar and Baz are not yet available when the class is compiled. For the types that are not available, java.lang.Object is substituted, so now we again have two methods with the same signature. It would have been nice to use a custom modifier to resolve this, but this isn't possible for two reasons:
- custom modifiers are not supported by Reflection.Emit (in .NET 1.0 and 1.1)
- custom modifiers do not accept any arguments, only a type (it would be possible to generate a type for each modifier, but that would hardly be an elegant solution)
The solution is to use method name mangling. The next problem is that we need a place to store the name of the class that the arguments and return value actually are. The most obvious way to do this is custom attributes. Method arguments (parameters) can be annotated with custom attributes using MethodBuilder.DefineParameter(...). Parameters are indexed starting at one, this (and the ilasm syntax) suggests that zero refers to the return type, unfortunately DefineParameter throws an exception when it is called with zero. This bug also exists in both .NET 1.0 and 1.1. Again the work around is easy, just emit a method attribute and put the real return type class in there.
12:02:32 PM Comments
|