Browse Source

Decompile all lifted operators on nullable values. Postfix increment/decrement and custom type conversions support incomplete, but correct.

pull/205/head
Pent Ploompuu 15 years ago
parent
commit
d226afb26d
  1. 1
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  2. 4
      ICSharpCode.Decompiler/ILAst/ILInlining.cs
  3. 29
      ICSharpCode.Decompiler/ILAst/NullableOperators.cs

1
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -701,6 +701,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -701,6 +701,7 @@ namespace ICSharpCode.Decompiler.ILAst
case ILCode.Ldc_I8:
case ILCode.Ldc_R4:
case ILCode.Ldc_R8:
case ILCode.Ldc_Decimal:
return true;
default:
return false;

4
ICSharpCode.Decompiler/ILAst/ILInlining.cs

@ -436,8 +436,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -436,8 +436,8 @@ namespace ICSharpCode.Decompiler.ILAst
}
return true;
default:
// abort, inlining is not possible
return false;
// instructions with no side-effects are safe (except for Ldloc and Ldloca which are handled separately)
return expr.HasNoSideEffects();
}
}

29
ICSharpCode.Decompiler/ILAst/NullableOperators.cs

@ -236,7 +236,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -236,7 +236,7 @@ namespace ICSharpCode.Decompiler.ILAst
bool IsCustomOperator(string s)
{
if (s.Length < 11 || !s.StartsWith("op_", StringComparison.Ordinal)) return false;
if (s.Length < 10 || !s.StartsWith("op_", StringComparison.Ordinal)) return false;
switch (s) {
case "op_Equality":
return type == OperatorType.Equality;
@ -257,9 +257,12 @@ namespace ICSharpCode.Decompiler.ILAst @@ -257,9 +257,12 @@ namespace ICSharpCode.Decompiler.ILAst
case "op_ExclusiveOr":
case "op_LeftShift":
case "op_RightShift":
case "op_Negation":
case "op_UnaryNegation":
case "op_UnaryPlus":
case "op_LogicalNot":
case "op_OnesComplement":
case "op_Increment":
case "op_Decrement":
return type == OperatorType.Other;
default: return false;
}
@ -332,8 +335,10 @@ namespace ICSharpCode.Decompiler.ILAst @@ -332,8 +335,10 @@ namespace ICSharpCode.Decompiler.ILAst
sealed class BooleanPattern : Pattern
{
public static readonly Pattern False = new BooleanPattern(false), True = new BooleanPattern(true);
readonly object value;
public BooleanPattern(bool value)
BooleanPattern(bool value)
: base(null)
{
this.value = Convert.ToInt32(value);
@ -420,23 +425,29 @@ namespace ICSharpCode.Decompiler.ILAst @@ -420,23 +425,29 @@ namespace ICSharpCode.Decompiler.ILAst
/* only one operand nullable */
// & (bool)
new ILPattern(ILCode.TernaryOp, Any, VariableA, new MethodPattern(ILCode.Newobj, ".ctor", new BooleanPattern(false))),
new ILPattern(ILCode.TernaryOp, Any, VariableA, new MethodPattern(ILCode.Newobj, ".ctor", BooleanPattern.False)),
new ILPattern(ILCode.And, VariableA, Any),
// | (bool)
new ILPattern(ILCode.TernaryOp, Any, new MethodPattern(ILCode.Newobj, ".ctor", new BooleanPattern(true)), VariableA),
new ILPattern(ILCode.TernaryOp, Any, new MethodPattern(ILCode.Newobj, ".ctor", BooleanPattern.True), VariableA),
new ILPattern(ILCode.Or, VariableA, Any),
// == true
VariableAGetValueOrDefault & VariableAHasValue,
new ILPattern(ILCode.Ceq, VariableA, new BooleanPattern(true)),
new ILPattern(ILCode.Ceq, VariableA, BooleanPattern.True),
// != true
!VariableAGetValueOrDefault | !VariableAHasValue,
new ILPattern(ILCode.Cne, VariableA, new BooleanPattern(true)),
new ILPattern(ILCode.Cne, VariableA, BooleanPattern.True),
// == false
!VariableAGetValueOrDefault & VariableAHasValue,
new ILPattern(ILCode.Ceq, VariableA, new BooleanPattern(false)),
new ILPattern(ILCode.Ceq, VariableA, BooleanPattern.False),
// != false
VariableAGetValueOrDefault | !VariableAHasValue,
new ILPattern(ILCode.Cne, VariableA, new BooleanPattern(false)),
new ILPattern(ILCode.Cne, VariableA, BooleanPattern.False),
// ?? true
!VariableAHasValue | VariableAGetValueOrDefault,
new ILPattern(ILCode.NullCoalescing, VariableA, BooleanPattern.True),
// ?? false
VariableAHasValue & VariableAGetValueOrDefault,
new ILPattern(ILCode.NullCoalescing, VariableA, BooleanPattern.False),
// null coalescing
new ILPattern(ILCode.TernaryOp, VariableAHasValue, VariableAGetValueOrDefault, Any),
new ILPattern(ILCode.NullCoalescing, VariableA, Any),

Loading…
Cancel
Save