Browse Source

Boolean logic decompilation improvement refactored to SimplifyTernaryOperator

pull/205/head
Pent Ploompuu 14 years ago
parent
commit
5bc2692ab7
  1. 20
      ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs
  2. 10
      ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs

20
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -911,26 +911,6 @@ namespace ICSharpCode.Decompiler.ILAst
} }
} }
if (expr.Code == ILCode.TernaryOp && TypeAnalysis.IsBoolean(expr.Arguments[2].InferredType) && (a = expr.Arguments[1]).Code == ILCode.Ldc_I4)
switch ((int)a.Operand) {
// "ternaryop(a, ldc.i4.0, b)" becomes "logicand(logicnot(a), b)" if the inferred type for expression "b" is boolean
case 0:
expr.Code = ILCode.LogicAnd;
a = new ILExpression(ILCode.LogicNot, null, expr.Arguments[0]) { ILRanges = a.ILRanges };
if (!SimplifyLogicNotArgument(a)) expr.Arguments[0] = a;
goto common;
// "ternaryop(a, ldc.i4.1, b)" becomes "logicor(a, b)" if the inferred type for expression "b" is boolean
case 1:
expr.Code = ILCode.LogicOr;
expr.ILRanges.AddRange(a.ILRanges);
common:
expr.Arguments.RemoveAt(1);
expr.InferredType = expr.Arguments[1].InferredType;
res = expr;
modified = true;
break;
}
return res; return res;
} }

10
ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs

@ -98,16 +98,16 @@ namespace ICSharpCode.Decompiler.ILAst
if (leftBoolVal != 0) { if (leftBoolVal != 0) {
newExpr = condExpr; newExpr = condExpr;
} else { } else {
newExpr = new ILExpression(ILCode.LogicNot, null, condExpr); newExpr = new ILExpression(ILCode.LogicNot, null, condExpr) { InferredType = typeSystem.Boolean };
} }
} else if (retTypeIsBoolean && trueExpr.Match(ILCode.Ldc_I4, out leftBoolVal)) { } else if ((retTypeIsBoolean || TypeAnalysis.IsBoolean(falseExpr.InferredType)) && trueExpr.Match(ILCode.Ldc_I4, out leftBoolVal) && (leftBoolVal == 0 || leftBoolVal == 1)) {
// It can be expressed as logical expression // It can be expressed as logical expression
if (leftBoolVal != 0) { if (leftBoolVal != 0) {
newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicOr, condExpr, falseExpr); newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicOr, condExpr, falseExpr);
} else { } else {
newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicAnd, new ILExpression(ILCode.LogicNot, null, condExpr), falseExpr); newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicAnd, new ILExpression(ILCode.LogicNot, null, condExpr), falseExpr);
} }
} else if (retTypeIsBoolean && falseExpr.Match(ILCode.Ldc_I4, out rightBoolVal)) { } else if ((retTypeIsBoolean || TypeAnalysis.IsBoolean(trueExpr.InferredType)) && falseExpr.Match(ILCode.Ldc_I4, out rightBoolVal) && (rightBoolVal == 0 || rightBoolVal == 1)) {
// It can be expressed as logical expression // It can be expressed as logical expression
if (rightBoolVal != 0) { if (rightBoolVal != 0) {
newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicOr, new ILExpression(ILCode.LogicNot, null, condExpr), trueExpr); newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicOr, new ILExpression(ILCode.LogicNot, null, condExpr), trueExpr);
@ -343,10 +343,10 @@ namespace ICSharpCode.Decompiler.ILAst
ILExpression current = right; ILExpression current = right;
while(current.Arguments[0].Match(code)) while(current.Arguments[0].Match(code))
current = current.Arguments[0]; current = current.Arguments[0];
current.Arguments[0] = new ILExpression(code, null, left, current.Arguments[0]); current.Arguments[0] = new ILExpression(code, null, left, current.Arguments[0]) { InferredType = typeSystem.Boolean };
return right; return right;
} else { } else {
return new ILExpression(code, null, left, right); return new ILExpression(code, null, left, right) { InferredType = typeSystem.Boolean };
} }
} }

Loading…
Cancel
Save