internal static void FromSystemType( this SignatureTypeEncoder typeEncoder, Type type, AssemblyGenerator generator) { if (type.IsPrimitive) { typeEncoder.PrimitiveType(GetPrimitiveTypeCode(type)); } else if (type == typeof(string)) { typeEncoder.String(); } else if (type == typeof(object)) { typeEncoder.Object(); } else if (type == typeof(void)) { throw new ArgumentException( "Void type is not allowed in SignatureTypeEncoder. Please, use FromSystemType from ReturnTypeEncoder."); //typeEncoder.VoidPointer(); } else if (type.IsArray) { var elementType = type.GetElementType(); var rank = type.GetArrayRank(); typeEncoder.Array( x => x.FromSystemType(elementType, generator), x => x.Shape( type.GetArrayRank(), ImmutableArray.Create <int>(), ImmutableArray.Create <int>())); } else if (type.IsGenericType) { var genericTypeDef = type.GetGenericTypeDefinition(); var typeHandler = generator.GetOrCreateType(genericTypeDef); var genericArguments = type.GetGenericArguments(); var inst = typeEncoder.GenericInstantiation(typeHandler, genericArguments.Length, false); foreach (var ga in genericArguments) { if (ga.IsGenericParameter) { inst.AddArgument().GenericTypeParameter(ga.GenericParameterPosition); } else { inst.AddArgument().FromSystemType(ga, generator); } } } else { var typeHandler = generator.GetOrCreateType(type); typeEncoder.Type(typeHandler, type.IsValueType); } }
public void SignatureTypeEncoder_Array() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); SignatureTypeEncoder elementType; ArrayShapeEncoder arrayShape; e.Array(out elementType, out arrayShape); AssertEx.Equal(new byte[] { 0x14 }, b.ToArray()); Assert.Same(b, elementType.Builder); Assert.Same(b, arrayShape.Builder); b.Clear(); e.Array( t => Assert.Same(b, t.Builder), s => Assert.Same(b, s.Builder)); AssertEx.Equal(new byte[] { 0x14 }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentNullException>(() => e.Array(null, n => { })); Assert.Throws <ArgumentNullException>(() => e.Array(n => { }, null)); }
public void SignatureTypeEncoder_GenericInstantiation() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); var m = e.GenericInstantiation(MetadataTokens.TypeDefinitionHandle(1), 1, true); Assert.Same(b, m.Builder); AssertEx.Equal(new byte[] { 0x15, 0x11, 0x04, 0x01 }, b.ToArray()); b.Clear(); e.GenericInstantiation(MetadataTokens.TypeReferenceHandle(1), 1, true); AssertEx.Equal(new byte[] { 0x15, 0x11, 0x05, 0x01 }, b.ToArray()); b.Clear(); e.GenericInstantiation(MetadataTokens.TypeDefinitionHandle(1), 1000, false); AssertEx.Equal(new byte[] { 0x15, 0x12, 0x04, 0x83, 0xE8 }, b.ToArray()); b.Clear(); e.GenericInstantiation(MetadataTokens.TypeDefinitionHandle(1), ushort.MaxValue, false); AssertEx.Equal(new byte[] { 0x15, 0x12, 0x04, 0xC0, 0x00, 0xFF, 0xFF }, b.ToArray()); b.Clear(); AssertExtensions.Throws <ArgumentException>(null, () => e.GenericInstantiation(MetadataTokens.TypeSpecificationHandle(1), 1, isValueType: false)); AssertExtensions.Throws <ArgumentException>(null, () => e.GenericInstantiation(default(EntityHandle), 1, isValueType: false)); Assert.Throws <ArgumentOutOfRangeException>(() => e.GenericInstantiation(default(TypeDefinitionHandle), 0, true)); Assert.Throws <ArgumentOutOfRangeException>(() => e.GenericInstantiation(default(TypeDefinitionHandle), -1, true)); Assert.Throws <ArgumentOutOfRangeException>(() => e.GenericInstantiation(default(TypeDefinitionHandle), ushort.MaxValue + 1, true)); Assert.Equal(0, b.Count); }
public void SignatureTypeEncoder_FunctionPointer() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); var m = e.FunctionPointer( SignatureCallingConvention.CDecl, FunctionPointerAttributes.HasThis, genericParameterCount: 1); Assert.Same(b, m.Builder); AssertEx.Equal(new byte[] { 0x1B, 0x21, 0x01 }, b.ToArray()); b.Clear(); e.FunctionPointer( SignatureCallingConvention.Default, FunctionPointerAttributes.HasExplicitThis, genericParameterCount: 0); AssertEx.Equal(new byte[] { 0x1B, 0x60 }, b.ToArray()); b.Clear(); e.FunctionPointer(); AssertEx.Equal(new byte[] { 0x1B, 0x00 }, b.ToArray()); b.Clear(); AssertExtensions.Throws <ArgumentException>("attributes", () => e.FunctionPointer(0, (FunctionPointerAttributes)1000, genericParameterCount: 0)); Assert.Throws <ArgumentOutOfRangeException>(() => e.FunctionPointer(0, 0, genericParameterCount: -1)); Assert.Throws <ArgumentOutOfRangeException>(() => e.FunctionPointer(0, 0, genericParameterCount: ushort.MaxValue + 1)); Assert.Equal(0, b.Count); }
public void SignatureTypeEncoder_VoidPointer() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); e.VoidPointer(); AssertEx.Equal(new byte[] { 0x0F, 0x01 }, b.ToArray()); }
public void SignatureTypeEncoder_CustomModifiers() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); var a = e.CustomModifiers(); AssertEx.Equal(new byte[0], b.ToArray()); Assert.Same(b, a.Builder); }
public void SignatureTypeEncoder_SZArray() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); var a = e.SZArray(); AssertEx.Equal(new byte[] { 0x1D }, b.ToArray()); Assert.Same(b, a.Builder); }
public void SignatureTypeEncoder_Pointer() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); var p = e.Pointer(); AssertEx.Equal(new byte[] { 0x0F }, b.ToArray()); Assert.Same(b, p.Builder); }
public void SignatureTypeEncoder_GenericTypeParameter() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); e.GenericTypeParameter(0); AssertEx.Equal(new byte[] { 0x13, 0x00 }, b.ToArray()); b.Clear(); e.GenericTypeParameter(ushort.MaxValue); AssertEx.Equal(new byte[] { 0x13, 0xC0, 0x00, 0xFF, 0xFF }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentOutOfRangeException>(() => e.GenericTypeParameter(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => e.GenericTypeParameter(ushort.MaxValue + 1)); Assert.Equal(0, b.Count); }
internal static void FromSystemType( this SignatureTypeEncoder typeEncoder, Type type, AssemblyGenerator generator) { if (type.IsPrimitive) { typeEncoder.PrimitiveType(GetPrimitiveTypeCode(type)); } else if (type == typeof(String)) { typeEncoder.String(); } else if (type == typeof(Object)) { typeEncoder.Object(); } else if (type == typeof(void)) { throw new ArgumentException("Void type is not allowed in SignatureTypeEncoder. Please, use FromSystemType from ReturnTypeEncoder."); //typeEncoder.VoidPointer(); } else if (type.IsArray) { var elementType = type.GetElementType(); var rank = type.GetArrayRank(); typeEncoder.Array( x => x.FromSystemType(elementType, generator), x => x.Shape( type.GetArrayRank(), ImmutableArray.Create <int>(), ImmutableArray.Create <int>())); } else if (type.IsGenericType) { throw new ArgumentException("Generic types not supported for now!"); } else { var typeHandler = generator.GetOrCreateType(type); typeEncoder.Type(typeHandler, type.IsValueType); } }
public void SignatureTypeEncoder_Type() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); e.Type(MetadataTokens.TypeDefinitionHandle(1), isValueType: true); AssertEx.Equal(new byte[] { 0x11, 0x04 }, b.ToArray()); b.Clear(); e.Type(MetadataTokens.TypeDefinitionHandle(1), isValueType: false); AssertEx.Equal(new byte[] { 0x12, 0x04 }, b.ToArray()); b.Clear(); e.Type(MetadataTokens.TypeReferenceHandle(1), isValueType: false); AssertEx.Equal(new byte[] { 0x12, 0x05 }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentException>(() => e.Type(MetadataTokens.TypeSpecificationHandle(1), isValueType: false)); Assert.Throws <ArgumentException>(() => e.Type(default(EntityHandle), isValueType: false)); Assert.Equal(0, b.Count); }
private EntityHandle MakeMemberReferenceHandle(TypeSystemEntity methodOrField) { EntityHandle handle; if (!_memberRefOrSpecHandles.TryGetValue(methodOrField, out handle)) { MethodDesc method = methodOrField as MethodDesc; FieldDesc field = methodOrField as FieldDesc; TypeDesc owningType = (method != null ? method.OwningType : field.OwningType); string name = (method != null ? method.Name : field.Name); BlobHandle signature = method != null? MakeSignatureHandle(method.GetTypicalMethodDefinition()) : MakeSignatureHandle(field); handle = _metadataBuilder.AddMemberReference( MakeTypeRefOrSpecHandle(owningType), _metadataBuilder.GetOrAddString(name), signature); if (method != null && method.HasInstantiation && !method.IsTypicalMethodDefinition) { BlobEncoder methodSpecEncoder = new BlobEncoder(new BlobBuilder()); GenericTypeArgumentsEncoder argEncoder = methodSpecEncoder.MethodSpecificationSignature(method.Instantiation.Length); for (int i = 0; i < method.Instantiation.Length; i++) { SignatureTypeEncoder argTypeEncoder = argEncoder.AddArgument(); _signatureEmitter.EncodeTypeSignature(argTypeEncoder, method.Instantiation[i]); } handle = _metadataBuilder.AddMethodSpecification(handle, _metadataBuilder.GetOrAddBlob(methodSpecEncoder.Builder)); } _memberRefOrSpecHandles[methodOrField] = handle; } return(handle); }
private EntityHandle MakeTypeRefOrSpecHandle(TypeDesc type) { EntityHandle handle; if (!_typeRefOrSpecHandles.TryGetValue(type, out handle)) { if (!type.IsDefType || !type.IsTypeDefinition || type is RuntimeDeterminedType) { SignatureTypeEncoder sigEncoder = new SignatureTypeEncoder(new BlobBuilder()); _signatureEmitter.EncodeTypeSignature(sigEncoder, type); handle = _metadataBuilder.AddTypeSpecification(_metadataBuilder.GetOrAddBlob(sigEncoder.Builder)); } else { handle = MakeTypeRefHandle(type); } _typeRefOrSpecHandles[type] = handle; } return(handle); }
public void SignatureTypeEncoder_Array() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); var parts = e.Array(); AssertEx.Equal(new byte[] { 0x14 }, b.ToArray()); Assert.Same(b, parts.Item1.Builder); Assert.Same(b, parts.Item2.Builder); b.Clear(); e.Array( part => Assert.Same(b, part.Builder), part => Assert.Same(b, part.Builder)); AssertEx.Equal(new byte[] { 0x14 }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentNullException>(() => e.Array(null, _ => { })); Assert.Throws <ArgumentNullException>(() => e.Array(_ => { }, null)); }
public void SignatureTypeEncoder_Primitives() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); e.Boolean(); AssertEx.Equal(new byte[] { 0x02 }, b.ToArray()); b.Clear(); e.Char(); AssertEx.Equal(new byte[] { 0x03 }, b.ToArray()); b.Clear(); e.SByte(); AssertEx.Equal(new byte[] { 0x04 }, b.ToArray()); b.Clear(); e.Byte(); AssertEx.Equal(new byte[] { 0x05 }, b.ToArray()); b.Clear(); e.Int16(); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); b.Clear(); e.UInt16(); AssertEx.Equal(new byte[] { 0x07 }, b.ToArray()); b.Clear(); e.Int32(); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); b.Clear(); e.UInt32(); AssertEx.Equal(new byte[] { 0x09 }, b.ToArray()); b.Clear(); e.Int64(); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); e.UInt64(); AssertEx.Equal(new byte[] { 0x0B }, b.ToArray()); b.Clear(); e.Single(); AssertEx.Equal(new byte[] { 0x0C }, b.ToArray()); b.Clear(); e.Double(); AssertEx.Equal(new byte[] { 0x0D }, b.ToArray()); b.Clear(); e.String(); AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); e.IntPtr(); AssertEx.Equal(new byte[] { 0x18 }, b.ToArray()); b.Clear(); e.UIntPtr(); AssertEx.Equal(new byte[] { 0x19 }, b.ToArray()); b.Clear(); e.Object(); AssertEx.Equal(new byte[] { 0x1C }, b.ToArray()); b.Clear(); }
public void SignatureTypeEncoder_Array() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); var parts = e.Array(); AssertEx.Equal(new byte[] { 0x14 }, b.ToArray()); Assert.Same(b, parts.Item1.Builder); Assert.Same(b, parts.Item2.Builder); b.Clear(); e.Array( part => Assert.Same(b, part.Builder), part => Assert.Same(b, part.Builder)); AssertEx.Equal(new byte[] { 0x14 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.Array(null, _ => { })); Assert.Throws<ArgumentNullException>(() => e.Array(_ => { }, null)); }
public void SignatureTypeEncoder_Array() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); SignatureTypeEncoder elementType; ArrayShapeEncoder arrayShape; e.Array(out elementType, out arrayShape); AssertEx.Equal(new byte[] { 0x14 }, b.ToArray()); Assert.Same(b, elementType.Builder); Assert.Same(b, arrayShape.Builder); b.Clear(); e.Array( t => Assert.Same(b, t.Builder), s => Assert.Same(b, s.Builder)); AssertEx.Equal(new byte[] { 0x14 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.Array(null, n => { })); Assert.Throws<ArgumentNullException>(() => e.Array(n => { }, null)); }
public void SignatureTypeEncoder_GenericInstantiation() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); var m = e.GenericInstantiation(MetadataTokens.TypeDefinitionHandle(1), 1, true); Assert.Same(b, m.Builder); AssertEx.Equal(new byte[] { 0x15, 0x11, 0x04, 0x01 }, b.ToArray()); b.Clear(); e.GenericInstantiation(MetadataTokens.TypeReferenceHandle(1), 1, true); AssertEx.Equal(new byte[] { 0x15, 0x11, 0x05, 0x01 }, b.ToArray()); b.Clear(); e.GenericInstantiation(MetadataTokens.TypeDefinitionHandle(1), 1000, false); AssertEx.Equal(new byte[] { 0x15, 0x12, 0x04, 0x83, 0xE8 }, b.ToArray()); b.Clear(); e.GenericInstantiation(MetadataTokens.TypeDefinitionHandle(1), ushort.MaxValue, false); AssertEx.Equal(new byte[] { 0x15, 0x12, 0x04, 0xC0, 0x00, 0xFF, 0xFF }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentException>(() => e.GenericInstantiation(MetadataTokens.TypeSpecificationHandle(1), 1, isValueType: false)); Assert.Throws<ArgumentException>(() => e.GenericInstantiation(default(EntityHandle), 1, isValueType: false)); Assert.Throws<ArgumentOutOfRangeException>(() => e.GenericInstantiation(default(TypeDefinitionHandle), 0, true)); Assert.Throws<ArgumentOutOfRangeException>(() => e.GenericInstantiation(default(TypeDefinitionHandle), -1, true)); Assert.Throws<ArgumentOutOfRangeException>(() => e.GenericInstantiation(default(TypeDefinitionHandle), ushort.MaxValue + 1, true)); Assert.Equal(0, b.Count); }
public void SignatureTypeEncoder_PrimitiveType() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); e.PrimitiveType(PrimitiveTypeCode.Boolean); AssertEx.Equal(new byte[] { 0x02 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Char); AssertEx.Equal(new byte[] { 0x03 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.SByte); AssertEx.Equal(new byte[] { 0x04 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Byte); AssertEx.Equal(new byte[] { 0x05 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int16); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt16); AssertEx.Equal(new byte[] { 0x07 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int32); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt32); AssertEx.Equal(new byte[] { 0x09 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int64); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt64); AssertEx.Equal(new byte[] { 0x0B }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Single); AssertEx.Equal(new byte[] { 0x0C }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Double); AssertEx.Equal(new byte[] { 0x0D }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.String); AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.IntPtr); AssertEx.Equal(new byte[] { 0x18 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UIntPtr); AssertEx.Equal(new byte[] { 0x19 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Object); AssertEx.Equal(new byte[] { 0x1C }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.Void)); Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.TypedReference)); Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveTypeCode)255)); }
public void Array(out SignatureTypeEncoder elementType, out ArrayShapeEncoder arrayShape) { Builder.WriteByte((byte)SignatureTypeCode.Array); elementType = this; arrayShape = new ArrayShapeEncoder(Builder); }
public void SignatureTypeEncoder_CustomModifiers() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); var a = e.CustomModifiers(); AssertEx.Equal(new byte[0], b.ToArray()); Assert.Same(b, a.Builder); }
public void SignatureTypeEncoder_Type() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); e.Type(MetadataTokens.TypeDefinitionHandle(1), isValueType: true); AssertEx.Equal(new byte[] { 0x11, 0x04 }, b.ToArray()); b.Clear(); e.Type(MetadataTokens.TypeDefinitionHandle(1), isValueType: false); AssertEx.Equal(new byte[] { 0x12, 0x04 }, b.ToArray()); b.Clear(); e.Type(MetadataTokens.TypeReferenceHandle(1), isValueType: false); AssertEx.Equal(new byte[] { 0x12, 0x05 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentException>(() => e.Type(MetadataTokens.TypeSpecificationHandle(1), isValueType: false)); Assert.Throws<ArgumentException>(() => e.Type(default(EntityHandle), isValueType: false)); Assert.Equal(0, b.Count); }
public void SignatureTypeEncoder_VoidPointer() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); e.VoidPointer(); AssertEx.Equal(new byte[] { 0x0F, 0x01 }, b.ToArray()); }
public void SignatureTypeEncoder_GenericTypeParameter() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); e.GenericTypeParameter(0); AssertEx.Equal(new byte[] { 0x13, 0x00 }, b.ToArray()); b.Clear(); e.GenericTypeParameter(ushort.MaxValue); AssertEx.Equal(new byte[] { 0x13, 0xC0, 0x00, 0xFF, 0xFF }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.GenericTypeParameter(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.GenericTypeParameter(ushort.MaxValue + 1)); Assert.Equal(0, b.Count); }
private void EncodeTypeSignature(SignatureTypeEncoder encoder, TypeDesc type) { if (type is RuntimeDeterminedType) { EncodeTypeSignature(encoder, ((RuntimeDeterminedType)type).RuntimeDeterminedDetailsType); return; } switch (type.Category) { case TypeFlags.Boolean: encoder.Boolean(); break; case TypeFlags.Byte: encoder.Byte(); break; case TypeFlags.SByte: encoder.SByte(); break; case TypeFlags.Char: encoder.Char(); break; case TypeFlags.Int16: encoder.Int16(); break; case TypeFlags.UInt16: encoder.UInt16(); break; case TypeFlags.Int32: encoder.Int32(); break; case TypeFlags.UInt32: encoder.UInt32(); break; case TypeFlags.Int64: encoder.Int64(); break; case TypeFlags.UInt64: encoder.UInt64(); break; case TypeFlags.Single: encoder.Single(); break; case TypeFlags.Double: encoder.Double(); break; case TypeFlags.IntPtr: encoder.IntPtr(); break; case TypeFlags.UIntPtr: encoder.UIntPtr(); break; case TypeFlags.Void: encoder.Builder.WriteByte((byte)PrimitiveTypeCode.Void); break; case TypeFlags.SignatureTypeVariable: encoder.GenericTypeParameter(((SignatureVariable)type).Index); break; case TypeFlags.SignatureMethodVariable: encoder.GenericMethodTypeParameter(((SignatureMethodVariable)type).Index); break; case TypeFlags.GenericParameter: { var genericTypeDesc = (GenericParameterDesc)type; if (genericTypeDesc.Kind == GenericParameterKind.Type) { encoder.GenericTypeParameter(genericTypeDesc.Index); } else { encoder.GenericMethodTypeParameter(genericTypeDesc.Index); } } break; case TypeFlags.FunctionPointer: { FunctionPointerType fptrType = (FunctionPointerType)type; encoder.FunctionPointer( SignatureCallingConvention.Default, fptrType.Signature.IsStatic ? default(FunctionPointerAttributes) : FunctionPointerAttributes.HasThis, fptrType.Signature.GenericParameterCount); // Return Type Sig EncodeTypeSignature(encoder, fptrType.Signature.ReturnType); // Parameter Types Sig for (int i = 0; i < fptrType.Signature.Length; i++) { EncodeTypeSignature(encoder, fptrType.Signature[i]); } } break; case TypeFlags.Array: { // Skip bounds and lobounds (TODO) ImmutableArray <int> bounds = ImmutableArray.Create <int>(); ImmutableArray <int> lowerBounds = ImmutableArray.Create <int>(); encoder.Array( elementType => EncodeTypeSignature(elementType, ((ArrayType)type).ElementType), arrayShape => arrayShape.Shape(((ArrayType)type).Rank, bounds, lowerBounds)); } break; case TypeFlags.SzArray: encoder.SZArray(); EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType); break; case TypeFlags.ByRef: encoder.Builder.WriteByte((byte)SignatureTypeCode.ByReference); EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType); break; case TypeFlags.Pointer: encoder.Builder.WriteByte((byte)SignatureTypeCode.Pointer); EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType); break; case TypeFlags.Enum: case TypeFlags.Class: case TypeFlags.ValueType: case TypeFlags.Interface: case TypeFlags.Nullable: { if (type == _typeSystemContext.GetWellKnownType(WellKnownType.TypedReference)) { encoder.Builder.WriteByte((byte)PrimitiveTypeCode.TypedReference); } else if (type == _typeSystemContext.GetWellKnownType(WellKnownType.Object)) { encoder.PrimitiveType(PrimitiveTypeCode.Object); } else if (type == _typeSystemContext.GetWellKnownType(WellKnownType.String)) { encoder.PrimitiveType(PrimitiveTypeCode.String); } else if (type.HasInstantiation && !type.IsGenericDefinition) { encoder.GenericInstantiation(MakeTypeRefOrSpecHandle(type.GetTypeDefinition()), type.Instantiation.Length, type.IsValueType); for (int i = 0; i < type.Instantiation.Length; i++) { EncodeTypeSignature(encoder, type.Instantiation[i]); } } else { encoder.Type(MakeTypeRefHandle(type), type.IsValueType); } } break; default: throw new InvalidOperationException("Attempting to encode an invalid type signature."); } }
internal static void FromSystemType(this SignatureTypeEncoder typeEncoder, Type type, IAssemblyMetadata metadata) { if (type.IsByRef) { throw new ArgumentException("ByRef types should be handled by parameter encoder or return type encoder"); } else if (type.IsPointer) { typeEncoder.Pointer().FromSystemType(type.GetElementType(), metadata); } else if (type.IsPrimitive) { typeEncoder.PrimitiveType(GetPrimitiveTypeCode(type)); } else if (type == typeof(string)) { typeEncoder.String(); } else if (type == typeof(object)) { typeEncoder.Object(); } else if (type == typeof(void)) { throw new ArgumentException( "Void type is not allowed in SignatureTypeEncoder. Please, use FromSystemType from ReturnTypeEncoder.", nameof(type)); } else if (type.IsArray) { var elementType = type.GetElementType(); if (type.GetArrayRank() == 1) { typeEncoder.SZArray().FromSystemType(elementType, metadata); } else { typeEncoder.Array( x => x.FromSystemType(elementType, metadata), x => x.Shape( type.GetArrayRank(), ImmutableArray.Create <int>(), ImmutableArray.CreateRange <int>(Enumerable.Repeat(0, type.GetArrayRank())) // better matches metadata from C# )); } } else if (type.IsGenericType) { var genericTypeDef = type.GetGenericTypeDefinition(); var typeHandler = metadata.GetTypeHandle(genericTypeDef); var genericArguments = type.GetGenericArguments(); var inst = typeEncoder.GenericInstantiation(typeHandler, genericArguments.Length, type.IsValueType); foreach (var ga in genericArguments) { if (ga.IsGenericParameter) { inst.AddArgument().GenericTypeParameter(ga.GenericParameterPosition); } else { inst.AddArgument().FromSystemType(ga, metadata); } } } else if (type.IsGenericMethodParameter()) { typeEncoder.GenericMethodTypeParameter(type.GenericParameterPosition); } else if (type.IsGenericParameter) { typeEncoder.GenericTypeParameter(type.GenericParameterPosition); } else { var typeHandler = metadata.GetTypeHandle(type); typeEncoder.Type(typeHandler, type.IsValueType); } }
public static void EncodeSpecialType(this SignatureTypeEncoder typeEncoder, SpecialType specialType) { switch (specialType) { case SpecialType.System_Boolean: typeEncoder.Boolean(); break; case SpecialType.System_SByte: typeEncoder.SByte(); break; case SpecialType.System_Byte: typeEncoder.Byte(); break; case SpecialType.System_Int16: typeEncoder.Int16(); break; case SpecialType.System_Int32: typeEncoder.Int32(); break; case SpecialType.System_Int64: typeEncoder.Int64(); break; case SpecialType.System_UInt16: typeEncoder.UInt16(); break; case SpecialType.System_UInt32: typeEncoder.UInt32(); break; case SpecialType.System_UInt64: typeEncoder.UInt64(); break; case SpecialType.System_Single: typeEncoder.Single(); break; case SpecialType.System_Double: typeEncoder.Double(); break; case SpecialType.System_Char: typeEncoder.Char(); break; case SpecialType.System_String: typeEncoder.String(); break; case SpecialType.System_Object: typeEncoder.Object(); break; case SpecialType.System_IntPtr: typeEncoder.IntPtr(); break; case SpecialType.System_UIntPtr: typeEncoder.UIntPtr(); break; default: throw new NotImplementedException(); } // TODO: handle C# interface mappings for special types }
/// <summary> /// Encode a type signature into a specified blob. /// </summary> /// <param name="blobBuilder">Blob to encode type signature into. Must not be null</param> public void EncodeSignatureForType(TypeDesc type, BlobBuilder blobBuilder) { SignatureTypeEncoder sigEncoder = new SignatureTypeEncoder(blobBuilder); _signatureEmitter.EncodeTypeSignature(sigEncoder, type); }
public void SignatureTypeEncoder_PrimitiveType() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); e.PrimitiveType(PrimitiveTypeCode.Boolean); AssertEx.Equal(new byte[] { 0x02 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Char); AssertEx.Equal(new byte[] { 0x03 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.SByte); AssertEx.Equal(new byte[] { 0x04 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Byte); AssertEx.Equal(new byte[] { 0x05 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int16); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt16); AssertEx.Equal(new byte[] { 0x07 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int32); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt32); AssertEx.Equal(new byte[] { 0x09 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int64); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt64); AssertEx.Equal(new byte[] { 0x0B }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Single); AssertEx.Equal(new byte[] { 0x0C }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Double); AssertEx.Equal(new byte[] { 0x0D }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.String); AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.IntPtr); AssertEx.Equal(new byte[] { 0x18 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UIntPtr); AssertEx.Equal(new byte[] { 0x19 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Object); AssertEx.Equal(new byte[] { 0x1C }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.Void)); Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.TypedReference)); Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveTypeCode)255)); }
public void SignatureTypeEncoder_SZArray() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); var a = e.SZArray(); AssertEx.Equal(new byte[] { 0x1D }, b.ToArray()); Assert.Same(b, a.Builder); }
public void SignatureTypeEncoder_FunctionPointer() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); var m = e.FunctionPointer( SignatureCallingConvention.CDecl, FunctionPointerAttributes.HasThis, genericParameterCount: 1); Assert.Same(b, m.Builder); AssertEx.Equal(new byte[] { 0x1B, 0x21, 0x01 }, b.ToArray()); b.Clear(); e.FunctionPointer( SignatureCallingConvention.Default, FunctionPointerAttributes.HasExplicitThis, genericParameterCount: 0); AssertEx.Equal(new byte[] { 0x1B, 0x60 }, b.ToArray()); b.Clear(); e.FunctionPointer(); AssertEx.Equal(new byte[] { 0x1B, 0x00 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentException>(() => e.FunctionPointer(0, (FunctionPointerAttributes)1000, genericParameterCount: 0)); Assert.Throws<ArgumentOutOfRangeException>(() => e.FunctionPointer(0, 0, genericParameterCount: -1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.FunctionPointer(0, 0, genericParameterCount: ushort.MaxValue + 1)); Assert.Equal(0, b.Count); }