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
case ILCode.Ldc_I8: case ILCode.Ldc_I8:
case ILCode.Ldc_R4: case ILCode.Ldc_R4:
case ILCode.Ldc_R8: case ILCode.Ldc_R8:
case ILCode.Ldc_Decimal:
return true; return true;
default: default:
return false; return false;

4
ICSharpCode.Decompiler/ILAst/ILInlining.cs

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

29
ICSharpCode.Decompiler/ILAst/NullableOperators.cs

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

Loading…
Cancel
Save