=head1 PMCs This document details the PMCs (Parrot Magic Cookies) that are used to read in .NET assemblies and provide access to the data held in them from PIR. =head2 DotNetAssembly This PMC represents an entire .NET CLI EXE or DLL file. It handles loading of a .NET assembly and instantiates all other PMCs that relate to the assembly. It also provides access to some of the global data =head3 Synopsis # Load an .NET CLI DLL or EXE file. $P1 = new .DotNetAssembly $P1 = "Example.dll" $P1.load() # Get name of loaded file. $S1 = $P1 # Is it a DLL? $I1 = $P1.is_dll() if $I1 = 0 goto EXE print "This is a DLL\n" goto CONTINUE EXE: print "This is an EXE file\n" CONTINUE: # Get an array of classes. $P2 = $P1.get_classes() # Get the globals pseudo-class. $P3 = $P1.get_global() =head3 Vtable Methods =head4 set_string_native Sets the filename of the .NET assembly to be loaded. =head4 get_string Gets the filename of the .NET assembly that is loaded or to be loaded. =head3 Additional Methods With the exception of load, all of these methods should only be called when after the load method. =head4 void load() Attempts to load the .NET assembly whose filenmae is stored in the string representation of the PMC. =head4 INTVAL is_dll() Returns a non-zero integer if the file is a DLL and zero otherwise. =head4 STRING* get_internal_string(INTVAL i) Gets the string with at the position identifier i from the strings heap. This is the string heap that is used for internal identifiers and are UTF-8 encoded. =head4 STRING* get_user_string(INTVAL i) Gets the string at position i from the user strings heap. This is the string heap that is used for strings that make up various bits of user data. Strings on the user heap are encoded as 16-bit unicode. =head4 STRING* get_blob(INTVAL i) Gets the blob at position i from the blobs heap. A blob is a lump of binary data; Parrot strings can handle these fine, though. =head4 PMC* get_classes() Returns a PMC array of classes that are defined by the assembly. Each element of the PMC array will be a DotNetClassMetadata PMC. =head4 PMC* get_class_order() Returns an integer array specifying indexes into the PMC array of classes as returned by the get_classes method. This array provides an ordering that ensures parent types come before their children. =head4 PMC* get_global() Returns a DotNetClassMetadata PMC representing the global pseudoclass. The fields and methods of this class are global variables/subs. =head4 PMC* get_field(INTVAL i) Returns a DotNetFieldMetadata PMC representing the field at the given row of the Field metadata table. =head4 PMC* get_method(INTVAL i) Returns a DotNetMethodMetadata PMC representing the method at the given row of the MethodDef metadata table. =head4 PMC* get_typerefs() Returns a PMC array of DotNetTypeRefMetadata PMCs, each one representing a type from an external module or assembly. =head4 PMC* get_memberrefs() Returns a PMC array of DotNetMemberRefMetadata PMCs, each one representing a field or method (aka member) from an external module or assembly. =head2 DotNetClassMetadata This PMC represents the metadata associated with a particular class. =head3 Synopsis # Imagining $P2 is an array of DotNetClassMetadata PMCs... $P3 = $P2[0] # Get name and namespace. $S1 = $P3 $S2 = $P3.get_namespace() # Get flags bit vector $I1 = $P3.get_flags() # Get fields and methods. $P4 = $P3.get_fields() $P5 = $P3.get_methods() =head3 Vtable methods =head4 get_string Gets the name of the class. =head3 Additional methods =head4 get_namespace Returns a string that is the namespace the class is in. =head4 get_flags Returns a bit vector of flags set on the method. For details of what the flags mean, see Partition II Clause 22.1.4 of the .NET Specification. =head4 PMC* get_fields() Returns a PMC array of fields belonging to this class. Each element of the PMC array will be a DotNetFieldMetadata PMC. =head4 PMC* get_methods() Returns a PMC array of methods belonging to this class. Each element of the PMC array will be a DotNetMethodMetadata PMC. =head4 get_parent_id() Returns the ID of the parent class. =head4 get_parent_type() Returns the type of the parent class ID - that is, whether it is a type in the current assembly or in another one. =head4 get_interface_ids() Returns an integer array PMC containing the IDs of the interfaces that the type implements. =head4 get_interface_types() Returns an integer array PMC containing the type of each of the IDs that was returned by get_interface_ids. =head2 DotNetMethodMetadata This PMC represents the metadata associated with a particular method. Note that some additional metadata about a method is stored in a seperate header preceding the instruction stream itself. This data is not accessible through this PMC; the DotNetBytecode PMC provides access to that. =head3 Synopsis # Imagine $P1 contains an array of DotNetMethodMetadata PMCs... $P2 = $P1[0] # Get the name of the method. $S1 = $P2 # Get the position of the blob holding a signature for the method. $I0 = $P2.get_signature() # Get flags bit vector $I1 = $P2.get_flags() # Get the method implementation (a DotNetBytecode PMC). $P4 = $P2.get_bytecode() # Get parameters (an array of DotNetParamMetadata PMCs). $P5 = $P2.get_params() =head3 Vtable methods =head4 get_string Gets the name of the method. =head3 Additional methods =head4 get_signature Returns an integer specifying the position in the blobs heap of the signature for the method. =head4 get_flags Returns a bit vector of flags set on the method. For details of what the flags mean, see Partition II Clause 22.1.9 of the .NET Specification. =head4 get_bytecode Returns a DotNetBytecode PMC that allows the bytecode that specifies the method body to be walked over easily. =head4 get_params Returns a PMC array of DotNetParamMetadata PMCs, one describing each of the parameters of the method. =head2 DotNetFieldMetadata This PMC represents the metadata associated with a particular field. =head3 Synopsis # Imagine $P1 contains an array of DotNetFieldMetadata PMCs... $P2 = $P1[0] # Get the name of the field. $S1 = $P2 # Get the position of the blob holding a signature for the field. $I0 = $P2.get_signature() # Get flags bit vector $I1 = $P2.get_flags() =head3 Vtable Methods =head4 get_string Gets the name of the field. =head3 Additional Methods =head4 get_signature Returns an integer specifying the position in the blobs heap of the signature for the field. =head4 get_flags Returns a bit vector of flags set on the field. For details of what the flags mean, see Partition II Clause 22.1.5 of the .NET Specification. =head3 TODO No handling of fields with some RVAs. =head2 DotNetParamMetadata This PMC represents a parameter of a method. =head3 Synopsis # Imagine $P1 contains an array of DotNetParamMetadata PMCs... $P2 = $P1[0] # Get the name of the parameter. $S1 = $P2 # Get flags for the parameter. $I0 = $P2.get_flags() # Get sequence number. $I1 = $P2.get_sequence() =head3 Vtable Methods =head4 get_string Gets the name of the parameter. =head3 Additional Methods =head4 get_flags Returns a bit vector of flags set on the parameter. For details of what the flags mean, see Partition II Clause 22.1.12 of the .NET Specification. =head4 get_sequence Returns an integer specifying the sequence number of the parameter. This is the position of the parameter. Sequence number 0 corresponds to the return value rather than a parameter. Sequence numbers should then increase, according to the .NET specification, however gaps are allowed. Quite what a gap in the sequence would imply is unclear, however. =head2 DotNetSignature Signatures in .NET are represented as binary blobs of data. This PMC, one assigned a string representing a blob, provides some assistance to programs walking signatures, hiding away the compression scheme. This PMC does not understand the structure of different types of signature. =head3 Synopsis $P0 = new DotNetSignature $S0 = assembly.get_blob(blob_position) $P0 = $S0 type = $P0.read_byte() # etc =head3 Vtable Methods =head4 set_string_native Assigns a string containing the concents of the signature blob. This must be done before any other operations are performed or an exception will be thrown. Doing this also resets the current internal position pointer to zero. =head3 Additional Methods =head4 read_uint8 Reads 1 unsigned byte of data. Updates the internal current position pointer. =head4 read_compressed Reads a compressed integer, compressed according to the method described in Partition II Section 22.2 of the .NET specification. Updates the current internal position pointer. =head2 DotNetBytecode This PMC provides useful methods for walking .NET CLI instruction streams and accessing data in the metadata encoded within the instruction stream, rather than the main metadata tables. =head3 Synopsis $P0.set_pos(0) $I0 = $P0.read_uint8() $N0 = $P0.read_float32() $I1 = $P0.get_pos() # $I1 will contain 5 =head3 Vtable Methods None. =head3 Additional Methods =head4 get_locals_sig Returns an integer specifying the position in the blobs heap of the signature for the local variables of the method. =head4 init_locals Returns an integer that is 0 if the initialize locals flag is set for the method and a non-zero value if it is. =head4 get_eh Returns a PMC array of DotNetEH (.NET exception handdler info) PMCs. =head4 get_pos Returns an integer value specifying the current offset into the instruction stream that is being held. This position is changed when any of the read_* methods are called. =head4 set_pos Sets the current offset into the instruction stream that is being held. =head4 read_int8 Reads a signed 8-bit integer and returns it as a native sized integer. Increments the current read position by 1 byte. =head4 read_uint8 Reads an unsigned 8-bit integer and returns it as a native sized integer. Increments the current read position by 1 byte. =head4 read_int16 Reads a signed 16-bit integer and returns it as a native sized integer. Increments the current read position by 2 bytes. =head4 read_uint16 Reads an unsigned 16-bit integer and returns it as a native sized integer. Increments the current read position by 2 bytes. =head4 read_int32 Reads a signed 32-bit integer and returns it as a native sized integer. Increments the current read position by 4 bytes. =head4 read_uint32 Reads an unsigned 32-bit integer and returns it as a native sized integer. Increments the current read position by 4 bytes. =head4 read_float32 Reads a 32-bit (single precision) float and returns it as the native sized floating point number type used for Parrot's N registers. Increments the current read position by 4 bytes. =head4 read_float64 Reads a 64-bit (single precision) float and returns it as the native sized floating point number type used for Parrot's N registers. Increments the current read position by 8 bytes. =head3 TODO Subtle issues relating to 32-bit unsigned integers and I registers, 64-bit integers. =head2 DotNetTypeRefMetadata This PMC represents the metadata associated with a type in an external module. =head3 Synopsis # Imagining $P2 is an array of DotNetTypeRefMetadata PMCs... $P3 = $P2[0] # Get name and namespace. $S1 = $P3 $S2 = $P3.get_namespace() # Get resolution scope. $I1 = $P3.get_resolution_scope() =head3 Vtable methods =head4 get_string Gets the name of the class. =head3 Additional methods =head4 get_namespace Returns a string that is the namespace the class is in. =head4 get_resolution_scope Returns an integer that defines the module or assembly containing the implementation of the type. =head2 DotNetMemberRefMetadata XXX TO DO =head2 DotNetEH XXX TO DO