Browse Source

#1336: Add limit in HandleSimpleArrayInitializer.

pull/1405/head
Siegfried Pammer 7 years ago
parent
commit
ab8c73b2f7
  1. 4
      ICSharpCode.Decompiler/IL/Transforms/DynamicCallSiteTransform.cs
  2. 4
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
  3. 20
      ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs

4
ICSharpCode.Decompiler/IL/Transforms/DynamicCallSiteTransform.cs

@ -322,7 +322,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
int numberOfTypeArguments = 0; int numberOfTypeArguments = 0;
if (!value.MatchLdNull()) { if (!value.MatchLdNull()) {
if (value is NewArr typeArgsNewArr && typeArgsNewArr.Type.IsKnownType(KnownTypeCode.Type) && typeArgsNewArr.Indices.Count == 1 && typeArgsNewArr.Indices[0].MatchLdcI4(out numberOfTypeArguments)) { if (value is NewArr typeArgsNewArr && typeArgsNewArr.Type.IsKnownType(KnownTypeCode.Type) && typeArgsNewArr.Indices.Count == 1 && typeArgsNewArr.Indices[0].MatchLdcI4(out numberOfTypeArguments)) {
if (!TransformArrayInitializers.HandleSimpleArrayInitializer(callSiteInitBlock, 3, variableOrTemporary, typeArgsNewArr.Type, numberOfTypeArguments, out var typeArguments, out _)) if (!TransformArrayInitializers.HandleSimpleArrayInitializer(context.Function, callSiteInitBlock, 3, variableOrTemporary, typeArgsNewArr.Type, numberOfTypeArguments, out var typeArguments, out _))
return false; return false;
int i = 0; int i = 0;
callSiteInfo.TypeArguments = new IType[numberOfTypeArguments]; callSiteInfo.TypeArguments = new IType[numberOfTypeArguments];
@ -496,7 +496,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (!(value is NewArr newArr2 && newArr2.Type.FullName == "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" && newArr2.Indices.Count == 1 && newArr2.Indices[0].MatchLdcI4(out var numberOfArguments))) if (!(value is NewArr newArr2 && newArr2.Type.FullName == "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" && newArr2.Indices.Count == 1 && newArr2.Indices[0].MatchLdcI4(out var numberOfArguments)))
return false; return false;
if (!TransformArrayInitializers.HandleSimpleArrayInitializer(callSiteInfo.InitBlock, instructionOffset, variable, newArr2.Type, numberOfArguments, out var arguments, out _)) if (!TransformArrayInitializers.HandleSimpleArrayInitializer(context.Function, callSiteInfo.InitBlock, instructionOffset, variable, newArr2.Type, numberOfArguments, out var arguments, out _))
return false; return false;
int i = 0; int i = 0;
callSiteInfo.ArgumentInfos = new CSharpArgumentInfo[numberOfArguments]; callSiteInfo.ArgumentInfos = new CSharpArgumentInfo[numberOfArguments];

4
ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

@ -90,7 +90,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return modified; return modified;
} }
static bool IsInConstructorInitializer(ILFunction function, ILInstruction inst, ref int? ctorCallStart) internal static bool IsInConstructorInitializer(ILFunction function, ILInstruction inst, ref int? ctorCallStart)
{ {
if (ctorCallStart == null) { if (ctorCallStart == null) {
if (function == null || !function.Method.IsConstructor) if (function == null || !function.Method.IsConstructor)
@ -109,7 +109,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return topLevelInst.ILRange.InclusiveEnd < ctorCallStart.GetValueOrDefault(); return topLevelInst.ILRange.InclusiveEnd < ctorCallStart.GetValueOrDefault();
} }
static bool IsCatchWhenBlock(Block block) internal static bool IsCatchWhenBlock(Block block)
{ {
var container = BlockContainer.FindClosestContainer(block); var container = BlockContainer.FindClosestContainer(block);
return container?.Parent is TryCatchHandler handler return container?.Parent is TryCatchHandler handler

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

@ -39,7 +39,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return; return;
this.context = context; this.context = context;
try { try {
if (DoTransform(block, pos)) if (DoTransform(context.Function, block, pos))
return; return;
if (DoTransformMultiDim(block, pos)) if (DoTransformMultiDim(block, pos))
return; return;
@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
} }
bool DoTransform(Block body, int pos) bool DoTransform(ILFunction function, Block body, int pos)
{ {
if (pos >= body.Instructions.Count - 2) if (pos >= body.Instructions.Count - 2)
return false; return false;
@ -66,7 +66,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true; return true;
} }
if (arrayLength.Length == 1) { if (arrayLength.Length == 1) {
if (HandleSimpleArrayInitializer(body, pos + 1, v, elementType, arrayLength[0], out values, out var instructionsToRemove)) { if (HandleSimpleArrayInitializer(function, body, pos + 1, v, elementType, arrayLength[0], out values, out var instructionsToRemove)) {
context.Step("HandleSimpleArrayInitializer", inst); context.Step("HandleSimpleArrayInitializer", inst);
var block = new Block(BlockKind.ArrayInitializer); var block = new Block(BlockKind.ArrayInitializer);
var tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type); var tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type);
@ -277,7 +277,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// <summary> /// <summary>
/// Handle simple case where RuntimeHelpers.InitializeArray is not used. /// Handle simple case where RuntimeHelpers.InitializeArray is not used.
/// </summary> /// </summary>
internal static bool HandleSimpleArrayInitializer(Block block, int pos, ILVariable store, IType elementType, int length, out ILInstruction[] values, out int elementCount) internal static bool HandleSimpleArrayInitializer(ILFunction function, Block block, int pos, ILVariable store, IType elementType, int length, out ILInstruction[] values, out int elementCount)
{ {
elementCount = 0; elementCount = 0;
values = new ILInstruction[length]; values = new ILInstruction[length];
@ -309,7 +309,17 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
if (pos + elementCount >= block.Instructions.Count) if (pos + elementCount >= block.Instructions.Count)
return false; return false;
return elementCount > 0; return ShouldTransformToInitializer(function, block, pos, elementCount, length);
}
static bool ShouldTransformToInitializer(ILFunction function, Block block, int startPos, int elementCount, int length)
{
if (elementCount >= Math.Min(length / 3 + 5, length))
return true;
int? unused = null;
if (ILInlining.IsCatchWhenBlock(block) || ILInlining.IsInConstructorInitializer(function, block.Instructions[startPos], ref unused))
return true;
return false;
} }
bool HandleJaggedArrayInitializer(Block block, int pos, ILVariable store, IType elementType, int length, out ILVariable finalStore, out ILInstruction[] values, out int instructionsToRemove) bool HandleJaggedArrayInitializer(Block block, int pos, ILVariable store, IType elementType, int length, out ILVariable finalStore, out ILInstruction[] values, out int instructionsToRemove)

Loading…
Cancel
Save