Forward Declaration of Classes

Forward Declaration of Classes

You can carry out a little experiment with the sample code. Open the source file Simple.il in any text editor and modify it by moving the declaration of the value type CharArray8 in front of the declaration of the field Format:

{      } // End of namespace .class public explicit CharArray8                extends [mscorlib]System.ValueType { .size 8 } .field public static valuetype CharArray8 Format at FormatData

Everything seems to be in order. But when you try to recompile the file, ILAsm compilation fails with the error message Unresolved MemberRef Format’.

Now modify the source file again, this time moving the declaration of value type CharArray8 before the declaration of the namespace Odd.or:

.class public explicit CharArray8                extends [mscorlib]System.ValueType { .size 8 } .namespace Odd.or {     .class public auto ansi Even extends [mscorlib]System.Object {         .field public static int32 val         .method public static void check( ) cil managed {                          ldsflda valuetype CharArray8 Format                      } // End of method     } // End of class } // End of namespace .field public static valuetype CharArray8 Format at FormatData

Now when you save the source code and try to recompile it, everything is back to normal. What’s going on here?

After the first change, when the field Format was being referenced in the ldsflda instruction in the method check, the value type CharArray8 had not been declared yet, so the respective TypeRef was emitted for it, and the signature of the field reference received the TypeRef as its type.

Then the value type CharArray8 was declared, and a new TypeDef was created. After that, when the field Format was actually declared, its type was recognized as a locally declared value type, and the signature of the field definition received the TypeDef as its type. But, no field named Format with a TypeRef as its type was declared anywhere in this module. Hence the reference-to-definition resolution failure.

(This is an inviting moment to criticize the ILAsm compiler’s lack of ability to match the signatures on a pragmatic level, with type analysis and matching the TypeRefs to TypeDefs by full name and resolution scope. Have patience, however.)

After the second change in the source code, the value type CharArray8 was declared first so that all references to it, no matter where they happen, refer to it as TypeDef. A rather obvious solution.

The solution becomes not so obvious when we consider two classes, members of which use each other’s class as type. Which class to declare first? Actually, both of them.

The discussion of class declaration mentioned the class amendment technique, based on the fact that ILAsm allows you to reopen a class scope to declare more class attributes and members. The general solution to the declaration/reference problem is to specify the empty-scope class definitions for all classes first. Following that, you can specify all the classes in full, with their attributes and members, as amendments. The “first wave” of class declarations should carry all class flags, extends clauses, and implements clauses and should include all nested classes (also with empty scopes). All the member declarations should be left for later.

This technique of forward declaration of classes guards against declaration/reference errors and, as a side effect, reduces the metadata size because it is unnecessary to emit redundant TypeRefs for locally defined classes.

(And the answer to the aforementioned criticism of the ILAsm compiler is that the compiler does signature matching in the fastest possible way, without needing more sophisticated and slower methods, as long as you use the class forward declaration. It is possible, however, that the need for the class forward declaration might be eliminated in future versions of the ILAsm compiler.)



Inside Microsoft. NET IL Assembler
Inside Microsoft .NET IL Assembler
ISBN: 0735615470
EAN: 2147483647
Year: 2005
Pages: 147
Authors: SERGE LIDIN

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net