Browse Source

Move LocalFunctionDecompiler.GetStatement to Block.GetContainingStatement

Siegfried Pammer 2 months ago
parent
commit
3865b31fea
  1. 4
      ICSharpCode.Decompiler/IL/ControlFlow/AwaitInFinallyTransform.cs
  2. 16
      ICSharpCode.Decompiler/IL/Instructions/Block.cs
  3. 5
      ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs
  4. 15
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  5. 13
      ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
  6. 2
      ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs

4
ICSharpCode.Decompiler/IL/ControlFlow/AwaitInFinallyTransform.cs

@ -16,12 +16,10 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.FlowAnalysis;
using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
@ -109,7 +107,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (objectVariable.LoadCount != 1 || objectVariable.StoreCount > 2) if (objectVariable.LoadCount != 1 || objectVariable.StoreCount > 2)
continue; continue;
var beforeExceptionCaptureBlock = (Block)LocalFunctionDecompiler.GetStatement(objectVariable.LoadInstructions[0])?.Parent; var beforeExceptionCaptureBlock = Block.FindClosestBlock(objectVariable.LoadInstructions[0]);
if (beforeExceptionCaptureBlock == null) if (beforeExceptionCaptureBlock == null)
continue; continue;

16
ICSharpCode.Decompiler/IL/Instructions/Block.cs

@ -383,6 +383,22 @@ namespace ICSharpCode.Decompiler.IL
return null; return null;
} }
/// <summary>
/// Gets the closest ancestor that is child of a control-flow (top-level) Block.
/// Returns null, if the instruction is not a descendant of a Block.
/// </summary>
public static ILInstruction? GetContainingStatement(ILInstruction inst)
{
var curr = inst;
while (curr != null)
{
if (curr.Parent is Block { Kind: BlockKind.ControlFlow })
return curr;
curr = curr.Parent;
}
return null;
}
public bool MatchInlineAssignBlock([NotNullWhen(true)] out CallInstruction? call, [NotNullWhen(true)] out ILInstruction? value) public bool MatchInlineAssignBlock([NotNullWhen(true)] out CallInstruction? call, [NotNullWhen(true)] out ILInstruction? value)
{ {
call = null; call = null;

5
ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs

@ -16,9 +16,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
@ -107,7 +104,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// We are only interested in store "statements" copying the exception variable // We are only interested in store "statements" copying the exception variable
// without modifying it. // without modifying it.
var statement = LocalFunctionDecompiler.GetStatement(load); var statement = Block.GetContainingStatement(load);
if (!(statement is StLoc stloc)) if (!(statement is StLoc stloc))
{ {
i++; i++;

15
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -312,25 +312,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitNewObj(NewObj inst) protected internal override void VisitNewObj(NewObj inst)
{ {
Block block;
if (TransformSpanTCtorContainingStackAlloc(inst, out ILInstruction locallocSpan)) if (TransformSpanTCtorContainingStackAlloc(inst, out ILInstruction locallocSpan))
{ {
context.Step("new Span<T>(stackalloc) -> stackalloc Span<T>", inst); context.Step("new Span<T>(stackalloc) -> stackalloc Span<T>", inst);
inst.ReplaceWith(locallocSpan); inst.ReplaceWith(locallocSpan);
block = null; ILInstruction stmt = Block.GetContainingStatement(locallocSpan);
ILInstruction stmt = locallocSpan;
while (stmt.Parent != null)
{
if (stmt.Parent is Block b)
{
block = b;
break;
}
stmt = stmt.Parent;
}
// Special case to eliminate extra store // Special case to eliminate extra store
if (stmt.GetNextSibling() is StLoc storeStmt && storeStmt.Value is LdLoc) if (stmt.GetNextSibling() is StLoc storeStmt && storeStmt.Value is LdLoc)
ILInlining.InlineIfPossible(block, stmt.ChildIndex, context); ILInlining.InlineIfPossible((Block)stmt.Parent, stmt.ChildIndex, context);
return; return;
} }
if (TransformArrayInitializers.TransformSpanTArrayInitialization(inst, context, out var replacement)) if (TransformArrayInitializers.TransformSpanTArrayInitialization(inst, context, out var replacement))

13
ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs

@ -575,17 +575,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
&& TransformDisplayClassUsage.IsPotentialClosure(context.CurrentTypeDefinition, type); && TransformDisplayClassUsage.IsPotentialClosure(context.CurrentTypeDefinition, type);
} }
internal static ILInstruction GetStatement(ILInstruction inst)
{
while (inst.Parent != null)
{
if (inst.Parent is Block b && b.Kind == BlockKind.ControlFlow)
return inst;
inst = inst.Parent;
}
return inst;
}
LocalFunctionMethod ReduceToLocalFunction(IMethod method, int typeParametersToRemove) LocalFunctionMethod ReduceToLocalFunction(IMethod method, int typeParametersToRemove)
{ {
int parametersToRemove = 0; int parametersToRemove = 0;
@ -747,7 +736,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (variable.Kind == VariableKind.Parameter) if (variable.Kind == VariableKind.Parameter)
return null; return null;
if (type.Kind == TypeKind.Struct) if (type.Kind == TypeKind.Struct)
return GetStatement(variable.AddressInstructions.OrderBy(i => i.StartILOffset).First()); return Block.GetContainingStatement(variable.AddressInstructions.OrderBy(i => i.StartILOffset).First());
else else
return (StLoc)variable.StoreInstructions[0]; return (StLoc)variable.StoreInstructions[0];
} }

2
ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs

@ -604,7 +604,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (context.Settings.LocalFunctions && closureType?.Kind == TypeKind.Struct if (context.Settings.LocalFunctions && closureType?.Kind == TypeKind.Struct
&& variable.UsesInitialValue && IsPotentialClosure(context, closureType)) && variable.UsesInitialValue && IsPotentialClosure(context, closureType))
{ {
initializer = LocalFunctionDecompiler.GetStatement(variable.AddressInstructions.OrderBy(i => i.StartILOffset).First()); initializer = Block.GetContainingStatement(variable.AddressInstructions.OrderBy(i => i.StartILOffset).First());
return true; return true;
} }
return false; return false;

Loading…
Cancel
Save