Browse Source

Adjust array initializer pattern to 'dup' changes.

pull/100/head
Daniel Grunwald 15 years ago
parent
commit
ea5c790991
  1. 22
      ICSharpCode.Decompiler/ILAst/ArrayInitializers.cs
  2. 3
      ICSharpCode.Decompiler/ILAst/ILInlining.cs

22
ICSharpCode.Decompiler/ILAst/ArrayInitializers.cs

@ -17,11 +17,9 @@ namespace ICSharpCode.Decompiler.ILAst
public static PeepholeTransform Transform(ILBlock method) public static PeepholeTransform Transform(ILBlock method)
{ {
var newArrPattern = new StoreToVariable(new ILExpression(ILCode.Newarr, ILExpression.AnyOperand, new ILExpression(ILCode.Ldc_I4, ILExpression.AnyOperand))); var newArrPattern = new StoreToVariable(new ILExpression(ILCode.Newarr, ILExpression.AnyOperand, new ILExpression(ILCode.Ldc_I4, ILExpression.AnyOperand)));
var arg1 = new StoreToVariable(new LoadFromVariable(newArrPattern)) { MustBeGenerated = true };
var arg2 = new StoreToVariable(new LoadFromVariable(newArrPattern)) { MustBeGenerated = true };
var initializeArrayPattern = new ILCall( var initializeArrayPattern = new ILCall(
"System.Runtime.CompilerServices.RuntimeHelpers", "InitializeArray", "System.Runtime.CompilerServices.RuntimeHelpers", "InitializeArray",
new LoadFromVariable(arg1), new ILExpression(ILCode.Ldtoken, ILExpression.AnyOperand)); new LoadFromVariable(newArrPattern), new ILExpression(ILCode.Ldtoken, ILExpression.AnyOperand));
return delegate(ILBlock block, ref int i) { return delegate(ILBlock block, ref int i) {
if (!newArrPattern.Match(block.Body[i])) if (!newArrPattern.Match(block.Body[i]))
@ -30,13 +28,11 @@ namespace ICSharpCode.Decompiler.ILAst
int arrayLength = (int)newArrInst.Arguments[0].Operand; int arrayLength = (int)newArrInst.Arguments[0].Operand;
if (arrayLength == 0) if (arrayLength == 0)
return; return;
if (arg1.Match(block.Body.ElementAtOrDefault(i + 1)) && arg2.Match(block.Body.ElementAtOrDefault(i + 2))) { if (initializeArrayPattern.Match(block.Body.ElementAtOrDefault(i + 1))) {
if (initializeArrayPattern.Match(block.Body.ElementAtOrDefault(i + 3))) { if (HandleStaticallyInitializedArray(newArrPattern, block, i, newArrInst, arrayLength)) {
if (HandleStaticallyInitializedArray(arg2, block, i, newArrInst, arrayLength)) { i -= new ILInlining(method).InlineInto(block, i + 1) - 1;
i -= new ILInlining(method).InlineInto(block, i + 1) - 1;
}
return;
} }
return;
} }
if (i + 1 + arrayLength > block.Body.Count) if (i + 1 + arrayLength > block.Body.Count)
return; return;
@ -78,9 +74,9 @@ namespace ICSharpCode.Decompiler.ILAst
} }
} }
static bool HandleStaticallyInitializedArray(StoreToVariable arg2, ILBlock block, int i, ILExpression newArrInst, int arrayLength) static bool HandleStaticallyInitializedArray(StoreToVariable newArrPattern, ILBlock block, int i, ILExpression newArrInst, int arrayLength)
{ {
FieldDefinition field = ((ILExpression)block.Body[i + 3]).Arguments[1].Operand as FieldDefinition; FieldDefinition field = ((ILExpression)block.Body[i + 1]).Arguments[1].Operand as FieldDefinition;
if (field == null || field.InitialValue == null) if (field == null || field.InitialValue == null)
return false; return false;
switch (TypeAnalysis.GetTypeCode(newArrInst.Operand as TypeReference)) { switch (TypeAnalysis.GetTypeCode(newArrInst.Operand as TypeReference)) {
@ -91,8 +87,8 @@ namespace ICSharpCode.Decompiler.ILAst
for (int j = 0; j < newArr.Length; j++) { for (int j = 0; j < newArr.Length; j++) {
newArr[j] = new ILExpression(ILCode.Ldc_I4, BitConverter.ToInt32(field.InitialValue, j * 4)); newArr[j] = new ILExpression(ILCode.Ldc_I4, BitConverter.ToInt32(field.InitialValue, j * 4));
} }
block.Body[i] = new ILExpression(ILCode.Stloc, arg2.LastVariable, new ILExpression(ILCode.InitArray, newArrInst.Operand, newArr)); block.Body[i] = new ILExpression(ILCode.Stloc, newArrPattern.LastVariable, new ILExpression(ILCode.InitArray, newArrInst.Operand, newArr));
block.Body.RemoveRange(i + 1, 3); block.Body.RemoveAt(i + 1);
return true; return true;
} }
break; break;

3
ICSharpCode.Decompiler/ILAst/ILInlining.cs

@ -224,7 +224,7 @@ namespace ICSharpCode.Decompiler.ILAst
public void CopyPropagation() public void CopyPropagation()
{ {
foreach (ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) { foreach (ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
for (int i = block.Body.Count - 1; i >= 0; i--) { for (int i = 0; i < block.Body.Count; i++) {
ILVariable v; ILVariable v;
ILExpression ldArg; ILExpression ldArg;
if (block.Body[i].Match(ILCode.Stloc, out v, out ldArg) if (block.Body[i].Match(ILCode.Stloc, out v, out ldArg)
@ -241,6 +241,7 @@ namespace ICSharpCode.Decompiler.ILAst
block.Body.RemoveAt(i); block.Body.RemoveAt(i);
InlineInto(block, i); // maybe inlining gets possible after the removal of block.Body[i] InlineInto(block, i); // maybe inlining gets possible after the removal of block.Body[i]
i--;
} }
} }
} }

Loading…
Cancel
Save