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; }
// 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); }
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)); } } }
// elementType \in {VALUETYPE, CLASS} internal Type(ElementTypes elementType, MetaDataObject classObject) { this.elementType = elementType; this.classObject = classObject; }
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); } } }