IL assembly has no version number of its own: a .il file does not say which edition of the language it is written for. The language moves with three things: the editions of the standard ECMA-335 (the same text is the international standard ISO/IEC 23271), the runtime’s addendum to that standard, which records what .NET did beyond it, and the source of ilasm, which accepts more than either describes. Whether a file written for an older ilasm still assembles with a newer one was not tested, and no word dropped from the keyword table was looked for.
The standard
| Edition | What is known from the text of the sixth edition |
|---|---|
| 1st edition | specified an XML encoding for permission sets, which the sixth edition says implementations should keep supporting (II.22.11) |
| 3rd edition | received Technical Report 89 (TR89), a collection of generic types for inter-language use; the 6th edition took a selection of those types into the standard |
| 5th edition | replaced by the sixth |
| 6th edition (June 2012) | “fully aligned with ISO/IEC 23271:2012”. It adds type forwarders (.class extern forwarder, II.6.8); redefines variance as a core feature, so that dispatch may prefer a match by variance over an exact match (II.12.2); and makes ilasm preserve the left-to-right order of the interfaces of a type header and the top-to-bottom order of the methods in the metadata tables (II.10.2). It revises the rules for assignment compatibility, the verification rules of many instructions and the delegate rules, and brings System.Math and System.Double closer to IEEE 754 |
The dates of the first to fifth editions and the full list of what the second to fifth added are not in the sixth edition’s foreword and were not looked up.
The runtime’s addendum
docs/design/specs/Ecma-335-Augments.md in dotnet/runtime lists additions and corrections to the standard, some documenting new runtime features and some the quirks of the Microsoft implementation. Its sections show where the language grew; the syntax that each needs in IL assembly is in the pages named.
| Section of the addendum | What it covers | In IL assembly |
|---|---|---|
| Signatures | five corrections to how types and custom modifiers may appear in signatures (class or valuetype followed by a type spec, modifiers in more places, byref before modifiers, richer type specs) | Types and signatures |
| Heap sizes, metadata merging, metadata logical format | rules for the metadata streams | not source syntax |
| Module initializer | the type initializer of the <Module> type runs at or before the first access to a static field or the first call of a method of the module, once | a global .cctor: a .method declared outside any class (Classes) |
| Default interface methods | interfaces may have instance methods with a body, and interface methods may implement other interfaces’ methods through final method impls | .override in an interface (Classes) |
| Static interface methods, covariant return types, function pointer type identity | static virtual members of interfaces; overrides that return a more derived type; when two method pointer types are the same | Classes, Types |
| Unsigned data conversion with overflow detection | the conv.ovf.*.un instructions | The instruction set |
| Ref fields, ByRefLike types in generics | fields that hold managed pointers; by-ref-like types as type arguments | byreflike on a generic parameter (Classes) |
Rules for IL rewriters, checked user-defined operators, atomic reads and writes, backward branch constraints, transient pointers, arrays created with newobj | further rules for code that edits IL, the op_Checked… operators, the sizes for which reads and writes are atomic, and so on | The instruction set |
| API documentation, debug interchange format | how the documentation of the class library and the portable debug information relate to the standard | not source syntax |
| Extended layout | the extended layout of value types, set by an ExtendedLayoutAttribute; .pack and .size are not valid on such a type | extended (Classes) |
| Implicit argument coercion rules, init-only static fields | the coercion rules of the stack; changing an init-only static field outside the type initializer can compromise memory integrity and type safety (instance init-only fields are not affected) | Fields and data |
Words and options ilasm has that the sixth edition does not
Read from the keyword table and the grammar of the current ilasm (the dates at which each arrived were not determined):
- class and generic parameter words:
extended,byreflike,windowsruntime,flags(…); - method implementation words:
aggressiveinlining,aggressiveoptimization,async,preservesig,optil; - assembly words:
retargetable,noplatform,legacy library,cil,x86,amd64,arm,arm64; - directives:
.interfaceimpl,.param constraint,.typedef,.language,.namespace, and the preprocessor; - options:
/PE64,/X64,/ARM,/ARM64,/32BITPREFERRED,/APPCONTAINER,/HIGHENTROPYVA,/DET(Tooling).
Not described
Known, not yet covered
- Reference: a table of which .NET version added which word was not built: the git history of
asmparse.yandil_kywd.hwas not read. The 2nd, 4th and 5th editions of the standard were not looked at. The sections of the addendum are named, and only those that were read in detail (the module initializer, default interface methods, extended layout, init-only static fields) are described.