Browse Source

Do not detect array initializer if element type and store type do not match.

pull/1012/head
Siegfried Pammer 8 years ago
parent
commit
7ad556e0bf
  1. 28
      ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs

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

@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
if (arrayLength.Length == 1) {
int instructionsToRemove;
if (HandleSimpleArrayInitializer(body, pos + 1, v, arrayLength[0], out values, out instructionsToRemove)) {
if (HandleSimpleArrayInitializer(body, pos + 1, v, elementType, arrayLength[0], out values, out instructionsToRemove)) {
context.Step("HandleSimpleArrayInitializer", inst);
var block = new Block(BlockKind.ArrayInitializer);
var tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type);
@ -85,7 +85,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -85,7 +85,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILInlining.InlineIfPossible(body, pos, context);
return true;
}
if (HandleJaggedArrayInitializer(body, pos + 1, v, arrayLength[0], out ILVariable finalStore, out values, out instructionsToRemove)) {
if (HandleJaggedArrayInitializer(body, pos + 1, v, elementType, arrayLength[0], out ILVariable finalStore, out values, out instructionsToRemove)) {
context.Step("HandleJaggedArrayInitializer", inst);
var block = new Block(BlockKind.ArrayInitializer);
var tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type);
@ -163,7 +163,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -163,7 +163,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// <summary>
/// Handle simple case where RuntimeHelpers.InitializeArray is not used.
/// </summary>
bool HandleSimpleArrayInitializer(Block block, int pos, ILVariable store, int length, out ILInstruction[] values, out int instructionsToRemove)
bool HandleSimpleArrayInitializer(Block block, int pos, ILVariable store, IType elementType, int length, out ILInstruction[] values, out int instructionsToRemove)
{
instructionsToRemove = 0;
values = null;
@ -171,12 +171,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -171,12 +171,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
int index = 0;
int elementCount = 0;
for (int i = pos; i < block.Instructions.Count; i++) {
ILInstruction target, value;
IType type;
if (index >= length)
break;
if (!block.Instructions[i].MatchStObj(out target, out value, out type) || value.Descendants.OfType<IInstructionWithVariableOperand>().Any(inst => inst.Variable == store))
if (!block.Instructions[i].MatchStObj(out ILInstruction target, out ILInstruction value, out IType type) || value.Descendants.OfType<IInstructionWithVariableOperand>().Any(inst => inst.Variable == store))
break;
if (!type.Equals(elementType))
return false;
var ldelem = target as LdElema;
if (ldelem == null || !ldelem.Array.MatchLdLoc(store) || ldelem.Indices.Count != 1 || !ldelem.Indices[0].MatchLdcI4(out index))
break;
@ -190,22 +190,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -190,22 +190,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return elementCount > 0;
}
bool HandleJaggedArrayInitializer(Block block, int pos, ILVariable store, 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)
{
instructionsToRemove = 0;
finalStore = null;
values = new ILInstruction[length];
ILInstruction initializer;
IType type;
for (int i = 0; i < length; i++) {
ILVariable temp;
ILInstruction storeLoad;
// 1. Instruction: (optional) temporary copy of store
bool hasTemporaryCopy = block.Instructions[pos].MatchStLoc(out temp, out storeLoad) && storeLoad.MatchLdLoc(store);
bool hasTemporaryCopy = block.Instructions[pos].MatchStLoc(out ILVariable temp, out ILInstruction storeLoad) && storeLoad.MatchLdLoc(store);
if (hasTemporaryCopy) {
if (!MatchJaggedArrayStore(block, pos + 1, temp, i, out initializer))
if (!MatchJaggedArrayStore(block, pos + 1, temp, i, out initializer, out type) || !elementType.Equals(type))
return false;
} else {
if (!MatchJaggedArrayStore(block, pos, store, i, out initializer))
if (!MatchJaggedArrayStore(block, pos, store, i, out initializer, out type) || !elementType.Equals(type))
return false;
}
values[i] = initializer;
@ -224,13 +224,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -224,13 +224,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true;
}
bool MatchJaggedArrayStore(Block block, int pos, ILVariable store, int index, out ILInstruction initializer)
bool MatchJaggedArrayStore(Block block, int pos, ILVariable store, int index, out ILInstruction initializer, out IType type)
{
initializer = null;
type = null;
// 3. Instruction: stobj(ldelema(ldloc temp, ldc.i4 0), ldloc tempArrayLoad)
var finalInstruction = block.Instructions.ElementAtOrDefault(pos + 1);
ILInstruction tempAccess, tempArrayLoad;
IType type;
ILVariable initializerStore;
if (finalInstruction == null || !finalInstruction.MatchStObj(out tempAccess, out tempArrayLoad, out type) || !tempArrayLoad.MatchLdLoc(out initializerStore))
return false;

Loading…
Cancel
Save