Browse Source

PortablePdbWriter: Add primitive support for state-machine hoisted local scopes. All variables are visible in the whole MoveNext method.

pull/1967/head
Siegfried Pammer 5 years ago
parent
commit
413c5b3baf
  1. 24
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
  2. 1
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

24
ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -31,7 +31,6 @@ using System.Text; @@ -31,7 +31,6 @@ using System.Text;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.TypeSystem;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
@ -58,7 +57,7 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -58,7 +57,7 @@ namespace ICSharpCode.Decompiler.DebugInfo
var emptyList = new List<SequencePoint>();
var localScopes = new List<(MethodDefinitionHandle Method, ImportScopeInfo Import, int Offset, int Length, HashSet<ILVariable> Locals)>();
var stateMachineMethods = new List<(MethodDefinitionHandle MoveNextMethod, MethodDefinitionHandle KickoffMethod)>();
var customDocumentDebugInfo = new List<(DocumentHandle Parent, GuidHandle Guid, BlobHandle Blob)>();
var customDebugInfo = new List<(EntityHandle Parent, GuidHandle Guid, BlobHandle Blob)>();
var customMethodDebugInfo = new List<(MethodDefinitionHandle Parent, GuidHandle Guid, BlobHandle Blob)>();
var globalImportScope = metadata.AddImportScope(default, default);
@ -93,7 +92,7 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -93,7 +92,7 @@ namespace ICSharpCode.Decompiler.DebugInfo
language: metadata.GetOrAddGuid(KnownGuids.CSharpLanguageGuid));
// Add embedded source to the PDB
customDocumentDebugInfo.Add((document,
customDebugInfo.Add((document,
metadata.GetOrAddGuid(KnownGuids.EmbeddedSource),
sourceBlob));
@ -111,6 +110,11 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -111,6 +110,11 @@ namespace ICSharpCode.Decompiler.DebugInfo
(MethodDefinitionHandle)function.MoveNextMethod.MetadataToken,
(MethodDefinitionHandle)function.Method.MetadataToken
));
customDebugInfo.Add((
function.MoveNextMethod.MetadataToken,
metadata.GetOrAddGuid(KnownGuids.StateMachineHoistedLocalScopes),
metadata.GetOrAddBlob(BuildStateMachineHoistedLocalScopes(function))
));
}
if (function.IsAsync) {
customMethodDebugInfo.Add((methodHandle,
@ -161,8 +165,8 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -161,8 +165,8 @@ namespace ICSharpCode.Decompiler.DebugInfo
foreach (var row in customMethodDebugInfo) {
metadata.AddCustomDebugInformation(row.Parent, row.Guid, row.Blob);
}
customDocumentDebugInfo.SortBy(row => MetadataTokens.GetRowNumber(row.Parent));
foreach (var row in customDocumentDebugInfo) {
customDebugInfo.SortBy(row => MetadataTokens.GetRowNumber(row.Parent));
foreach (var row in customDebugInfo) {
metadata.AddCustomDebugInformation(row.Parent, row.Guid, row.Blob);
}
@ -194,6 +198,16 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -194,6 +198,16 @@ namespace ICSharpCode.Decompiler.DebugInfo
}
}
static BlobBuilder BuildStateMachineHoistedLocalScopes(ILFunction function)
{
var builder = new BlobBuilder();
foreach (var variable in function.Variables.Where(v => v.StateMachineField != null).OrderBy(v => MetadataTokens.GetRowNumber(v.StateMachineField.MetadataToken))) {
builder.WriteUInt32(0);
builder.WriteUInt32((uint)function.CodeSize);
}
return builder;
}
static BlobHandle WriteSourceToBlob(MetadataBuilder metadata, string sourceText, out byte[] sourceCheckSum)
{
var builder = new BlobBuilder();

1
ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

@ -532,6 +532,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -532,6 +532,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
ILFunction moveNextFunction = CreateILAst(moveNextMethod, context);
function.MoveNextMethod = moveNextFunction.Method;
function.CodeSize = moveNextFunction.CodeSize;
// Copy-propagate temporaries holding a copy of 'this'.
// This is necessary because the old (pre-Roslyn) C# compiler likes to store 'this' in temporary variables.

Loading…
Cancel
Save