Пример #1
0
 // elementType is FNPTR
 internal Type(ElementTypes elementType,
               SignatureMethod methodSignature)
 {
     this.elementType     = elementType;
     this.methodSignature = methodSignature;
 }
Пример #2
0
        private Type parseSignatureType(MetaDataLoader mdLoader)
        {
            ElementTypes elementType = (ElementTypes)this.buffer[this.offset];

            this.offset++;
            switch (elementType)
            {
            case ElementTypes.VOID:
            case ElementTypes.BOOLEAN:
            case ElementTypes.CHAR:
            case ElementTypes.I1:
            case ElementTypes.U1:
            case ElementTypes.I2:
            case ElementTypes.U2:
            case ElementTypes.I4:
            case ElementTypes.U4:
            case ElementTypes.I8:
            case ElementTypes.U8:
            case ElementTypes.R4:
            case ElementTypes.R8:
            case ElementTypes.U:
            case ElementTypes.I:
            case ElementTypes.OBJECT:
            case ElementTypes.STRING:
            case ElementTypes.TYPEDBYREF: {
                return(new Type(elementType));
            }

            case ElementTypes.VALUETYPE:
            case ElementTypes.CLASS: {
                // Followed by: TypeDefOrRefEncoded
                MetaDataObject classObject = uncompressToken(mdLoader);
                return(new Type(elementType, classObject));
            }

            case ElementTypes.SZARRAY: {
                // Followed by: CustomMod* Type
                Modifier modifierList = this.parseSignatureModifiers(mdLoader);
                Type     type         = this.parseSignatureType(mdLoader);
                return(new Type(elementType, type, modifierList));
            }

            case ElementTypes.ARRAY: {
                // Followed by: Type ArrayShape
                Type type = this.parseSignatureType(mdLoader);
                uint rank = uncompressInt(this.buffer, ref this.offset);
                if (rank == 0)
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("ARRAY with rank 0");
                }
                uint[] upperBounds    = new uint[rank];
                uint[] lowerBounds    = new uint[rank];
                uint   numUpperBounds =
                    uncompressInt(this.buffer, ref this.offset);
                if (numUpperBounds > rank)
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("ARRAY with upper bounds > rank");
                }
                for (int i = 0; i < numUpperBounds; i++)
                {
                    upperBounds[i] =
                        uncompressInt(this.buffer, ref this.offset);
                }
                uint numLowerBounds =
                    uncompressInt(this.buffer, ref this.offset);
                if (numLowerBounds > rank)
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("ARRAY with lower bounds > rank");
                }
                for (int i = 0; i < numLowerBounds; i++)
                {
                    lowerBounds[i] =
                        uncompressInt(this.buffer, ref this.offset);
                }
                return(new Type(elementType, type, lowerBounds, upperBounds));
            }

            case ElementTypes.FNPTR: {
                // Followed by: MethodDefSig or MethodRefSig
                uint unmaskedCallingConvention =
                    uncompressInt(this.buffer, ref this.offset);
                CallingConventions callingConvention = (CallingConventions)
                                                       (unmaskedCallingConvention
                                                        & (uint)CallingConventions.Mask);
                if (callingConvention == CallingConventions.Field ||
                    callingConvention == CallingConventions.LocalVar ||
                    callingConvention == CallingConventions.Property)
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("FNPTR surprised by calling convention " + callingConvention);
                }
                if ((unmaskedCallingConvention
                     & (uint)CallingConventions.Generic) != 0)
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("FNPTR generic unimplemented - check to see if legal");
                }
                uint    paramCount       = uncompressInt(this.buffer, ref this.offset);
                Type    returnType       = this.parseSignatureType(mdLoader);
                int     sentinelLocation = -1;
                Param[] parameters       = new Param[paramCount];
                for (int i = 0; i < paramCount; i++)
                {
                    byte first = this.buffer[this.offset];
                    if (first == (byte)ElementTypes.SENTINEL)
                    {
                        sentinelLocation = i;
                        this.offset++;
                    }
                    parameters[i] = this.parseSignatureParam(mdLoader);
                }
                SignatureMethod signature =
                    new SignatureMethod(callingConvention, 0, returnType,
                                        parameters, sentinelLocation);
                return(new Type(elementType, signature));
            }

            case ElementTypes.VAR:
            case ElementTypes.MVAR: {
                // Generic type variables
                uint number = uncompressInt(this.buffer, ref this.offset);
                return(new Type(elementType, number));
            }

            case ElementTypes.GENERICINST: {
                // Generic type instantiation
                Type   type       = this.parseSignatureType(mdLoader);
                uint   typeCount  = uncompressInt(this.buffer, ref this.offset);
                Type[] typeParams = new Type[typeCount];
                for (int i = 0; i < typeCount; i++)
                {
                    Type paramType = this.parseSignatureType(mdLoader);
                    typeParams[i] = paramType;
                }

                return(new Type(elementType, type, typeParams));
            }

            case ElementTypes.CMOD_OPT:
            case ElementTypes.CMOD_REQD: {
                // Modifiers
                this.offset--;
                Modifier modifierList = this.parseSignatureModifiers(mdLoader);
                Type     type         = this.parseSignatureType(mdLoader);
                return(new Type(elementType, type, modifierList));
            }

            case ElementTypes.PINNED:
            case ElementTypes.PTR:
            case ElementTypes.BYREF: {
                // Modifiers
                Type type = this.parseSignatureType(mdLoader);
                return(new Type(elementType, type, (Modifier)null));
            }

            default: {
                throw new MetaDataLoader.IllegalMetaDataFormatException("Unknown signature type: 0x" + ((byte)elementType).ToString("x2") + " at " + this.offset + " in " + this);
            }
            }
        }