internal void AddGenericParamConstraint(MetaDataObject constraint)
 {
     if (this.genericParamConstraints == null)
     {
         this.genericParamConstraints = new ArrayList(2);
     }
     this.genericParamConstraints.Add(constraint);
 }
        // Constructor Methods

        internal MetaDataCustomAttribute(int parentIndex,
                                         MetaDataObject type,
                                         byte[] buffer)
        {
            this.parentIndex = parentIndex;
            this.type        = type;
            this.buffer      = buffer;
        }
Exemple #3
0
            // Constructor Methods

            internal Modifier(ElementTypes kind,
                              MetaDataObject type,
                              Modifier next)
            {
                this.kind = kind;
                this.type = type;
                this.next = next;
            }
        // Constructor Methods

        internal EHClause(int flags, int tryOffset, int tryLength,
                          int handlerOffset, int handlerLength,
                          int filterOffset, MetaDataObject classObject)
        {
            this.flags         = (ExceptionFlag)flags;
            this.tryOffset     = tryOffset;
            this.tryEnd        = tryOffset + tryLength;
            this.handlerOffset = handlerOffset;
            this.handlerEnd    = handlerOffset + handlerLength;
            this.filterOffset  = filterOffset;
            this.classObject   = classObject;
        }
        private static MetaDataObject ResolveTypeRef(MetaDataResolver resolver,
                                                     MetaDataResolver[] resolvers,
                                                     MetaDataTypeReference typeRef)
        {
            MetaDataObject result = resolver.ResolveTypeRef(typeRef);
            int            i      = 0;

            while (result == null && i < resolvers.Length)
            {
                MetaDataResolver testResolver = resolvers[i];
                i++;
                if (testResolver != resolver)
                {
                    result = testResolver.ResolveTypeRef(typeRef);
                }
            }
            return(result);
        }
