private bool IsBinaryExpression(Expression expression, out Expression binaryExpression, out bool isWrappedInUnary) { binaryExpression = null; isWrappedInUnary = false; V_0 = expression as BinaryExpression; V_1 = expression as UnaryExpression; if (V_0 != null) { binaryExpression = V_0; return(true); } if (V_1 == null || V_1.get_Operator() != 11 && V_1.get_Operator() != 1 || V_1.get_Operand() as BinaryExpression == null) { return(false); } if (V_1.get_Operator() != 1) { binaryExpression = V_1.get_Operand(); } else { binaryExpression = Negator.Negate(V_1.get_Operand(), this.typeSystem); if (binaryExpression as BinaryExpression == null) { isWrappedInUnary = true; } } return(true); }
private static Expression NegateConditionExpression(Expression expression, TypeSystem typeSystem) { stackVariable1 = (ConditionExpression)expression; stackVariable1.set_Then(Negator.Negate(stackVariable1.get_Then(), typeSystem)); stackVariable1.set_Else(Negator.Negate(stackVariable1.get_Else(), typeSystem)); return stackVariable1; }
private static Expression NegateUnaryExpression(Expression expression, TypeSystem typeSystem) { V_0 = (UnaryExpression)expression; V_1 = V_0.get_Operator(); if (V_1 == 1) { V_0.set_Operator(11); return V_0; } if (V_1 != 8 && V_1 != 11) { throw new ArgumentException("expression"); } if (V_0.get_Operand().get_CodeNodeType() == 24) { V_2 = Negator.NegateBinaryExpression(V_0.get_Operand() as BinaryExpression, typeSystem); V_0.set_Operand(V_2); return V_0; } if (V_0.get_Operand().get_CodeNodeType() != 23 || (V_0.get_Operand() as UnaryExpression).get_Operator() != 1) { V_0.set_Operator(1); } else { V_0.set_Operand((V_0.get_Operand() as UnaryExpression).get_Operand()); } return V_0; }
private void TryMergeExpressions(ConditionStatement node) { if (!(node.Condition is UnaryExpression)) { return; } UnaryExpression unaryExpression = (UnaryExpression)node.Condition; if (unaryExpression.Operator != UnaryOperator.LogicalNot) { return; } if (unaryExpression.Operand is MethodInvocationExpression || unaryExpression.Operand is PropertyReferenceExpression) { return; } if (!IsConditionExpression(unaryExpression.Operand)) { return; } node.Condition = Negator.Negate(unaryExpression.Operand, typeSystem); }
private void InvertIfStatement(IfStatement theIf) { theIf.Condition = Negator.Negate(theIf.Condition, context.MethodContext.Method.Module.TypeSystem); BlockStatement swap = theIf.Else; theIf.Else = theIf.Then; theIf.Then = swap; }
private void InvertIfStatement(IfStatement theIf) { theIf.set_Condition(Negator.Negate(theIf.get_Condition(), this.context.get_MethodContext().get_Method().get_Module().get_TypeSystem())); V_0 = theIf.get_Else(); theIf.set_Else(theIf.get_Then()); theIf.set_Then(V_0); return; }
private Expression SimplifyBooleanComparison(BinaryExpression expression) { V_0 = this.IsFalse(expression.get_Right()); if (!V_0 || expression.get_Operator() != 9 && V_0 || expression.get_Operator() != 10) { return expression; } V_1 = new List<Instruction>(expression.get_MappedInstructions()); V_1.AddRange(expression.get_Right().get_UnderlyingSameMethodInstructions()); return Negator.Negate(expression.get_Left(), this.typeSystem).CloneAndAttachInstructions(V_1); }
/// <summary> /// Simplifies boolean expressions. /// </summary> /// <param name="expression">The expression to be simplified.</param> /// <returns>Returns the simplified expression.</returns> private Expression SimplifyBooleanComparison(BinaryExpression expression) { bool isFalse = IsFalse(expression.Right); if (isFalse && expression.Operator == BinaryOperator.ValueEquality || !isFalse && expression.Operator == BinaryOperator.ValueInequality) { List <Instruction> instructions = new List <Instruction>(expression.MappedInstructions); instructions.AddRange(expression.Right.UnderlyingSameMethodInstructions); return(Negator.Negate(expression.Left, typeSystem).CloneAndAttachInstructions(instructions)); } return(expression); }
private static Expression NegateBinaryExpression(Expression expression, TypeSystem typeSystem) { V_0 = (BinaryExpression)expression; if (Negator.IsLogicalOperator(V_0.get_Operator())) { if (V_0.get_Operator() == 12) { stackVariable48 = 11; } else { stackVariable48 = 12; } V_2 = stackVariable48; V_0.set_Left(Negator.Negate(V_0.get_Left(), typeSystem)); V_0.set_Operator(V_2); V_0.set_Right(Negator.Negate(V_0.get_Right(), typeSystem)); return V_0; } if (!Negator.IsBitwiseOperator(V_0.get_Operator()) || !String.op_Equality(V_0.get_ExpressionType().get_FullName(), typeSystem.get_Boolean().get_FullName())) { if (!Negator.TryGetInverseOperator(V_0.get_Operator(), out V_1)) { throw new ArgumentException("expression"); } V_0.set_Operator(V_1); return V_0; } if (V_0.get_Operator() != 23) { V_0.set_Left(Negator.Negate(V_0.get_Left(), typeSystem)); stackVariable32 = V_0; if (V_0.get_Operator() == 22) { stackVariable36 = 21; } else { stackVariable36 = 22; } stackVariable32.set_Operator(stackVariable36); V_0.set_Right(Negator.Negate(V_0.get_Right(), typeSystem)); } else { V_0.set_Operator(9); } return V_0; }
public static Expression Negate(Expression expression, TypeSystem typeSystem) { if (expression == null) { return null; } V_1 = expression.get_CodeNodeType(); if (V_1 == 23) { return Negator.NegateUnaryExpression(expression, typeSystem); } if (V_1 == 24) { V_2 = (BinaryExpression)expression; if (!Negator.IsMathOperator(V_2.get_Operator())) { return Negator.NegateBinaryExpression(expression, typeSystem); } if (String.op_Equality(V_2.get_ExpressionType().get_FullName(), "System.Boolean")) { return new UnaryExpression(1, expression, null); } return new BinaryExpression(9, expression, new LiteralExpression((object)0, typeSystem, null), typeSystem, null, false); } if (V_1 == 36) { return Negator.NegateConditionExpression(expression, typeSystem); } if (expression.get_CodeNodeType() == 22 && String.op_Equality(expression.get_ExpressionType().get_FullName(), typeSystem.get_Boolean().get_FullName())) { return new LiteralExpression((object)(!(Boolean)(expression as LiteralExpression).get_Value()), typeSystem, expression.get_UnderlyingSameMethodInstructions()); } V_0 = expression.get_ExpressionType().GetDefaultValueExpression(typeSystem) as LiteralExpression; if (V_0 == null) { return new UnaryExpression(1, expression, null); } if (String.op_Equality(V_0.get_ExpressionType().get_FullName(), typeSystem.get_Boolean().get_FullName())) { return new UnaryExpression(1, expression, null); } return new BinaryExpression(9, expression, V_0, typeSystem, null, false); }
private void TryMergeExpressions(ConditionStatement node) { if (node.get_Condition() as UnaryExpression == null) { return; } V_0 = (UnaryExpression)node.get_Condition(); if (V_0.get_Operator() != 1) { return; } if (V_0.get_Operand() as MethodInvocationExpression != null || V_0.get_Operand() as PropertyReferenceExpression != null) { return; } if (!this.IsConditionExpression(V_0.get_Operand())) { return; } node.set_Condition(Negator.Negate(V_0.get_Operand(), this.typeSystem)); return; }
private bool IsBinaryExpression(Expression expression, out Expression binaryExpression, out bool isWrappedInUnary) { binaryExpression = null; isWrappedInUnary = false; BinaryExpression nestedBinary = expression as BinaryExpression; UnaryExpression nestedUnary = expression as UnaryExpression; if (nestedBinary != null) { binaryExpression = nestedBinary; return(true); } else if (nestedUnary != null && (nestedUnary.Operator == UnaryOperator.None || nestedUnary.Operator == UnaryOperator.LogicalNot) && nestedUnary.Operand is BinaryExpression) { if (nestedUnary.Operator == UnaryOperator.LogicalNot) { binaryExpression = Negator.Negate(nestedUnary.Operand, typeSystem); if (!(binaryExpression is BinaryExpression)) { // Currently the only boolean expression that cannot be negated (without wrapping it in unary with logical not) // is binary expression with XOR operator. isWrappedInUnary = true; } } else { binaryExpression = nestedUnary.Operand; } return(true); } return(false); }
/// <summary> /// Fixes expressions, generated for brtrue and brfalse. As 0,false and null are all represented as 0 in IL, this step adds the correct constant /// to the expression. /// </summary> /// <param name="expression">The expression.</param> /// <param name="isBrTrue">The type of jump.</param> /// <returns>Returns the fixed expression.</returns> private ICodeNode FixBranchingExpression(Expression expression, Instruction branch) { /// example: /// before the step: /// ... /// a //a is int32, opperation is brfalse /// After the step: /// ... /// a == 0 bool isBrTrue = branch.OpCode.Code == Code.Brtrue || branch.OpCode.Code == Code.Brtrue_S; TypeReference expressionType = expression.ExpressionType; BinaryExpression newCondition; BinaryOperator operation = BinaryOperator.ValueEquality; Instruction[] instructions = new Instruction[] { branch }; if (isBrTrue) { operation = BinaryOperator.ValueInequality; } if (expressionType.Name == "Boolean" || expressionType.Name.Contains("Boolean ")) { Expression operand; if (!isBrTrue) { operand = Negator.Negate(expression, typeSystem); } else { operand = expression; } Expression result; if (expression is SafeCastExpression) { result = new BinaryExpression(operation, expression, GetLiteralExpression(false, null), typeSystem, instructions); } else { result = new UnaryExpression(UnaryOperator.None, operand, instructions); } return(result); } if (expressionType.Name == "Char") { newCondition = new BinaryExpression(operation, expression, GetLiteralExpression('\u0000', null), typeSystem, instructions); newCondition.ExpressionType = typeSystem.Boolean; } if (!expressionType.IsPrimitive) { TypeDefinition expressionTypeDefinition = expressionType.Resolve(); /// expressionTypeDefinition can resolve to null when dealing with generics if (expressionTypeDefinition != null && expressionTypeDefinition.IsEnum && !expressionType.IsArray) { ///Find the field that corresponds to 0 FieldDefinition field = null; foreach (FieldDefinition enumField in expressionTypeDefinition.Fields) { if (enumField.Constant != null && enumField.Constant.Value != null && enumField.Constant.Value.Equals(0)) { field = enumField; break; } } if (field == null) { newCondition = new BinaryExpression(operation, expression, GetLiteralExpression(0, null), typeSystem, instructions); newCondition.ExpressionType = typeSystem.Boolean; } else { newCondition = new BinaryExpression(operation, expression, new EnumExpression(field, null), typeSystem, instructions); newCondition.ExpressionType = typeSystem.Boolean; } } else { /// If it is not primitive class, then the check should be against null newCondition = new BinaryExpression(operation, expression, GetLiteralExpression(null, null), typeSystem, instructions); newCondition.ExpressionType = typeSystem.Boolean; } } else { /// This is primitive type, the check should be against 0 newCondition = new BinaryExpression(operation, expression, GetLiteralExpression(0, null), typeSystem, instructions); newCondition.ExpressionType = typeSystem.Boolean; } return(newCondition); }
private bool TryTransformTernary(ConditionExpression ternary, out Expression transformed) { transformed = null; LiteralExpression literal; bool isLiteralInThen; LiteralExpression literalInThen = ternary.Then as LiteralExpression; LiteralExpression literalInElse = ternary.Else as LiteralExpression; // Transforms the case: Method() && someVar > 12 ? 0 : 1 if (literalInThen != null && literalInElse != null) { bool areValidValues = false; bool shouldBeNegated = false; if (literalInThen.ExpressionType.FullName == Constants.Int32 && literalInElse.ExpressionType.FullName == Constants.Int32) { int valueInThen = (int)literalInThen.Value; int valueInElse = (int)literalInElse.Value; if ((valueInThen == 0 && valueInElse == 1) || (valueInThen == 1 && valueInElse == 0)) { areValidValues = true; if (valueInThen == 0 && valueInElse == 1) { shouldBeNegated = true; } } } else if (literalInThen.ExpressionType.FullName == Constants.Boolean && literalInElse.ExpressionType.FullName == Constants.Boolean) { bool valueInThen = (bool)literalInThen.Value; bool valueInElse = (bool)literalInElse.Value; if ((valueInThen == false && valueInElse == true) || (valueInThen == true && valueInElse == false)) { areValidValues = true; if (valueInThen == false && valueInElse == true) { shouldBeNegated = true; } } } if (areValidValues) { if (shouldBeNegated) { transformed = Transform(Negator.Negate(ternary.Condition, typeSystem)); } else { transformed = Transform(ternary.Condition); } return(true); } } if (literalInThen != null) { literal = literalInThen; isLiteralInThen = true; } else if (literalInElse != null) { literal = literalInElse; isLiteralInThen = false; } else // Transforms the case: someCondition ? (int)boolVar1 : (int)boolVar2 { CastExpression thenCast = ternary.Then as CastExpression; CastExpression elseCast = ternary.Else as CastExpression; if (thenCast != null && elseCast != null && thenCast.TargetType.FullName == Constants.Int32 && thenCast.Expression.ExpressionType.FullName == Constants.Boolean && elseCast.TargetType.FullName == Constants.Int32 && elseCast.Expression.ExpressionType.FullName == Constants.Boolean) { ternary.Then = thenCast.Expression; ternary.Else = elseCast.Expression; transformed = ternary; return(true); } return(false); } bool isTrueLikeValue; if (literal.ExpressionType.FullName == Constants.Int32) { isTrueLikeValue = (int)literal.Value != 0 ? true : false; } else if (literal.ExpressionType.FullName == Constants.Boolean) { isTrueLikeValue = (bool)literal.Value; } else { return(false); } BinaryOperator newOperator; Expression newLeft = null; Expression newRight = null; newLeft = Transform(ternary.Condition); Expression expression; if (isLiteralInThen) { expression = ternary.Else; } else { expression = ternary.Then; } ConditionExpression nestedTernary = expression as ConditionExpression; CastExpression castExpression = expression as CastExpression; Expression nestedBinaryAsExpression = null; bool isNestedBinaryInUnary = false; if (nestedTernary == null && (castExpression == null || castExpression.TargetType.FullName != Constants.Int32 || castExpression.Expression.ExpressionType.FullName != Constants.Boolean) && !IsBinaryExpression(expression, out nestedBinaryAsExpression, out isNestedBinaryInUnary) && expression.ExpressionType.FullName != Constants.Boolean) { return(false); } bool isRightTransformed = false; if (castExpression != null) { newRight = castExpression.Expression; isRightTransformed = true; } else { if (nestedBinaryAsExpression != null) { BinaryExpression nestedBinary = GetBinaryExpression(isNestedBinaryInUnary, nestedBinaryAsExpression); if (TryTransformBinary(nestedBinary)) { newRight = GetResultExpression(isNestedBinaryInUnary, nestedBinaryAsExpression, nestedBinary); isRightTransformed = true; } } else if (nestedTernary != null && TryTransformTernary(nestedTernary, out newRight)) { isRightTransformed = true; } } if (!isRightTransformed) { newRight = expression; } if (newLeft == null || newRight == null) { return(false); } if (isTrueLikeValue) { newOperator = BinaryOperator.LogicalOr; newLeft = isLiteralInThen ? newLeft : Negator.Negate(newLeft, this.typeSystem); } else { newOperator = BinaryOperator.LogicalAnd; newLeft = isLiteralInThen ? Negator.Negate(newLeft, this.typeSystem) : newLeft; } transformed = new BinaryExpression(newOperator, newLeft, newRight, this.typeSystem, ternary.MappedInstructions); return(true); }
private bool TryTransformTernary(ConditionExpression ternary, out Expression transformed) { transformed = null; V_2 = ternary.get_Then() as LiteralExpression; V_3 = ternary.get_Else() as LiteralExpression; if (V_2 != null && V_3 != null) { V_14 = false; V_15 = false; if (!String.op_Equality(V_2.get_ExpressionType().get_FullName(), "System.Int32") || !String.op_Equality(V_3.get_ExpressionType().get_FullName(), "System.Int32")) { if (String.op_Equality(V_2.get_ExpressionType().get_FullName(), "System.Boolean") && String.op_Equality(V_3.get_ExpressionType().get_FullName(), "System.Boolean")) { V_18 = (Boolean)V_2.get_Value(); V_19 = (Boolean)V_3.get_Value(); if (!V_18 && V_19 || V_18 && !V_19) { V_14 = true; if (!V_18 && V_19) { V_15 = true; } } } } else { V_16 = (Int32)V_2.get_Value(); V_17 = (Int32)V_3.get_Value(); if (V_16 == 0 && V_17 == 1 || V_16 == 1 && V_17 == 0) { V_14 = true; if (V_16 == 0 && V_17 == 1) { V_15 = true; } } } if (V_14) { if (!V_15) { transformed = this.Transform(ternary.get_Condition()); } else { transformed = this.Transform(Negator.Negate(ternary.get_Condition(), this.typeSystem)); } return(true); } } if (V_2 == null) { if (V_3 == null) { V_20 = ternary.get_Then() as ExplicitCastExpression; V_21 = ternary.get_Else() as ExplicitCastExpression; if (V_20 == null || V_21 == null || !String.op_Equality(V_20.get_TargetType().get_FullName(), "System.Int32") || !String.op_Equality(V_20.get_Expression().get_ExpressionType().get_FullName(), "System.Boolean") || !String.op_Equality(V_21.get_TargetType().get_FullName(), "System.Int32") || !String.op_Equality(V_21.get_Expression().get_ExpressionType().get_FullName(), "System.Boolean")) { return(false); } ternary.set_Then(V_20.get_Expression()); ternary.set_Else(V_21.get_Expression()); transformed = ternary; return(true); } V_0 = V_3; V_1 = false; } else { V_0 = V_2; V_1 = true; } if (!String.op_Equality(V_0.get_ExpressionType().get_FullName(), "System.Int32")) { if (!String.op_Equality(V_0.get_ExpressionType().get_FullName(), "System.Boolean")) { return(false); } V_4 = (Boolean)V_0.get_Value(); } else { if ((Int32)V_0.get_Value() != 0) { stackVariable163 = true; } else { stackVariable163 = false; } V_4 = stackVariable163; } V_6 = null; V_7 = null; V_6 = this.Transform(ternary.get_Condition()); if (!V_1) { V_8 = ternary.get_Then(); } else { V_8 = ternary.get_Else(); } V_9 = V_8 as ConditionExpression; V_10 = V_8 as ExplicitCastExpression; V_11 = null; V_12 = false; if (V_9 == null && V_10 == null || String.op_Inequality(V_10.get_TargetType().get_FullName(), "System.Int32") || String.op_Inequality(V_10.get_Expression().get_ExpressionType().get_FullName(), "System.Boolean") && !this.IsBinaryExpression(V_8, out V_11, out V_12) && String.op_Inequality(V_8.get_ExpressionType().get_FullName(), "System.Boolean")) { return(false); } V_13 = false; if (V_10 == null) { if (V_11 == null) { if (V_9 != null && this.TryTransformTernary(V_9, out V_7)) { V_13 = true; } } else { V_22 = TransformCatchClausesFilterExpressionStep.GetBinaryExpression(V_12, V_11); if (this.TryTransformBinary(V_22)) { V_7 = TransformCatchClausesFilterExpressionStep.GetResultExpression(V_12, V_11, V_22); V_13 = true; } } } else { V_7 = V_10.get_Expression(); V_13 = true; } if (!V_13) { V_7 = V_8; } if (V_6 == null || V_7 == null) { return(false); } if (!V_4) { V_5 = 12; if (V_1) { stackVariable97 = Negator.Negate(V_6, this.typeSystem); } else { stackVariable97 = V_6; } V_6 = stackVariable97; } else { V_5 = 11; if (V_1) { stackVariable111 = V_6; } else { stackVariable111 = Negator.Negate(V_6, this.typeSystem); } V_6 = stackVariable111; } transformed = new BinaryExpression(V_5, V_6, V_7, this.typeSystem, ternary.get_MappedInstructions(), false); return(true); }
private ICodeNode FixBranchingExpression(Expression expression, Instruction branch) { if (branch.get_OpCode().get_Code() == 57) { stackVariable5 = true; } else { V_5 = branch.get_OpCode(); stackVariable5 = V_5.get_Code() == 44; } V_0 = stackVariable5; V_1 = expression.get_ExpressionType(); V_3 = 9; stackVariable10 = new Instruction[1]; stackVariable10[0] = branch; V_4 = stackVariable10; if (V_0) { V_3 = 10; } if (String.op_Equality(V_1.get_Name(), "Boolean") || V_1.get_Name().Contains("Boolean ")) { if (V_0) { V_6 = expression; } else { V_6 = Negator.Negate(expression, this.typeSystem); } if (expression as SafeCastExpression == null) { V_7 = new UnaryExpression(11, V_6, V_4); } else { V_7 = new BinaryExpression(V_3, expression, this.GetLiteralExpression(false, null), this.typeSystem, V_4, false); } return V_7; } if (String.op_Equality(V_1.get_Name(), "Char")) { V_2 = new BinaryExpression(V_3, expression, this.GetLiteralExpression('\0', null), this.typeSystem, V_4, false); V_2.set_ExpressionType(this.typeSystem.get_Boolean()); } if (V_1.get_IsPrimitive()) { V_2 = new BinaryExpression(V_3, expression, this.GetLiteralExpression(0, null), this.typeSystem, V_4, false); V_2.set_ExpressionType(this.typeSystem.get_Boolean()); } else { V_8 = V_1.Resolve(); if (V_8 == null || !V_8.get_IsEnum() || V_1.get_IsArray()) { V_2 = new BinaryExpression(V_3, expression, this.GetLiteralExpression(null, null), this.typeSystem, V_4, false); V_2.set_ExpressionType(this.typeSystem.get_Boolean()); } else { V_9 = null; V_10 = V_8.get_Fields().GetEnumerator(); try { while (V_10.MoveNext()) { V_11 = V_10.get_Current(); if (V_11.get_Constant() == null || V_11.get_Constant().get_Value() == null || !V_11.get_Constant().get_Value().Equals(0)) { continue; } V_9 = V_11; goto Label0; } } finally { V_10.Dispose(); } Label0: if (V_9 != null) { V_2 = new BinaryExpression(V_3, expression, new EnumExpression(V_9, null), this.typeSystem, V_4, false); V_2.set_ExpressionType(this.typeSystem.get_Boolean()); } else { V_2 = new BinaryExpression(V_3, expression, this.GetLiteralExpression(0, null), this.typeSystem, V_4, false); V_2.set_ExpressionType(this.typeSystem.get_Boolean()); } } } return V_2; }