|
|
|
@ -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; |
|
|
|
|