Exemple #6
0
        private Modifier parseSignatureModifiers(MetaDataLoader mdLoader)
        {
            Modifier     result = null;
            ElementTypes mod    = (ElementTypes)this.buffer[this.offset];

            while (mod == ElementTypes.CMOD_REQD ||
                   mod == ElementTypes.CMOD_OPT)
            {
                this.offset++;
                uint typeEncoded = uncompressInt(this.buffer, ref this.offset);
                // BUGBUG: type conversion on int.
                MetaDataObject type = mdLoader.getTypeDefOrRef((int)typeEncoded);
                result = new Modifier(mod, type, result);
                if (this.offset < this.buffer.Length)
                {
                    mod = (ElementTypes)this.buffer[this.offset];
                }
                else
                {
                    mod = ElementTypes.VOID;
                }
            }
            return(result);
        }
        // Helper Methods

        private int getFieldSize(Signature.Type fieldType)
        {
            switch (fieldType.ElementType)
            {
            case ElementTypes.VOID:
                return(0);

            case ElementTypes.BOOLEAN:
            case ElementTypes.I1:
            case ElementTypes.U1:
                return(1);

            case ElementTypes.CHAR:
            case ElementTypes.I2:
            case ElementTypes.U2:
                return(2);

            case ElementTypes.I4:
            case ElementTypes.U4:
            case ElementTypes.R4:
                return(4);

            case ElementTypes.I8:
            case ElementTypes.U8:
            case ElementTypes.R8:
                return(8);

            case ElementTypes.OBJECT:
            case ElementTypes.STRING:
            case ElementTypes.FNPTR:
            case ElementTypes.CLASS:
            case ElementTypes.PTR:
            case ElementTypes.BYREF:
            case ElementTypes.U:
            case ElementTypes.I:
                return(machineIntSize);

            case ElementTypes.TYPEDBYREF:
                return(2 * machineIntSize);

            case ElementTypes.VALUETYPE: {
                MetaDataObject classObject = fieldType.ClassObject;
                if (!(classObject is MetaDataTypeDefinition))
                {
                    return(-1);
                }
                MetaDataTypeDefinition typedef = (MetaDataTypeDefinition)classObject;
                if ((typedef.Flags & TypeAttributes.Interface) != 0 ||
                    (typedef.Flags & TypeAttributes.Abstract) != 0)
                {
                    return(-1);
                }
                int classSize = 0;
                int packSize  = 0;
                if (typedef.ClassLayout != null)
                {
                    classSize = typedef.ClassLayout.ClassSize;
                    packSize  = typedef.ClassLayout.PackingSize;
                }
                int instanceFieldSize = 0;
                if ((typedef.Flags & TypeAttributes.ExplicitLayout) != 0)
                {
                    foreach (MetaDataField mdField in typedef.Fields)
                    {
                        if ((mdField.Flags & (int)MetaDataField.FieldAttributes.Static) == 0)
                        {
                            Signature.Type nestedFieldType =
                                ((SignatureField)mdField.Signature).FieldType;
                            int fieldSize = this.getFieldSize(nestedFieldType);
                            int offset    = mdField.Layout.Offset;
                            int fieldEnd  = fieldSize + offset;
                            if (fieldEnd > instanceFieldSize)
                            {
                                instanceFieldSize = fieldEnd;
                            }
                        }
                    }
                }
                else
                {
                    foreach (MetaDataField mdField in typedef.Fields)
                    {
                        if ((mdField.Flags & (int)MetaDataField.FieldAttributes.Static) == 0)
                        {
                            Signature.Type nestedFieldType =
                                ((SignatureField)mdField.Signature).FieldType;
                            int fieldSize = this.getFieldSize(nestedFieldType);
                            if (fieldSize == -1)
                            {
                                return(-1);
                            }
                            if (packSize > 1)
                            {
                                int delta = instanceFieldSize % packSize;
                                if (delta > 0)
                                {
                                    instanceFieldSize += packSize - delta;
                                }
                            }
                            instanceFieldSize += fieldSize;
                        }
                    }
                }
                if (instanceFieldSize > classSize)
                {
                    return(instanceFieldSize);
                }
                else if (classSize > 0)
                {
                    return(classSize);
                }
                else
                {
                    return(1);
                }
            }

            case ElementTypes.ARRAY: {
                int    elementCount = 1;
                uint[] lowerBounds  = fieldType.LowerBounds;
                uint[] upperBounds  = fieldType.UpperBounds;
                int    rank         = upperBounds.Length;
                for (int i = 0; i < rank; i++)
                {
                    int dimSize = (int)(upperBounds[i] - lowerBounds[i]);
                    if (dimSize == 0)
                    {
                        // Must be an array of pointers to other arrays
                        return(elementCount * machineIntSize);
                    }
                    else
                    {
                        elementCount *= dimSize;
                    }
                }
                int elementSize = this.getFieldSize(fieldType.TypeObject);
                return(elementCount * elementSize);
            }

            case ElementTypes.CMOD_REQD:
            case ElementTypes.CMOD_OPT:
                return(this.getFieldSize(fieldType.TypeObject));

            case ElementTypes.PINNED:
                return(this.getFieldSize(fieldType.TypeObject));

            case ElementTypes.SZARRAY:
                // Should be machine dependent!
                return(4);

            case ElementTypes.SENTINEL:
            case ElementTypes.END:
            default:
                return(-1);
            }
        }
        // Resolve all the custom attributes found in the assemblies registered
        // in 'resolver', using all the type information found in 'resolver' and
        // 'resolvers'.
        internal void resolveReferences(MetaDataResolver resolver,
                                        MetaDataResolver[] resolvers)
        {
            if (this.buffer[0] != 0x01 || this.buffer[1] != 0x00)
            {
                throw new MetaDataLoader.IllegalMetaDataFormatException("Custom Attribute doesn't start with 0x0001!");
            }
            SignatureMethod signature;

            if (this.type is MetaDataMethod)
            {
                MetaDataMethod method = (MetaDataMethod)this.type;
                signature = (SignatureMethod)method.Signature;
                if (!method.Name.Equals(".ctor"))
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("Custom attribute with unexpected method name: " + method.Name);
                }
                this.typeDefOrRef = method.Parent;
                this.name         = method.Parent.FullName;
            }
            else if (this.type is MetaDataMemberRef)
            {
                MetaDataMemberRef memberRef = (MetaDataMemberRef)this.type;
                signature = (SignatureMethod)memberRef.Signature;
                if (!memberRef.Name.Equals(".ctor"))
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("Custom attribute with unexpected memberRef name: " + memberRef.Name);
                }
                MetaDataObject methodParent = memberRef.Class;
                this.typeDefOrRef = methodParent;
                if (methodParent is MetaDataTypeDefinition)
                {
                    this.name = ((MetaDataTypeDefinition)methodParent).FullName;
                }
                else if (methodParent is MetaDataTypeReference)
                {
                    this.name = ((MetaDataTypeReference)methodParent).FullName;
                }
                else
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("Custom attribute with unexpected class type: " + methodParent);
                }
            }
            else
            {
                throw new MetaDataLoader.IllegalMetaDataFormatException("Custom attribute with unexpected type: " + this.type);
            }
            Signature.Param[] parameters = signature.Parameters;
            int fixedCount = parameters.Length;

            this.fixedArgs = new Object[fixedCount];
            MemoryStream stream =
                new MemoryStream(this.buffer, 2, this.buffer.Length - 2, false);
            BinaryReader reader = new BinaryReader(stream);

            for (int i = 0; i < fixedCount; i++)
            {
                Signature.Param parameter = parameters[i];
                Signature.Type  paramType = parameter.Type;
                Object          value     =
                    ExtractParameter(paramType, reader, resolver, resolvers);
                fixedArgs[i] = value;
            }
            short namedCount = ((reader.PeekChar() == -1) ?
                                (short)0 :
                                reader.ReadInt16());

            if (namedCount > this.buffer.Length &&
                this.Name.Equals("System.Runtime.CompilerServices.RequiredAttributeAttribute"))
            {
                // Some CLR libraries have been compiled against a version of
                // mscorlib that had a fixed parameter to RequiredAttribute.
                // Simply ignore whatever the parameter was!
                namedCount = 0;
            }
            this.namedArgs = new NamedArg[namedCount];
            for (int i = 0; i < namedCount; i++)
            {
                SerializationTypes propOrField = (SerializationTypes)
                                                 reader.ReadByte();
                ElementTypes fieldType = (ElementTypes)reader.ReadByte();
                ElementTypes arrayType = ElementTypes.END;
                switch (fieldType)
                {
                case ElementTypes.SZARRAY: {
                    arrayType = (ElementTypes)reader.ReadByte();
                    if (arrayType == (ElementTypes)SerializationTypes.ENUM)
                    {
                        throw new Exception("Not implemented: Array of ENUM " +
                                            "for named field/property");
                    }
                    break;
                }

                case (ElementTypes)SerializationTypes.ENUM: {
                    String enumName = ExtractString(reader);
                    if (enumName.Length == 0)
                    {
                        throw new Exception("Empty enum name");
                    }
                    // Hope it is a 4-byte enum
                    fieldType = (ElementTypes)SerializationTypes.U4;
                    break;
                }

                case (ElementTypes)SerializationTypes.TAGGED_OBJECT: {
                    throw new Exception("Not implemented: " + fieldType +
                                        " for named field/property");
                }

                default: {
                    break;
                }
                }
                String name = ExtractString(reader);
                Object value;
                if (fieldType == ElementTypes.SZARRAY)
                {
                    value = ExtractArrayValue(arrayType, reader);
                }
                else
                {
                    value = ExtractValue(fieldType, reader);
                }
                if (propOrField == SerializationTypes.FIELD ||
                    propOrField == SerializationTypes.PROPERTY)
                {
                    this.namedArgs[i] =
                        new NamedArg(propOrField == SerializationTypes.FIELD,
                                     -1, name, value);
                }
                else
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("Unknown prop-or-field type: " + propOrField);
                }
            }
        }
        private static Object ExtractParameter(Signature.Type type,
                                               BinaryReader reader,
                                               MetaDataResolver resolver,
                                               MetaDataResolver[] resolvers)
        {
            switch (type.ElementType)
            {
            case ElementTypes.VALUETYPE: {
                MetaDataObject classObject = type.ClassObject;
                if (classObject is MetaDataTypeReference)
                {
                    MetaDataTypeReference classReference =
                        (MetaDataTypeReference)classObject;
                    MetaDataObject resolvedObject =
                        ResolveTypeRef(resolver, resolvers, classReference);
                    if (resolvedObject is MetaDataTypeDefinition)
                    {
                        classObject = resolvedObject;
                    }
                }
                if (classObject is MetaDataTypeReference)
                {
                    // We will simply assume it is an I4 enum
                    Console.Out.WriteLine("====>>> WARNING: Making I4 enum assumption for " + classObject);
                    return(reader.ReadInt32());
                }
                else if (classObject is MetaDataTypeDefinition)
                {
                    MetaDataTypeDefinition classDef =
                        (MetaDataTypeDefinition)classObject;
                    MetaDataObject superClass = classDef.Extends;
                    String         superName;
                    if (superClass is MetaDataTypeDefinition)
                    {
                        superName =
                            ((MetaDataTypeDefinition)superClass).FullName;
                    }
                    else if (superClass is MetaDataTypeReference)
                    {
                        superName =
                            ((MetaDataTypeReference)superClass).FullName;
                    }
                    else
                    {
                        throw new MetaDataLoader.IllegalMetaDataFormatException("Unexpected superclass of valuetype: " + superClass);
                    }
                    if (!superName.Equals("System.Enum"))
                    {
                        throw new MetaDataLoader.IllegalMetaDataFormatException("Found valuetype that wasn't an Enum");
                    }
                    return(ExtractEnumValue(classDef, reader,
                                            resolver, resolvers));
                }
                else
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("Unexpected valuetype class: " + classObject);
                }
            }

            case ElementTypes.CLASS: {
                MetaDataObject classObject = type.ClassObject;
                if (classObject is MetaDataTypeReference)
                {
                    MetaDataTypeReference classReference =
                        (MetaDataTypeReference)classObject;
                    MetaDataObject resolvedObject =
                        ResolveTypeRef(resolver, resolvers, classReference);
                    if (resolvedObject is MetaDataTypeDefinition)
                    {
                        classObject = resolvedObject;
                    }
                }
                String className;
                if (classObject is MetaDataTypeReference)
                {
                    className =
                        ((MetaDataTypeReference)classObject).FullName;
                }
                else if (classObject is MetaDataTypeDefinition)
                {
                    className =
                        ((MetaDataTypeDefinition)classObject).FullName;
                }
                else
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("Unexpected class: " + classObject);
                }
                if (className.Equals("System.String"))
                {
                    return(ExtractString(reader));
                }
                else if (className.Equals("System.Object"))
                {
                    goto case ElementTypes.OBJECT;
                }
                else if (className.Equals("System.Type"))
                {
                    return(ExtractString(reader));
                }
                if (!(classObject is MetaDataTypeDefinition))
                {
                    throw new MetaDataLoader.IllegalMetaDataFormatException("Cannot determine whether the following is an array: " + classObject);
                }
                MetaDataObject superClass =
                    ((MetaDataTypeDefinition)classObject).Extends;
                Console.WriteLine("class is " + classObject);
                throw new Exception("Not implemented: object encoding an array");
            }

            case ElementTypes.OBJECT:
            case (ElementTypes)SerializationTypes.TAGGED_OBJECT: {
                SerializationTypes objectType = (SerializationTypes)
                                                reader.ReadByte();
                switch (objectType)
                {
                case SerializationTypes.ENUM: {
                    String typeName = ExtractString(reader);
                    // Some Stringified type names include a bunch of
                    // information past the type, none of which we
                    // are concerned about for the moment.
                    int nameEnd = typeName.IndexOf(',');
                    if (nameEnd >= 0)
                    {
                        typeName = typeName.Substring(0, nameEnd);
                    }
                    // A type defined within another type has a "+"
                    // as the separator.  Convert it to ".", which is
                    // the convention the rest of the reader uses.
                    typeName = typeName.Replace('+', '.');
                    MetaDataTypeDefinition typeDef =
                        ResolveName(resolver, resolvers, typeName);
                    if (typeDef == null)
                    {
                        throw new Exception("No typedef for " + typeName);
                    }
                    return(ExtractEnumValue(typeDef, reader,
                                            resolver, resolvers));
                }

                case SerializationTypes.TYPE: {
                    return(ExtractValue((ElementTypes)objectType,
                                        reader));
                }

                default: {
                    throw new Exception("Found OBJECT type with type " + objectType);
                }
                }
            }

            case ElementTypes.SZARRAY: {
                return(ExtractArrayValue(type.TypeObject, reader,
                                         resolver, resolvers));
            }

            default: {
                return(ExtractValue(type.ElementType, reader));
            }
            }
        }
Exemple #10
0
 // elementType \in {VALUETYPE, CLASS}
 internal Type(ElementTypes elementType,
               MetaDataObject classObject)
 {
     this.elementType = elementType;
     this.classObject = classObject;
 }
Exemple #11
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);
            }
            }
        }