/// <summary> /// Parse an arbitrary method signature. /// </summary> /// <param name="builder">Output string builder to receive the textual signature representation</param> private void ParseMethod(StringBuilder builder) { uint methodFlags = ReadUInt(); string owningTypeOverride = null; if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) { SignatureDecoder owningTypeDecoder = new SignatureDecoder(_metadataReader, _image, _offset); owningTypeOverride = owningTypeDecoder.ReadTypeSignature(); _offset = owningTypeDecoder._offset; } if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_SlotInsteadOfToken) != 0) { throw new NotImplementedException(); } if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken) != 0) { ParseMethodRefToken(builder, owningTypeOverride: owningTypeOverride); } else { ParseMethodDefToken(builder, owningTypeOverride: owningTypeOverride); } if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0) { uint typeArgCount = ReadUInt(); builder.Append("<"); for (int typeArgIndex = 0; typeArgIndex < typeArgCount; typeArgIndex++) { if (typeArgIndex != 0) { builder.Append(", "); } ParseType(builder); } builder.Append(">"); } if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained) != 0) { builder.Append(" @ "); ParseType(builder); } }
/// <summary> /// Initialize generic method instances with argument types and runtime function indices from InstanceMethodEntrypoints /// </summary> private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint) { if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS)) { return; } R2RSection instMethodEntryPointSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS]; int instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress); NativeParser parser = new NativeParser(Image, (uint)instMethodEntryPointsOffset); NativeHashtable instMethodEntryPoints = new NativeHashtable(Image, parser, (uint)(instMethodEntryPointsOffset + instMethodEntryPointSection.Size)); NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries(); NativeParser curParser = allEntriesEnum.GetNext(); while (!curParser.IsNull()) { SignatureDecoder decoder = new SignatureDecoder(this, (int)curParser.Offset); string owningType = null; uint methodFlags = decoder.ReadUInt(); if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) { owningType = decoder.ReadTypeSignature(); } if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_SlotInsteadOfToken) != 0) { throw new NotImplementedException(); } EntityHandle methodHandle; int rid = (int)decoder.ReadUInt(); if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken) != 0) { methodHandle = MetadataTokens.MemberReferenceHandle(rid); } else { methodHandle = MetadataTokens.MethodDefinitionHandle(rid); } string[] methodTypeArgs = null; if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0) { uint typeArgCount = decoder.ReadUInt(); methodTypeArgs = new string[typeArgCount]; for (int typeArgIndex = 0; typeArgIndex < typeArgCount; typeArgIndex++) { methodTypeArgs[typeArgIndex] = decoder.ReadTypeSignature(); } } string constrainedType = null; if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained) != 0) { constrainedType = decoder.ReadTypeSignature(); } int runtimeFunctionId; FixupCell[] fixups; GetRuntimeFunctionIndexFromOffset((int)decoder.Offset, out runtimeFunctionId, out fixups); R2RMethod method = new R2RMethod(R2RMethods.Count, this, methodHandle, runtimeFunctionId, owningType, constrainedType, methodTypeArgs, fixups); if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < isEntryPoint.Length) { isEntryPoint[method.EntryPointRuntimeFunctionId] = true; } R2RMethods.Add(method); InstanceMethods.Add(new InstanceMethod(curParser.LowHashcode, method)); curParser = allEntriesEnum.GetNext(); } }