private TypeDesc GetModifierType(ref NativeParser parser, TypeModifierKind modifier) { TypeDesc typeParameter = GetType(ref parser); switch (modifier) { case TypeModifierKind.Array: return(_typeSystemContext.GetArrayType(typeParameter)); case TypeModifierKind.ByRef: return(_typeSystemContext.GetByRefType(typeParameter)); case TypeModifierKind.Pointer: return(_typeSystemContext.GetPointerType(typeParameter)); default: parser.ThrowBadImageFormatException(); return(null); } }
private TypeDesc GetModifierType(ref NativeParser parser, TypeModifierKind modifier) { TypeDesc typeParameter = GetType(ref parser); switch (modifier) { case TypeModifierKind.Array: return _typeSystemContext.GetArrayType(typeParameter); case TypeModifierKind.ByRef: return _typeSystemContext.GetByRefType(typeParameter); case TypeModifierKind.Pointer: return _typeSystemContext.GetPointerType(typeParameter); default: parser.ThrowBadImageFormatException(); return null; } }
private bool CompareTypeSigWithType(ref NativeParser parser, Handle typeHandle) { while (typeHandle.HandleType == HandleType.TypeSpecification) { typeHandle = typeHandle .ToTypeSpecificationHandle(_metadataReader) .GetTypeSpecification(_metadataReader) .Signature; } // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader // expects to read it in. uint startOffset = parser.Offset; uint data; var typeSignatureKind = parser.GetTypeSignatureKind(out data); switch (typeSignatureKind) { case TypeSignatureKind.Lookback: { NativeParser lookbackParser = parser.GetLookbackParser(data); return(CompareTypeSigWithType(ref lookbackParser, typeHandle)); } case TypeSignatureKind.Modifier: { // Ensure the modifier kind (vector, pointer, byref) is the same TypeModifierKind modifierKind = (TypeModifierKind)data; switch (modifierKind) { case TypeModifierKind.Array: if (typeHandle.HandleType == HandleType.SZArraySignature) { return(CompareTypeSigWithType(ref parser, typeHandle .ToSZArraySignatureHandle(_metadataReader) .GetSZArraySignature(_metadataReader) .ElementType)); } return(false); case TypeModifierKind.ByRef: if (typeHandle.HandleType == HandleType.ByReferenceSignature) { return(CompareTypeSigWithType(ref parser, typeHandle .ToByReferenceSignatureHandle(_metadataReader) .GetByReferenceSignature(_metadataReader) .Type)); } return(false); case TypeModifierKind.Pointer: if (typeHandle.HandleType == HandleType.PointerSignature) { return(CompareTypeSigWithType(ref parser, typeHandle .ToPointerSignatureHandle(_metadataReader) .GetPointerSignature(_metadataReader) .Type)); } return(false); default: Debug.Assert(null == "invalid type modifier kind"); return(false); } } case TypeSignatureKind.Variable: { bool isMethodVar = (data & 0x1) == 1; uint index = data >> 1; if (isMethodVar) { if (typeHandle.HandleType == HandleType.MethodTypeVariableSignature) { return(index == typeHandle .ToMethodTypeVariableSignatureHandle(_metadataReader) .GetMethodTypeVariableSignature(_metadataReader) .Number); } } else { if (typeHandle.HandleType == HandleType.TypeVariableSignature) { return(index == typeHandle .ToTypeVariableSignatureHandle(_metadataReader) .GetTypeVariableSignature(_metadataReader) .Number); } } return(false); } case TypeSignatureKind.MultiDimArray: { if (typeHandle.HandleType != HandleType.ArraySignature) { return(false); } ArraySignature sig = typeHandle .ToArraySignatureHandle(_metadataReader) .GetArraySignature(_metadataReader); if (data != sig.Rank) { return(false); } if (!CompareTypeSigWithType(ref parser, sig.ElementType)) { return(false); } uint boundCount1 = parser.GetUnsigned(); for (uint i = 0; i < boundCount1; i++) { parser.GetUnsigned(); } uint lowerBoundCount1 = parser.GetUnsigned(); for (uint i = 0; i < lowerBoundCount1; i++) { parser.GetUnsigned(); } break; } case TypeSignatureKind.FunctionPointer: { // callingConvention is in data uint argCount1 = parser.GetUnsigned(); for (uint i = 0; i < argCount1; i++) { if (!CompareTypeSigWithType(ref parser, typeHandle)) { return(false); } } return(false); } case TypeSignatureKind.Instantiation: { if (typeHandle.HandleType != HandleType.TypeInstantiationSignature) { return(false); } TypeInstantiationSignature sig = typeHandle .ToTypeInstantiationSignatureHandle(_metadataReader) .GetTypeInstantiationSignature(_metadataReader); if (!CompareTypeSigWithType(ref parser, sig.GenericType)) { return(false); } uint genericArgIndex = 0; foreach (Handle genericArgumentTypeHandle in sig.GenericTypeArguments) { if (genericArgIndex >= data) { // The metadata generic has more parameters than the native layour return(false); } if (!CompareTypeSigWithType(ref parser, genericArgumentTypeHandle)) { return(false); } genericArgIndex++; } // Make sure all generic parameters have been matched return(genericArgIndex == data); } case TypeSignatureKind.External: { RuntimeTypeHandle type2; switch (typeHandle.HandleType) { case HandleType.TypeDefinition: if (!TypeLoaderEnvironment.Instance.TryGetOrCreateNamedTypeForMetadata( _metadataReader, typeHandle.ToTypeDefinitionHandle(_metadataReader), out type2)) { return(false); } break; case HandleType.TypeReference: if (!TypeLoaderEnvironment.TryGetNamedTypeForTypeReference( _metadataReader, typeHandle.ToTypeReferenceHandle(_metadataReader), out type2)) { return(false); } break; default: return(false); } RuntimeTypeHandle type1 = SigParsing.GetTypeFromNativeLayoutSignature(ref parser, startOffset); return(type1.Equals(type2)); } default: return(false); } return(true); }
public Vertex GetModifierTypeSignature(TypeModifierKind modifier, Vertex param) { ModifierTypeSignature sig = new ModifierTypeSignature(modifier, param); return(Unify(sig)); }
public ModifierTypeSignature(TypeModifierKind modifier, Vertex param) { _modifier = modifier; _param = param; }
private static bool CompareTypeSigWithType(ref NativeParser parser, Type type) { // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader // expects to read it in. uint startOffset = parser.Offset; uint data; var typeSignatureKind = parser.GetTypeSignatureKind(out data); switch (typeSignatureKind) { case TypeSignatureKind.Lookback: { NativeParser lookbackParser = parser.GetLookbackParser(data); return(CompareTypeSigWithType(ref lookbackParser, type)); } case TypeSignatureKind.Modifier: { // Ensure the modifier kind (vector, pointer, byref) is the same TypeModifierKind modifierKind = (TypeModifierKind)data; switch (modifierKind) { case TypeModifierKind.Array: if (!type.IsArray) { return(false); } break; case TypeModifierKind.ByRef: if (!type.IsByRef) { return(false); } break; case TypeModifierKind.Pointer: if (!type.IsPointer) { return(false); } break; } return(CompareTypeSigWithType(ref parser, type.GetElementType())); } case TypeSignatureKind.Variable: { if (!type.IsGenericParameter) { return(false); } bool isMethodVar = (data & 0x1) == 1; uint index = data >> 1; if (index != type.GenericParameterPosition) { return(false); } // MVARs are represented as having a non-null DeclaringMethod in the reflection object model if (isMethodVar ^ (type.GetTypeInfo().DeclaringMethod != null)) { return(false); } break; } case TypeSignatureKind.MultiDimArray: { if (!type.IsArray) { return(false); } if (data != type.GetArrayRank()) { return(false); } if (!CompareTypeSigWithType(ref parser, type.GetElementType())) { return(false); } uint boundCount1 = parser.GetUnsigned(); for (uint i = 0; i < boundCount1; i++) { parser.GetUnsigned(); } uint lowerBoundCount1 = parser.GetUnsigned(); for (uint i = 0; i < lowerBoundCount1; i++) { parser.GetUnsigned(); } break; } case TypeSignatureKind.FunctionPointer: { // callingConvention is in data uint argCount1 = parser.GetUnsigned(); for (uint i = 0; i < argCount1; i++) { if (!CompareTypeSigWithType(ref parser, type)) { return(false); } } return(false); } case TypeSignatureKind.Instantiation: { // Type Def if (!type.GetTypeInfo().IsGenericType) { return(false); } if (!CompareTypeSigWithType(ref parser, type.GetGenericTypeDefinition())) { return(false); } for (uint i = 0; i < data; i++) { if (!CompareTypeSigWithType(ref parser, type.GenericTypeArguments[i])) { return(false); } } break; } case TypeSignatureKind.External: { RuntimeTypeHandle type1 = SigParsing.GetTypeFromNativeLayoutSignature(ref parser, startOffset); if (!CanGetTypeHandle(type)) { return(false); } RuntimeTypeHandle type2 = type.TypeHandle; if (!type1.Equals(type2)) { return(false); } break; } default: return(false); } return(true); }