void ParseTypeHandle() { int token = MetadataTokens.GetToken(_input.ReadTypeHandle()); int newToken = _getAlternateStreamToken(token); int newEncodedHandle = CodedIndex.TypeDefOrRefOrSpec(MetadataTokens.EntityHandle(newToken)); _output.WriteCompressedInteger(newEncodedHandle); }
public void TypeDefOrRefOrSpec() { Assert.Equal(0, CodedIndex.TypeDefOrRefOrSpec(default(TypeDefinitionHandle))); Assert.Equal((0xffffff << 2) | 2, CodedIndex.TypeDefOrRefOrSpec(MetadataTokens.TypeSpecificationHandle(0xffffff))); Assert.Equal(0x04 | 0, CodedIndex.TypeDefOrRefOrSpec(MetadataTokens.TypeDefinitionHandle(1))); Assert.Equal(0x04 | 1, CodedIndex.TypeDefOrRefOrSpec(MetadataTokens.TypeReferenceHandle(1))); Assert.Equal(0x04 | 2, CodedIndex.TypeDefOrRefOrSpec(MetadataTokens.TypeSpecificationHandle(1))); }
private void DeclareInterfacesAndCreateInterfaceMap(Type type, TypeDefinitionHandle handle) { // Only add those interfaces that are not already implemented by the base type. // This prevents the generation of assembly dependencies not covered by the // GetReferencedAssemblies method. HashSet <Type> interfaces = new HashSet <Type>((type.BaseType is null ? type.GetInterfaces() : type.GetInterfaces().Except(type.BaseType.GetInterfaces())) .OrderBy(t => CodedIndex.TypeDefOrRefOrSpec(_metadata.GetTypeHandle(t)))); foreach (var ifc in interfaces) { _metadata.Builder.AddInterfaceImplementation(handle, _metadata.GetTypeHandle(ifc)); } // If the type is an interface there may be no interface map. // TODO: This isn't necessarily true for Default interface methods. if (type.IsInterface) { return; } // Build the interface map. // All interfaces need to be considered (not just the ones added by the type) because // the type may override interface methods of interfaces implemented by the base type. // It is also possible for a type to use a base type method to implement an interface // method of an interface added by the type. For these reasons it is not sufficient // to only use the interfaces declared by a type or look at the declaring type of a // method implementing an interface method. foreach (var ifcm in from ifc in type.GetInterfaces() select type.GetInterfaceMap(ifc)) { bool implementedByType = interfaces.Contains(ifcm.InterfaceType); for (int i = 0; i < ifcm.InterfaceMethods.Length; ++i) { MethodInfo targetMethod = ifcm.TargetMethods[i]; MethodInfo ifcMethod = ifcm.InterfaceMethods[i]; // Declare a method override either when the interface implementation or // the interface method implementation is declared by the type. if (implementedByType || targetMethod.DeclaringType.Equals(type)) { // Mark the target method as implementing the interface method. // (This is the equivalent of .Override in msil) _metadata.Builder.AddMethodImplementation( (TypeDefinitionHandle)_metadata.GetTypeHandle(targetMethod.DeclaringType), _metadata.GetMethodHandle(targetMethod), _metadata.GetMethodHandle(ifcMethod)); } } } }
public void Type(EntityHandle type, string?alias = null) { if (alias != null) { // <import> ::= AliasType <alias> <target-type> Builder.WriteByte((byte)ImportDefinitionKind.AliasType); Builder.WriteCompressedInteger(MetadataTokens.GetHeapOffset(MetadataBuilder.GetOrAddBlobUTF8(alias))); } else { // <import> ::= ImportType <target-type> Builder.WriteByte((byte)ImportDefinitionKind.ImportType); } Builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(type)); }
private static TypeSignature _forClassOrValueType(EntityHandle handle, bool isValueType) { if (handle.IsNil) { throw new ArgumentException("Handle for a class or value type must not be null.", nameof(handle)); } var builder = TypeSignatureBuilder.getInstance(); try { builder.appendByte((byte)(isValueType ? SignatureTypeKind.ValueType : SignatureTypeKind.Class)); builder.appendCompressedUnsignedInt(CodedIndex.TypeDefOrRefOrSpec(handle)); return(builder.makeSignature()); } finally { builder.clear(); } }
public void Errors() { var badHandleKind = CustomAttributeHandle.FromRowId(1); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasCustomAttribute(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasConstant(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.CustomAttributeType(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasDeclSecurity(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasFieldMarshal(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasSemantics(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.Implementation(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.MemberForwarded(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.MemberRefParent(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.MethodDefOrRef(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.ResolutionScope(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.TypeDefOrRef(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.TypeDefOrRefOrSpec(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.TypeOrMethodDef(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasCustomDebugInformation(badHandleKind)); }
public void EmitAtCurrentIndexStack(BlobBuilder signatureBuilder) { if (!Complete) { if (_embeddedDataIndex < _embeddedData.Length) { string indexData = string.Join(".", _indexStack); while ((_embeddedDataIndex < _embeddedData.Length) && _embeddedData[_embeddedDataIndex].index == indexData) { switch (_embeddedData[_embeddedDataIndex].kind) { case EmbeddedSignatureDataKind.OptionalCustomModifier: { signatureBuilder.WriteByte((byte)SignatureTypeCode.OptionalModifier); EntityHandle handle = _metadataEmitter.GetTypeRef((MetadataType)_embeddedData[_embeddedDataIndex].type); signatureBuilder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(handle)); } break; case EmbeddedSignatureDataKind.RequiredCustomModifier: { signatureBuilder.WriteByte((byte)SignatureTypeCode.RequiredModifier); EntityHandle handle = _metadataEmitter.GetTypeRef((MetadataType)_embeddedData[_embeddedDataIndex].type); signatureBuilder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(handle)); } break; case EmbeddedSignatureDataKind.ArrayShape: return; default: throw new NotImplementedException(); } _embeddedDataIndex++; } } } }
private void SerializeImport(BlobBuilder writer, UsedNamespaceOrType import) { if (import.TargetXmlNamespaceOpt != null) { Debug.Assert(import.TargetNamespaceOpt == null); Debug.Assert(import.TargetAssemblyOpt == null); Debug.Assert(import.TargetTypeOpt == null); // <import> ::= ImportXmlNamespace <alias> <target-namespace> writer.WriteByte((byte)ImportDefinitionKind.ImportXmlNamespace); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.TargetXmlNamespaceOpt))); } else if (import.TargetTypeOpt != null) { Debug.Assert(import.TargetNamespaceOpt == null); Debug.Assert(import.TargetAssemblyOpt == null); if (import.AliasOpt != null) { // <import> ::= AliasType <alias> <target-type> writer.WriteByte((byte)ImportDefinitionKind.AliasType); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); } else { // <import> ::= ImportType <target-type> writer.WriteByte((byte)ImportDefinitionKind.ImportType); } writer.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(GetTypeHandle(import.TargetTypeOpt))); // TODO: index in release build } else if (import.TargetNamespaceOpt != null) { if (import.TargetAssemblyOpt != null) { if (import.AliasOpt != null) { // <import> ::= AliasAssemblyNamespace <alias> <target-assembly> <target-namespace> writer.WriteByte((byte)ImportDefinitionKind.AliasAssemblyNamespace); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); } else { // <import> ::= ImportAssemblyNamespace <target-assembly> <target-namespace> writer.WriteByte((byte)ImportDefinitionKind.ImportAssemblyNamespace); } writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(GetAssemblyReferenceHandle(import.TargetAssemblyOpt))); } else { if (import.AliasOpt != null) { // <import> ::= AliasNamespace <alias> <target-namespace> writer.WriteByte((byte)ImportDefinitionKind.AliasNamespace); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); } else { // <import> ::= ImportNamespace <target-namespace> writer.WriteByte((byte)ImportDefinitionKind.ImportNamespace); } } // TODO: cache? string namespaceName = TypeNameSerializer.BuildQualifiedNamespaceName(import.TargetNamespaceOpt); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(namespaceName))); } else { // <import> ::= ImportReferenceAlias <alias> Debug.Assert(import.AliasOpt != null); Debug.Assert(import.TargetAssemblyOpt == null); writer.WriteByte((byte)ImportDefinitionKind.ImportAssemblyReferenceAlias); writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); } }
private BlobHandle SerializeLocalConstantSignature(ILocalDefinition localConstant) { var builder = new BlobBuilder(); // TODO: BlobEncoder.LocalConstantSignature // CustomMod* var encoder = new CustomModifiersEncoder(builder); SerializeCustomModifiers(encoder, localConstant.CustomModifiers); var type = localConstant.Type; var typeCode = type.TypeCode(Context); object value = localConstant.CompileTimeValue.Value; // PrimitiveConstant or EnumConstant if (value is decimal) { builder.WriteByte((byte)SignatureTypeKind.ValueType); builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(GetTypeHandle(type))); builder.WriteDecimal((decimal)value); } else if (value is DateTime) { builder.WriteByte((byte)SignatureTypeKind.ValueType); builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(GetTypeHandle(type))); builder.WriteDateTime((DateTime)value); } else if (typeCode == PrimitiveTypeCode.String) { builder.WriteByte((byte)ConstantTypeCode.String); if (value == null) { builder.WriteByte(0xff); } else { builder.WriteUTF16((string)value); } } else if (value != null) { // TypeCode builder.WriteByte((byte)GetConstantTypeCode(value)); // Value builder.WriteConstant(value); // EnumType if (type.IsEnum) { builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(GetTypeHandle(type))); } } else if (this.module.IsPlatformType(type, PlatformType.SystemObject)) { builder.WriteByte((byte)SignatureTypeCode.Object); } else { builder.WriteByte((byte)(type.IsValueType ? SignatureTypeKind.ValueType : SignatureTypeKind.Class)); builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(GetTypeHandle(type))); } return(_debugMetadataOpt.GetOrAddBlob(builder)); }
public unsafe static void Convert(BlobBuilder builder, MetadataModel metadataModel, byte[] signature, object value) { fixed(byte *sigPtr = signature) { var sigReader = new BlobReader(sigPtr, signature.Length); // copy custom modifiers over: byte rawTypeCode; while (true) { rawTypeCode = sigReader.ReadByte(); if (rawTypeCode != (int)SignatureTypeCode.OptionalModifier && rawTypeCode != (int)SignatureTypeCode.RequiredModifier) { break; } builder.WriteByte(rawTypeCode); builder.WriteCompressedInteger(sigReader.ReadCompressedInteger()); } switch ((SignatureTypeCode)rawTypeCode) { case (SignatureTypeCode)SignatureTypeKind.Class: case (SignatureTypeCode)SignatureTypeKind.ValueType: int typeRefDefSpec = sigReader.ReadCompressedInteger(); if (value is decimal) { // GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <decimal> builder.WriteByte((byte)SignatureTypeKind.ValueType); builder.WriteCompressedInteger(typeRefDefSpec); builder.WriteDecimal((decimal)value); } else if (value is DateTime) { // GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <date-time> builder.WriteByte((byte)SignatureTypeKind.ValueType); builder.WriteCompressedInteger(typeRefDefSpec); builder.WriteDateTime((DateTime)value); } else if (value == null) { // GeneralConstant: CLASS TypeDefOrRefOrSpecEncoded builder.WriteByte(rawTypeCode); builder.WriteCompressedInteger(typeRefDefSpec); } else { // EnumConstant ::= EnumTypeCode EnumValue EnumType // EnumTypeCode ::= BOOLEAN | CHAR | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 // EnumType ::= TypeDefOrRefOrSpecEncoded var enumTypeCode = MetadataHelpers.GetConstantTypeCode(value); builder.WriteByte((byte)enumTypeCode); builder.WriteConstant(value); builder.WriteCompressedInteger(typeRefDefSpec); } break; case SignatureTypeCode.Object: // null: Debug.Assert(value == null); builder.WriteByte((byte)SignatureTypeCode.Object); break; case SignatureTypeCode.Boolean: case SignatureTypeCode.Char: case SignatureTypeCode.SByte: case SignatureTypeCode.Byte: case SignatureTypeCode.Int16: case SignatureTypeCode.UInt16: case SignatureTypeCode.Int32: case SignatureTypeCode.UInt32: case SignatureTypeCode.Int64: case SignatureTypeCode.UInt64: case SignatureTypeCode.Single: case SignatureTypeCode.Double: case SignatureTypeCode.String: // PrimitiveConstant builder.WriteByte(rawTypeCode); builder.WriteConstant(value); break; case SignatureTypeCode.SZArray: case SignatureTypeCode.Array: case SignatureTypeCode.GenericTypeInstance: Debug.Assert(value == null); // Find an existing TypeSpec in metadata. // If there isn't one we can't represent the constant type in the Portable PDB, use Object. // +1/-1 for the type code we already read. var spec = new byte[sigReader.RemainingBytes + 1]; Buffer.BlockCopy(signature, sigReader.Offset - 1, spec, 0, spec.Length); TypeSpecificationHandle typeSpec; if (metadataModel.TryResolveTypeSpecification(spec, out typeSpec)) { builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(typeSpec)); } else { // TODO: warning - can't translate const type builder.WriteByte((byte)SignatureTypeCode.Object); } break; case SignatureTypeCode.GenericMethodParameter: case SignatureTypeCode.GenericTypeParameter: case SignatureTypeCode.FunctionPointer: case SignatureTypeCode.Pointer: // generic parameters, pointers are not valid types for constants: throw new BadImageFormatException(); } } }
private void CreateType(Type type) { // Check reserved and not already emitted if (!_metadata.TryGetTypeDefinition(type, out var metadata)) { ThrowMetadataIsNotReserved("Type", type); } EnsureMetadataWasNotEmitted(metadata, type); // Add the type definition var baseTypeHandle = type.BaseType != null?_metadata.GetTypeHandle(type.BaseType) : default; var typeHandle = _metadata.Builder.AddTypeDefinition( type.Attributes, type.DeclaringType == null ? _metadata.GetOrAddString(ApplyNameChange(type.Namespace)) : default(StringHandle), _metadata.GetOrAddString(type.Name), baseTypeHandle, MetadataTokens.FieldDefinitionHandle(_metadata.Builder.GetRowCount(TableIndex.Field) + 1), MetadataTokens.MethodDefinitionHandle(_metadata.Builder.GetRowCount(TableIndex.MethodDef) + 1)); // Verify and mark emitted VerifyEmittedHandle(metadata, typeHandle); metadata.MarkAsEmitted(); // Setup pack and size attributes (if explicit layout) if (type.IsExplicitLayout) { _metadata.Builder.AddTypeLayout( typeHandle, (ushort)type.StructLayoutAttribute.Pack, (uint)type.StructLayoutAttribute.Size ); } // Add implemented interfaces (not for enums though - eg: IComparable etc...) if (!type.IsEnum) { foreach (var itf in type.GetInterfaces().OrderBy(t => CodedIndex.TypeDefOrRefOrSpec(_metadata.GetTypeHandle(t)))) { _metadata.Builder.AddInterfaceImplementation(typeHandle, _metadata.GetTypeHandle(itf)); } } // Setup enclosing type if (type.DeclaringType != null) { _metadata.Builder.AddNestedType(typeHandle, (TypeDefinitionHandle)_metadata.GetTypeHandle(type.DeclaringType)); } // Create attributes CreateCustomAttributes(typeHandle, type.GetCustomAttributesData()); // Handle generics type if (type.IsGenericType) { if (type.IsGenericTypeDefinition) { var genericType = type.GetGenericTypeDefinition(); var typeInfo = genericType.GetTypeInfo(); for (var i = 0; i < typeInfo.GenericTypeParameters.Length; ++i) { var parm = typeInfo.GenericTypeParameters[i]; var attr = parm.GenericParameterAttributes; var genericParameterHandle = _metadata.Builder.AddGenericParameter(typeHandle, attr, _metadata.GetOrAddString(parm.Name), i); foreach (var constraint in parm.GetGenericParameterConstraints()) { _metadata.Builder.AddGenericParameterConstraint(genericParameterHandle, _metadata.GetTypeHandle(constraint)); } } } } // Create members... CreateFields(type.GetFields(AllFields)); CreatePropertiesForType(type.GetProperties(AllProperties)); CreateEventsForType(type.GetEvents(AllEvents)); CreateConstructors(type.GetConstructors(AllMethods)); CreateMethods(type.GetMethods(AllMethods)); }
public static ReadyToRunStandaloneMethodMetadata Compute(EcmaMethod wrappedMethod) { var metadataReader = wrappedMethod.MetadataReader; var _module = wrappedMethod.Module; var rva = wrappedMethod.MetadataReader.GetMethodDefinition(wrappedMethod.Handle).RelativeVirtualAddress; var _methodBody = _module.PEReader.GetMethodBody(rva); byte[] _alternateILStream = _methodBody.GetILBytes(); var exceptionRegions = _methodBody.ExceptionRegions; ILExceptionRegion[] _exceptionRegions; int length = exceptionRegions.Length; if (length == 0) { _exceptionRegions = Array.Empty <ILExceptionRegion>(); } else { _exceptionRegions = new ILExceptionRegion[length]; for (int i = 0; i < length; i++) { var exceptionRegion = exceptionRegions[i]; _exceptionRegions[i] = new ILExceptionRegion( (ILExceptionRegionKind)exceptionRegion.Kind, // assumes that ILExceptionRegionKind and ExceptionRegionKind enums are in sync exceptionRegion.TryOffset, exceptionRegion.TryLength, exceptionRegion.HandlerOffset, exceptionRegion.HandlerLength, MetadataTokens.GetToken(exceptionRegion.CatchType), exceptionRegion.FilterOffset); } } BlobReader localsBlob = default(BlobReader); if (!_methodBody.LocalSignature.IsNil) { localsBlob = wrappedMethod.MetadataReader.GetBlobReader(wrappedMethod.MetadataReader.GetStandaloneSignature(_methodBody.LocalSignature).Signature); } AlternativeTypeRefProvider alternateTypes = new AlternativeTypeRefProvider(); EcmaSignatureEncoder <AlternativeTypeRefProvider> alternateEncoder = new EcmaSignatureEncoder <AlternativeTypeRefProvider>(alternateTypes); Dictionary <int, int> _alternateNonTokenStrings = new Dictionary <int, int>(); BlobBuilder _alternateNonTypeRefStream = new BlobBuilder(); BlobBuilder _nonCodeAlternateBlob = new BlobBuilder(); { // Generate alternate stream for exceptions. _nonCodeAlternateBlob.WriteCompressedInteger(_exceptionRegions.Length); for (int i = 0; i < _exceptionRegions.Length; i++) { var region = _exceptionRegions[i]; _nonCodeAlternateBlob.WriteCompressedInteger((int)region.Kind); _nonCodeAlternateBlob.WriteCompressedInteger((int)region.TryOffset); _nonCodeAlternateBlob.WriteCompressedInteger((int)region.TryLength); _nonCodeAlternateBlob.WriteCompressedInteger((int)region.HandlerOffset); _nonCodeAlternateBlob.WriteCompressedInteger((int)region.HandlerLength); if (region.Kind == ILExceptionRegionKind.Catch) { int alternateToken = GetAlternateStreamToken(region.ClassToken); int encodedToken = CodedIndex.TypeDefOrRefOrSpec(MetadataTokens.EntityHandle(alternateToken)); _nonCodeAlternateBlob.WriteCompressedInteger(encodedToken); } else if (region.Kind == ILExceptionRegionKind.Filter) { _nonCodeAlternateBlob.WriteCompressedInteger(region.FilterOffset); } } if (localsBlob.Length == 0) { // No locals. Encode a 2 to indicate this _nonCodeAlternateBlob.WriteByte(2); } else { _nonCodeAlternateBlob.WriteByte(_methodBody.LocalVariablesInitialized ? (byte)1 : (byte)0); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(localsBlob, _nonCodeAlternateBlob, GetAlternateStreamToken); sigTranslator.ParseLocalsSignature(); } } ILTokenReplacer.Replace(_alternateILStream, GetAlternateStreamToken); // Add all the streams together into the _nonCodeAlternateBlob int expectedFinalSize = _nonCodeAlternateBlob.Count + _alternateILStream.Length + _alternateNonTypeRefStream.Count; _nonCodeAlternateBlob.WriteBytes(_alternateILStream); _nonCodeAlternateBlob.LinkSuffix(_alternateNonTypeRefStream); Debug.Assert(expectedFinalSize == _nonCodeAlternateBlob.Count); ReadyToRunStandaloneMethodMetadata methodBlock = new ReadyToRunStandaloneMethodMetadata(); methodBlock.ConstantData = _nonCodeAlternateBlob.ToArray(); methodBlock.TypeRefs = alternateTypes._alternateTypeRefStream.ToArray(); return(methodBlock); ///// HELPER FUNCTIONS unsafe int GetAlternateStreamToken(int token) { if (token == 0 || !_alternateNonTokenStrings.TryGetValue(token, out int alternateToken)) { var handle = MetadataTokens.Handle(token); if (handle.Kind == HandleKind.TypeDefinition || handle.Kind == HandleKind.TypeReference) { EcmaType ecmaType = (EcmaType)wrappedMethod.Module.GetObject(MetadataTokens.EntityHandle(token)); alternateToken = MetadataTokens.GetToken(alternateTypes.GetTypeDefOrRefHandleForTypeDesc(ecmaType)); } else { BlobBuilder blob = new BlobBuilder(); int flag = 0; if (handle.Kind == HandleKind.UserString) { string strAlternate = metadataReader.GetUserString((UserStringHandle)handle); flag = 0x70000000; blob.WriteCompressedInteger(strAlternate.Length); fixed(char *charData = strAlternate) { blob.WriteBytes((byte *)charData, strAlternate.Length * 2); } // TODO: consider encoding via wtf-8, or possibly utf-8 } else if (handle.Kind == HandleKind.TypeSpecification) { flag = 0x1B000000; var sigBlob = metadataReader.GetBlobReader(metadataReader.GetTypeSpecification((TypeSpecificationHandle)handle).Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseType(); } else if (handle.Kind == HandleKind.MemberReference) { flag = 0x0a000000; var memberReference = metadataReader.GetMemberReference((MemberReferenceHandle)handle); var sigBlob = metadataReader.GetBlobReader(memberReference.Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseMemberRefSignature(); blob.WriteSerializedString(metadataReader.GetString(memberReference.Name)); blob.WriteCompressedInteger(CodedIndex.MemberRefParent(MetadataTokens.EntityHandle(GetAlternateStreamToken(MetadataTokens.GetToken(memberReference.Parent))))); } else if (handle.Kind == HandleKind.MethodDefinition) { flag = 0x0a000000; var methodDefinition = metadataReader.GetMethodDefinition((MethodDefinitionHandle)handle); var sigBlob = metadataReader.GetBlobReader(methodDefinition.Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseMethodSignature(); blob.WriteSerializedString(metadataReader.GetString(methodDefinition.Name)); blob.WriteCompressedInteger(CodedIndex.MemberRefParent(MetadataTokens.EntityHandle(GetAlternateStreamToken(MetadataTokens.GetToken(methodDefinition.GetDeclaringType()))))); } else if (handle.Kind == HandleKind.FieldDefinition) { flag = 0x0a000000; var fieldDefinition = metadataReader.GetFieldDefinition((FieldDefinitionHandle)handle); var sigBlob = metadataReader.GetBlobReader(fieldDefinition.Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseFieldSignature(); blob.WriteSerializedString(metadataReader.GetString(fieldDefinition.Name)); blob.WriteCompressedInteger(CodedIndex.MemberRefParent(MetadataTokens.EntityHandle(GetAlternateStreamToken(MetadataTokens.GetToken(fieldDefinition.GetDeclaringType()))))); } else if (handle.Kind == HandleKind.MethodSpecification) { flag = 0x2B000000; var methodSpecification = metadataReader.GetMethodSpecification((MethodSpecificationHandle)handle); var sigBlob = metadataReader.GetBlobReader(methodSpecification.Signature); blob.WriteCompressedInteger(MetadataTokens.GetRowNumber(MetadataTokens.EntityHandle(GetAlternateStreamToken(MetadataTokens.GetToken(methodSpecification.Method))))); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseMethodSpecSignature(); } else if (handle.Kind == HandleKind.StandaloneSignature) { flag = 0x11000000; var reader = wrappedMethod.Module.MetadataReader; var sigBlob = reader.GetBlobReader(reader.GetStandaloneSignature((StandaloneSignatureHandle)handle).Signature); EcmaSignatureTranslator sigTranslator = new EcmaSignatureTranslator(sigBlob, blob, GetAlternateStreamToken); sigTranslator.ParseMethodSignature(); } _alternateNonTypeRefStream.WriteBytes(blob.ToArray()); alternateToken = (_alternateNonTokenStrings.Count + 1) | flag; } _alternateNonTokenStrings.Add(token, alternateToken); } return(alternateToken); } }