public void MemberRefParent() { Assert.Equal(0, CodedIndex.MemberRefParent(default(TypeDefinitionHandle))); Assert.Equal((0xffffff << 3) | 4, CodedIndex.MemberRefParent(MetadataTokens.TypeSpecificationHandle(0xffffff))); Assert.Equal(0x08 | 0, CodedIndex.MemberRefParent(MetadataTokens.TypeDefinitionHandle(1))); Assert.Equal(0x08 | 1, CodedIndex.MemberRefParent(MetadataTokens.TypeReferenceHandle(1))); Assert.Equal(0x08 | 2, CodedIndex.MemberRefParent(MetadataTokens.ModuleReferenceHandle(1))); Assert.Equal(0x08 | 3, CodedIndex.MemberRefParent(MetadataTokens.MethodDefinitionHandle(1))); Assert.Equal(0x08 | 4, CodedIndex.MemberRefParent(MetadataTokens.TypeSpecificationHandle(1))); }
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 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); } }