Skip to content

Commit

Permalink
#36. Clone MethodDebugInformationo.
Browse files Browse the repository at this point in the history
  • Loading branch information
inversionhourglass committed Feb 22, 2024
1 parent e8bf4bc commit a6886cd
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 4 deletions.
43 changes: 43 additions & 0 deletions src/Rougamo.Fody/Extensions/MonoExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ namespace Rougamo.Fody
{
internal static class MonoExtension
{
private static readonly System.Reflection.ConstructorInfo _CtorMethodDebugInformation = typeof(MethodDebugInformation).GetConstructors(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Single();
private static readonly System.Reflection.FieldInfo _FieldVariableIndex = typeof(VariableDebugInformation).GetField("index", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
private static readonly System.Reflection.FieldInfo _FieldIndexVariable = typeof(VariableIndex).GetField("variable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

public static bool Is(this TypeReference typeRef, string fullName)
{
return typeRef.Resolve()?.FullName == fullName;
Expand Down Expand Up @@ -576,13 +580,15 @@ public static MethodDefinition Clone(this MethodDefinition methodDef, string met
}

var instructionMap = new Dictionary<Instruction, Instruction>();
var offsetMap = new Dictionary<int, Instruction>();
var brs = new List<Instruction>();
foreach (var instruction in methodDef.Body.Instructions)
{
var cloned = instruction.Clone();
clonedMethodDef.Body.Instructions.Add(cloned);

instructionMap[instruction] = cloned;
offsetMap[instruction.Offset] = cloned;
if (cloned.Operand != null)
{
if (map.TryGetValue(cloned.Operand, out var value))
Expand Down Expand Up @@ -614,7 +620,44 @@ public static MethodDefinition Clone(this MethodDefinition methodDef, string met
clonedMethodDef.Body.InitLocals = methodDef.Body.InitLocals;
clonedMethodDef.Body.MaxStackSize = methodDef.Body.MaxStackSize;

clonedMethodDef.DebugInformation = (MethodDebugInformation)_CtorMethodDebugInformation.Invoke(new object[] { clonedMethodDef });
foreach (var point in methodDef.DebugInformation.SequencePoints)
{
var clonedPoint = new SequencePoint(offsetMap[point.Offset], point.Document)
{
StartLine = point.StartLine,
StartColumn = point.StartColumn,
EndLine = point.EndLine,
EndColumn = point.EndColumn
};
clonedMethodDef.DebugInformation.SequencePoints.Add(clonedPoint);
}
clonedMethodDef.DebugInformation.Scope = methodDef.DebugInformation.Scope.Clone(offsetMap, map);

return clonedMethodDef;
}

public static ScopeDebugInformation Clone(this ScopeDebugInformation scope, Dictionary<int, Instruction> offsetMap, Dictionary<object, object> variableMap)
{
var start = scope.Start.IsEndOfMethod ? null : offsetMap[scope.Start.Offset];
var end = scope.End.IsEndOfMethod ? null : offsetMap[scope.End.Offset];
var clonedScope = new ScopeDebugInformation(start, end);
foreach (var constant in scope.Constants)
{
clonedScope.Constants.Add(constant);
}
foreach (var variable in scope.Variables)
{
var index = _FieldVariableIndex.GetValue(variable);
var variableDef = _FieldIndexVariable.GetValue(index);
clonedScope.Variables.Add(new VariableDebugInformation((VariableDefinition)variableMap[variableDef], variable.Name));
}
foreach (var childScope in scope.Scopes)
{
clonedScope.Scopes.Add(childScope.Clone(offsetMap, variableMap));
}

return clonedScope;
}
}
}
2 changes: 1 addition & 1 deletion src/Rougamo.Fody/LoadBasicReference.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Mono.Cecil.Rocks;
using Mono.Cecil.Cil;
using System;
using System.Collections.Generic;
using System.Diagnostics;
Expand Down
2 changes: 0 additions & 2 deletions src/Rougamo.Fody/ModuleWeaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ public partial class ModuleWeaver : BaseModuleWeaver
private MethodReference _methodMethodContextGetRetryCountRef;
private Dictionary<string, MethodReference> _methodIMosRef;

private Delegate _isMatch;

private List<RouType> _rouTypes;
private Config _config;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
Expand Down
9 changes: 8 additions & 1 deletion src/Rougamo.Fody/WeaveSync_Strict.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,23 @@ private void StrictSyncMethodWeave(RouMethod rouMethod)
var actualMethodDef = rouMethod.MethodDef.Clone($"$Rougamo_{rouMethod.MethodDef.Name}");
rouMethod.MethodDef.DeclaringType.Methods.Add(actualMethodDef);

//var swap = rouMethod.MethodDef.DebugInformation;
//actualMethodDef.DebugInformation = rouMethod.MethodDef.DebugInformation;
rouMethod.MethodDef.DebugInformation = null;

DebuggerStepThrough(rouMethod.MethodDef);

StrictSyncAdaptedCall(rouMethod, actualMethodDef);
}

private void StrictSyncAdaptedCall(RouMethod rouMethod, MethodDefinition methodDef)
{
var instructions = rouMethod.MethodDef.Body.Instructions;
var body = rouMethod.MethodDef.Body;
var instructions = body.Instructions;

instructions.Clear();
body.Variables.Clear();
body.ExceptionHandlers.Clear();

if (!methodDef.IsStatic) instructions.Add(Create(OpCodes.Ldarg_0));
foreach(var parameter in rouMethod.MethodDef.Parameters)
Expand Down

0 comments on commit a6886cd

Please sign in to comment.