Global Fields

Global Fields

Fields declared outside the scope of any class are known as global fields. They don’t belong to a class but instead belong to the module in which they are declared. Because a module is represented by a special TypeDef record under the name <Module>, all the formalities that govern how field records are identified by reference from their parent TypeDef records are observed.

Global fields must be static. Since only one instance of the module exists when the assembly is loaded, and because it is impossible to create alternative instances of the module, this limitation seems obvious.

Global fields can have public, private, or privatescope accessibility flags—at least that’s what the metadata validity rules say. As we saw in Chapter 1, however, a global item (a field or a method) can have any accessibility flag, and the loader interprets this flag only as assembly, private, or privatescope. The public, assembly, and famorassem flags are all interpreted as assembly, while the family, famandassem, and private flags are all interpreted as private. The global fields cannot be accessed from outside the assembly, so they don’t have true public accessibility. And because no type can be derived from <Module>, the question about family-related accessibility is moot.

Global fields can be accessed from anywhere within the module, regardless of their declared accessibility. In this regard, the classes that are declared within a module and use the global fields have the same access rights as if they were nested in the module. The metadata contains no indications of such nesting, of course.

A reference to a global field declared in the same module has no <class_ref>:: part:

<global_field_ref> ::= [field<field_type> <field_name>

The keyword field is used in particular cases when the nature of the reference cannot be inferred from the context.

A reference to a global field declared in a different module of the assembly also lacks the class name but has resolution scope:

<global_field_ref> ::= [field] [.module <mod_name>]::<field_name>

The following are two examples of such declarations:

ldsfld int32 globalInt ldtoken field int32 [.module supporting.dll]::globalInt

Since the global fields are static, we cannot explicitly specify their layout except by mapping them to data. Thus our 4-2-1-byte union MultiDword would look like this if we implemented it with global fields:

.field public static unsigned int32 dw at D_00 .field public static unsigned int16 w1 at D_00 .field public static unsigned int16 w2 at D_02 .field public static unsigned int8 b1 at D_00 .field public static unsigned int8 b2 at D_01 .field public static unsigned int8 b3 at D_02 .field public static unsigned int8 b4 at D_03 .data D_00 = int8(0) .data D_01 = int8(0) .data D_02 = int8(0) .data D_03 = int8(0)  ldc.i1.1 stsfld unsigned int8 b3 // Set value of third byte

Fortunately, we don’t have to do that every time we need a global union. Instead, we can declare the value type MultiDword exactly as before and then declare a global field of this type:

.field public static valuetype MultiDword multi_dword  ldc.i1.1 ldsflda valuetype MultiDword multi_dword  // Load reference to the field // As instance of MultiDword stfld unsigned int8 MultiDword::b3 // Set value of third byte



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