Class Metadata

Class Metadata

From a structural point of view, all five categories of types have identical metadata representations. Thus we can talk about class metadata, or type metadata, in a general sense.

Class metadata is grouped around two distinct concepts: type definition (TypeDef) and type reference (TypeRef). TypeDefs and related metadata describe the types declared in the current module, whereas TypeRefs describe references to types that are declared somewhere else. Because it obviously takes more information to adequately define a type than to refer to one already defined, TypeDefs and related metadata are far more complex than TypeRefs.

When defining a type, you should supply the following information:

  • The name of the type being defined

  • Flags indicating special features the type should have

  • The type from which this type is derived

  • The interfaces this type implements

  • How the loader should lay out this class

  • Whether this type is nested in another type—and if so, in which one

  • Where fields and methods of this type (if any) can be found

When referencing a type, only its name and resolution scope need be specified. The resolution scope indicates where the definition of the referenced type can be found: in this module, in another module of this assembly, or in another assembly. In the case of referencing the nested types, the resolution scope is another TypeRef.

Figure 6-2 shows the metadata tables that engage in type definition and referencing but not the tables related to identification of type members—fields and methods, for example, and their attributes. The arrows denote cross-table referencing by means of metadata tokens. In the following sections, we’ll have a look at all the metadata tables involved.

Figure 6-2 Metadata tables that engage in type definition and referencing.

TypeDef Metadata Table

The TypeDef table is the main table containing type definition information. Each record in this table has six entries:

  • Flags (4-byte unsigned integer)  Binary flags indicating special features of the type. Because the TypeDef flags are numerous and important, this chapter discusses them separately; see “Class Attributes.”

  • Name (offset in the #Strings stream)  The name of the type. This entry must not be empty.

  • Namespace (offset in the #Strings stream)  The namespace of the type. This entry can be empty. The namespace plus the name constitute the full name of the type.

  • Extends (coded token of type TypeDefOrRef)  A token of the type’s parent—that is, of the type from which this type is derived. This entry must be set to 0 for all interfaces and for one class, the type hierarchy root class System.Object. For all other types, this entry should carry a valid reference to the TypeDef or TypeRef table.

  • FieldList (record index [RID] to the Field table)  An index to the Field table, marking the start of the field records belonging to this type.

  • MethodList (RID to the Method table)  An index to the Method table, marking the start of the method records belonging to this type.

TypeRef Metadata Table

The TypeRef metadata table has a much simpler structure than the TypeDef table. Each record in this table has three entries:

  • ResolutionScope (coded token of type ResolutionScope)  An indicator of the location of the type definition. This entry is set to 0 if the referenced type is defined in the current assembly—which IL assembly language (ILAsm) does not allow—or to 1 (the Module token) if the referenced type is defined in the same module. ResolutionScope can be a token referencing the ModuleRef table if the type is defined in another module of the same assembly, a token referencing the AssemblyRef table if the type is defined in another assembly, or a token referencing the TypeRef table if the type is nested in another type. Having TypeRefs for the types defined in the same module does not constitute a metadata error, but it is redundant and should be avoided if possible.

  • Name (offset in the #Strings stream)  The name of the referenced type. This entry must not be empty.

  • Namespace (offset in the #Strings stream)  The namespace of the referenced type. This entry can be empty. The namespace plus the name constitute the full name of the type.

InterfaceImpl Metadata Table

If the defined type implements one or several interfaces, the corresponding TypeDef record is referenced in one or several records of the InterfaceImpl metadata table. This table serves as a lookup table, providing information about “what is implementing what,” and it is ordered by implementing type. The InterfaceImpl table has only two entries in each record:

  • Class (RID to the TypeDef table)  An index to the TypeDef table, indicating the implementing type.

  • Interface (coded token of type TypeDefOrRef)  An indicator of the implemented type, which can reside in either the TypeDef table or the TypeRef table. The implemented type must be marked as an interface.

NestedClass Metadata Table

If the defined type is nested in another type, its TypeDef record is referenced in another lookup table: the NestedClass metadata table. (For more information about nesting, see “Nested Types” later in this chapter.) Like the InterfaceImpl table, the NestedClass table has only two entries per record:

  • NestedClass (RID to the TypeDef table)  An indicator of the nested type (the nestee).

  • EnclosingClass (RID to the TypeDef table)  An indicator of the type in which the current type is nested (the encloser, or nester).

Because types of both entries are RIDs in the TypeDef table, the nestee and the encloser cannot be defined in different modules or assemblies.

ClassLayout Metadata Table

Usually, the loader has its own ideas about how to lay out the type being loaded. Certain types, however, must be laid out in a specific manner, and they carry metadata information regarding these specifics.

The ClassLayout metadata table provides additional information about the packing order and total size of the type. In the section “Value Type as Placeholder” in Chapter 1, for example, when we declared a “placeholder” type without any internal structure, we used such additional information—the total size of the type.

A record in the ClassLayout metadata table has three entries:

  • PackingSize (2-byte unsigned integer)  The alignment factor in bytes. This entry must be set to 0 or to a power of 2, from 1 to 128.

  • ClassSize (4-byte unsigned integer)  The total requested layout size of the type. If the type has instance fields and the summary size of these fields, aligned by PackingSize, is different from ClassSize, the loader allocates the larger of the two sizes for the type.

  • Parent (RID to the TypeDef table)  An index of the type definition record to which this layout belongs. The ClassLayout table should not contain any duplicate records with the same Parent entry value.



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