So, we’re now 3 weeks into GSoC, and I figure I should start blogging about my work.
This post will be about the ILAsm standard (specified in ECMA 335) and the Microsoft implementation. There are several annoying differences and incompatibilities between the two. As part of figuring them out, I’ve been reading Expert .NET 2.0 IL Assembler and the Microsoft-annotated ECMA 335 standard.
The first difference is that MS.NET’s ILAsm does not respect the unsigned modifier on integer types. This means that an unsigned int32 will in effect be treated as an int32 (signed). I’ve chosen to break compatibility with Microsoft and correctly emit an unsigned integer, primarily because I think this is an outright stupid bug. Note that you can still get an unsigned integer by using uint32 with MS.NET. The latter form is preferred, anyway.
Second, MS.NET does not have the platformapi keyword. Instead, you have to use the winapi keyword, which makes your ILAsm source code unportable. In Mono’s ILAsm, we support both, in order to aid portability.
Third, MS.NET allows #line instead of .line for specifying source line information. This seems to be for compatibility reasons. Mono’s ILAsm supports both notations.
Fourth, MS.NET has a bunch of directives that just don’t exist in the standard. Specifically .file alignment, .imagebase, .language, and .namespace. We support all of them, though the first two currently have no actual effect. Note that use of .namespace is considered bad practice.
Fifth, MS.NET’s ILAsm doesn’t use .culture for specifying culture information, but rather .locale. This is directly against the standard, and the assembler won’t even recognize .culture. Mono’s ILAsm supports both notations.
Sixth, the MS.NET ILAsm doesn’t require the .hash directive; if it’s not specified, the hash will automatically be computed.
Seventh, the MS.NET ILAsm allows using “value class” in place of “valuetype” for indicating value types. This is relatively easy to handle, and Mono’s ILAsm does so. It is, however, considered bad notation.
Lastly, the MS.NET ILAsm allows specifying things like calling convention, type attributes, method attributes, field attributes, parameter attributes, and so on using flags(int32) notation. I’m sure this was done for a reason, but it seems like a great way to give developers the opportunity to make their programs unportable or impossible to run at all.
There are a lot of other incompatibilities, but they’re less annoying and easier to work around/implement.
That’s it for the this post. Next time: Implementation details of Mono’s ILAsm.