Browse Source

Port DelegateConstruction and TransformArrayInitializers

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
b311ba5a44
  1. 10
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  2. 18
      ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs

10
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -19,6 +19,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.CSharp; using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
@ -137,13 +138,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!IsAnonymousMethod(decompilationContext.CurrentTypeDefinition, targetMethod)) if (!IsAnonymousMethod(decompilationContext.CurrentTypeDefinition, targetMethod))
return null; return null;
target = value.Arguments[0]; target = value.Arguments[0];
var methodDefinition = (Mono.Cecil.MethodDefinition)context.TypeSystem.GetCecil(targetMethod); if (targetMethod.MetadataToken.IsNil)
if (methodDefinition == null) return null;
var metadata = context.TypeSystem.GetMetadata();
var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)targetMethod.MetadataToken);
if (!methodDefinition.HasBody())
return null; return null;
var localTypeSystem = context.TypeSystem.GetSpecializingTypeSystem(targetMethod.Substitution); var localTypeSystem = context.TypeSystem.GetSpecializingTypeSystem(targetMethod.Substitution);
var ilReader = new ILReader(localTypeSystem); var ilReader = new ILReader(localTypeSystem);
ilReader.UseDebugSymbols = context.Settings.UseDebugSymbols; ilReader.UseDebugSymbols = context.Settings.UseDebugSymbols;
var function = ilReader.ReadIL(methodDefinition.Body, context.CancellationToken); var function = ilReader.ReadIL(context.TypeSystem.ModuleDefinition, (MethodDefinitionHandle)targetMethod.MetadataToken, context.TypeSystem.ModuleDefinition.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress), context.CancellationToken);
function.DelegateType = value.Method.DeclaringType; function.DelegateType = value.Method.DeclaringType;
function.CheckInvariant(ILPhase.Normal); function.CheckInvariant(ILPhase.Normal);

18
ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs

@ -319,11 +319,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true; return true;
} }
bool MatchInitializeArrayCall(ILInstruction instruction, out IMethod method, out ILVariable array, out Mono.Cecil.FieldReference field) bool MatchInitializeArrayCall(ILInstruction instruction, out IMethod method, out ILVariable array, out System.Reflection.Metadata.FieldDefinition field)
{ {
method = null; method = null;
array = null; array = null;
field = null; field = default;
Call call = instruction as Call; Call call = instruction as Call;
if (call == null || call.Arguments.Count != 2) if (call == null || call.Arguments.Count != 2)
return false; return false;
@ -337,22 +337,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
IMember member; IMember member;
if (!call.Arguments[1].MatchLdMemberToken(out member)) if (!call.Arguments[1].MatchLdMemberToken(out member))
return false; return false;
field = context.TypeSystem.GetCecil(member) as Mono.Cecil.FieldReference; if (member.MetadataToken.IsNil)
if (field == null)
return false; return false;
field = context.TypeSystem.GetMetadata().GetFieldDefinition((System.Reflection.Metadata.FieldDefinitionHandle)member.MetadataToken);
return true; return true;
} }
bool ForwardScanInitializeArrayRuntimeHelper(Block body, int pos, ILVariable array, IType arrayType, int[] arrayLength, out ILInstruction[] values, out int foundPos) bool ForwardScanInitializeArrayRuntimeHelper(Block body, int pos, ILVariable array, IType arrayType, int[] arrayLength, out ILInstruction[] values, out int foundPos)
{ {
ILVariable v2; if (MatchInitializeArrayCall(body.Instructions[pos], out var method, out var v2, out var field) && array == v2) {
IMethod method; if (field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA)) {
Mono.Cecil.FieldReference field;
if (MatchInitializeArrayCall(body.Instructions[pos], out method, out v2, out field) && array == v2) {
var fieldDef = field.ResolveWithinSameModule();
if (fieldDef != null && fieldDef.InitialValue != null) {
var valuesList = new List<ILInstruction>(); var valuesList = new List<ILInstruction>();
if (DecodeArrayInitializer(arrayType, array, fieldDef.InitialValue, arrayLength, valuesList)) { if (DecodeArrayInitializer(arrayType, array, field.GetInitialValue(context.TypeSystem.ModuleDefinition.Reader), arrayLength, valuesList)) {
values = valuesList.ToArray(); values = valuesList.ToArray();
foundPos = pos; foundPos = pos;
return true; return true;

Loading…
Cancel
Save