private List<Expression> GetDominatedExpressions(BinaryExpression assignment, IList<Expression> blockExpressions) { int assignmentIndex = blockExpressions.IndexOf(assignment); Expression assignedValue = assignment.Right; List<Expression> result = new List<Expression>(); //ExpressionTreeVisitor etv = new ExpressionTreeVisitor(); //IEnumerable<VariableReference> variablesUsed = etv.GetUsedVariables(assignedValue); //ICollection<ParameterReference> argumentsUsed = etv.GetUsedArguments(assignedValue); /// If this is some form of autoassignment if (ChangesAssignedExpression(assignment.Right, assignment.Left, assignment.Left)) { return result; } for (int i = assignmentIndex + 1; i < blockExpressions.Count; i++) { //TODO: Add breaks and checks Expression currentExpression = blockExpressions[i]; if (ChangesAssignedExpression(currentExpression, assignedValue, assignment.Left)) { break; } result.Add(blockExpressions[i]); } return result; }
private void ProcessBinaryExpression(BinaryExpression binaryExpression) { if (!binaryExpression.IsAssignmentExpression) { return; } if (binaryExpression.Left.CodeNodeType != CodeNodeType.VariableReferenceExpression) { return; } CodeNodeType rightCodeNodeType; if (binaryExpression.Right.IsArgumentReferenceToRefParameter()) { rightCodeNodeType = CodeNodeType.ArgumentReferenceExpression; } else { rightCodeNodeType = binaryExpression.Right.CodeNodeType; } VariableReference variableReference = (binaryExpression.Left as VariableReferenceExpression).Variable; if (this.variableToAssignedCodeNodeTypeMap.ContainsKey(variableReference)) { this.variableToAssignedCodeNodeTypeMap[variableReference] = rightCodeNodeType; } else { this.variableToAssignedCodeNodeTypeMap.Add(variableReference, rightCodeNodeType); } }
public override ICodeNode VisitBinaryExpression(BinaryExpression node) { if (node.Operator == BinaryOperator.Assign) { if (node.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression && asyncData.AwaiterVariables.Contains((node.Left as VariableReferenceExpression).Variable)) { VariableReference awaiterVariable = (node.Left as VariableReferenceExpression).Variable; if (node.Right.CodeNodeType == CodeNodeType.MethodInvocationExpression && (node.Right as MethodInvocationExpression).MethodExpression.Method.Name == "GetAwaiter") { Expression expression = null;//(Expression)Visit((node.Right as MethodInvocationExpression).MethodExpression.Target); MethodInvocationExpression methodInvocation = node.Right as MethodInvocationExpression; if (methodInvocation.MethodExpression.Target != null) { if(methodInvocation.Arguments.Count == 0) { expression = (Expression)Visit(methodInvocation.MethodExpression.Target); } } else { if (methodInvocation.Arguments.Count == 1) { expression = (Expression)Visit(methodInvocation.Arguments[0]); } } if (expression != null && matcherState == MatcherState.FindAwaitExpression) { currentAwaiterVariable = awaiterVariable; awaitedExpression = expression; matcherState = MatcherState.FindIsCompletedInvoke; return null; } } else if ( (node.Right.CodeNodeType == CodeNodeType.ObjectCreationExpression) || ((node.Right.CodeNodeType == CodeNodeType.LiteralExpression) && ((node.Right as LiteralExpression).Value == null)) ) { if ((matcherState & MatcherState.FindInitObj) == MatcherState.FindInitObj && currentAwaiterVariable == awaiterVariable) { matcherState ^= MatcherState.FindInitObj; return null; } } matcherState = MatcherState.Stopped; return node; } else if (node.Left.CodeNodeType == CodeNodeType.FieldReferenceExpression && (node.Left as FieldReferenceExpression).Field.Resolve() == asyncData.StateField || node.Right.CodeNodeType == CodeNodeType.ThisReferenceExpression) { return null; } } return base.VisitBinaryExpression(node); }
public override void VisitBinaryExpression(BinaryExpression node) { if (!node.IsAssignmentExpression || !CheckForAssignment(node)) { base.VisitBinaryExpression(node); } }
public override void VisitBinaryExpression(BinaryExpression node) { base.VisitBinaryExpression(node); if (node.Operator == BinaryOperator.Assign && node.Right.CodeNodeType == CodeNodeType.ArrayCreationExpression) { ArrayCreationExpression arrayCreation = node.Right as ArrayCreationExpression; bool isInitializerPresent = Utilities.IsInitializerPresent(arrayCreation.Initializer); if (node.Left.CodeNodeType == CodeNodeType.VariableDeclarationExpression) { VariableDeclarationExpression variableDeclaration = node.Left as VariableDeclarationExpression; node.Left = new ArrayVariableDeclarationExpression(variableDeclaration, arrayCreation.ElementType, arrayCreation.Dimensions.CloneExpressionsOnly(), isInitializerPresent, null); } if (node.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression) { VariableReferenceExpression variableReference = node.Left as VariableReferenceExpression; node.Left = new ArrayVariableReferenceExpression(variableReference, arrayCreation.ElementType, arrayCreation.Dimensions.CloneExpressionsOnly(), isInitializerPresent, null); } if (node.Left.CodeNodeType == CodeNodeType.FieldReferenceExpression) { FieldReferenceExpression fieldReference = node.Left as FieldReferenceExpression; node.Left = new ArrayAssignmentFieldReferenceExpression(fieldReference, arrayCreation.ElementType, arrayCreation.Dimensions.CloneExpressionsOnly(), isInitializerPresent, null); } } }
public override ICodeNode VisitBinaryExpression(BinaryExpression node) { if (node.IsAssignmentExpression) { return VisitAssignExpression(node); } return base.VisitBinaryExpression(node); }
public override ICodeNode VisitBinaryExpression(BinaryExpression node) { if (TryTransform(node)) { return node; } return base.VisitBinaryExpression(node); }
public static Expression Negate(Expression expression, TypeSystem typeSystem) { if (expression == null) { return null; } switch (expression.CodeNodeType) { case CodeNodeType.BinaryExpression: { BinaryExpression binaryExpression = (BinaryExpression)expression; if (IsMathOperator(binaryExpression.Operator)) { if (binaryExpression.ExpressionType.FullName == "System.Boolean") { return new UnaryExpression(UnaryOperator.LogicalNot, expression, null); } BinaryExpression result = new BinaryExpression(BinaryOperator.ValueEquality, expression, new LiteralExpression(0, typeSystem, null), typeSystem, null); return result; } return NegateBinaryExpression(expression, typeSystem); } case CodeNodeType.UnaryExpression: { return NegateUnaryExpression(expression, typeSystem); } case CodeNodeType.ConditionExpression: { return NegateConditionExpression(expression, typeSystem); } } if (expression.CodeNodeType == CodeNodeType.LiteralExpression && expression.ExpressionType.FullName == typeSystem.Boolean.FullName) { return new LiteralExpression(!(bool)(expression as LiteralExpression).Value, typeSystem, expression.UnderlyingSameMethodInstructions); } LiteralExpression literalExpression = expression.ExpressionType.GetDefaultValueExpression(typeSystem) as LiteralExpression; if (literalExpression != null) { if (literalExpression.ExpressionType.FullName == typeSystem.Boolean.FullName) { UnaryExpression unaryResult = new UnaryExpression(UnaryOperator.LogicalNot, expression, null); return unaryResult; } BinaryExpression result = new BinaryExpression(BinaryOperator.ValueEquality, expression, literalExpression, typeSystem, null); return result; } else { return new UnaryExpression(UnaryOperator.LogicalNot, expression, null); } }
protected bool IsAssignToVariableExpression(BinaryExpression theAssignExpression, out VariableReference theVariable) { theVariable = null; bool result = theAssignExpression != null && theAssignExpression.IsAssignmentExpression && (theAssignExpression.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression || theAssignExpression.Left.CodeNodeType == CodeNodeType.VariableDeclarationExpression); if (result) { theVariable = GetVariableReferenceFromExpression(theAssignExpression.Left); } return result; }
public override ICodeNode VisitBinaryExpression(BinaryExpression node) { if (node.IsAssignmentExpression) { if (node.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression) { node.Right = (Expression)Visit(node.Right); return node; } } return base.VisitBinaryExpression(node); }
//x = cond ? y : z; // //== // //if(cond) //{ // x = y; //} //else //{ // x = z; //} // //x - phi variable //y, z - expressions public bool TryMatchInternal(IfStatement theIfStatement, out Statement result) { result = null; if (theIfStatement == null) { return false; } VariableReference xVariableReference = null; VariableReference x1VariableReference = null; Expression yExpressionValue; Expression zExpressionValue; if (theIfStatement.Else == null || theIfStatement.Then.Statements.Count != 1 || theIfStatement.Else.Statements.Count != 1 || theIfStatement.Then.Statements[0].CodeNodeType != CodeNodeType.ExpressionStatement || theIfStatement.Else.Statements[0].CodeNodeType != CodeNodeType.ExpressionStatement) { return false; } BinaryExpression thenAssignExpression = (theIfStatement.Then.Statements[0] as ExpressionStatement).Expression as BinaryExpression; BinaryExpression elseAssignExpression = (theIfStatement.Else.Statements[0] as ExpressionStatement).Expression as BinaryExpression; if (!IsAssignToVariableExpression(thenAssignExpression, out x1VariableReference) || !IsAssignToVariableExpression(elseAssignExpression, out xVariableReference)) { return false; } if (xVariableReference != x1VariableReference) { return false; } if (!ShouldInlineExpressions(thenAssignExpression, elseAssignExpression)) { /// Although correct syntax, nesting ternary expressions makes the code very unreadable. return false; } yExpressionValue = GetRightExpressionMapped(thenAssignExpression); zExpressionValue = GetRightExpressionMapped(elseAssignExpression); ConditionExpression ternaryConditionExpression = new ConditionExpression(theIfStatement.Condition, yExpressionValue, zExpressionValue, null); BinaryExpression ternaryAssign = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(xVariableReference, null), ternaryConditionExpression, this.typeSystem, null); result = new ExpressionStatement(ternaryAssign) { Parent = theIfStatement.Parent }; FixContext(xVariableReference.Resolve(), 1, 0, result as ExpressionStatement); return true; }
private void InsertTopLevelParameterAssignments(BlockStatement block) { for (int i = 0; i < this.context.MethodContext.OutParametersToAssign.Count; i++) { ParameterDefinition parameter = this.context.MethodContext.OutParametersToAssign[i]; TypeReference nonPointerType = parameter.ParameterType.IsByReference ? parameter.ParameterType.GetElementType() : parameter.ParameterType; UnaryExpression parameterDereference = new UnaryExpression(UnaryOperator.AddressDereference, new ArgumentReferenceExpression(parameter, null), null); BinaryExpression assignExpression = new BinaryExpression(BinaryOperator.Assign, parameterDereference, nonPointerType.GetDefaultValueExpression(typeSystem), nonPointerType, typeSystem, null); block.AddStatementAt(i, new ExpressionStatement(assignExpression)); } }
public override void VisitBinaryExpression(BinaryExpression node) { base.VisitBinaryExpression(node); if (node.IsAssignmentExpression && node.Right.CodeNodeType == CodeNodeType.DelegateCreationExpression) { DelegateCreationExpression theDelegateCreation = (DelegateCreationExpression)node.Right; if (node.Left.HasType) { TypeReference leftType = node.Left.ExpressionType; if (CanInferTypeOfDelegateCreation(leftType)) { theDelegateCreation.TypeIsImplicitlyInferable = true; } } } }
public override ICodeNode VisitBinaryExpression(BinaryExpression node) { if (node.IsAssignmentExpression) { return VisitAssignExpression(node); } ICodeNode newNode = canCastStep.VisitBinaryExpression(node); if (newNode != null) return newNode; if (node.Operator == BinaryOperator.ValueEquality || node.Operator == BinaryOperator.ValueInequality) { return VisitCeqExpression(node); } return base.VisitBinaryExpression(node); }
public override ICodeNode VisitBinaryExpression(BinaryExpression node) { if (node.IsAssignmentExpression) { if (node.Left.CodeNodeType == CodeNodeType.FieldReferenceExpression) { FieldDefinition theFieldDef = (node.Left as FieldReferenceExpression).Field.Resolve(); if (theFieldDef != null && fieldsToRemove.ContainsKey(theFieldDef)) { throw new Exception("A caching field cannot be assigned more than once."); } } else if (node.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression) { if (variablesToRemove.ContainsKey((node.Left as VariableReferenceExpression).Variable)) { throw new Exception("A caching variable cannot be assigned more than once."); } } } return base.VisitBinaryExpression(node); }
public override void VisitBinaryExpression(BinaryExpression node) { if (!node.IsAssignmentExpression) { base.VisitBinaryExpression(node); return; } Visit(node.Right); if (this.searchResult != UsageFinderSearchResult.NotFound) { return; } if (CheckExpression(node.Left)) { this.searchResult = UsageFinderSearchResult.Assigned; } else { base.Visit(node.Left); } }
/// <summary> /// Adds the starting assignments to the newly introduced flag variables. /// </summary> /// <param name="body">The body of the method.</param> private void AddDefaultAssignmentsToNewConditionalVariables(BlockStatement body) { foreach (VariableDefinition variable in labelToVariable.Values) { ///Add assignments for every label variable. BinaryExpression defaultAssignment = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(variable, null), GetLiteralExpression(false), typeSystem, null); body.AddStatementAt(0, new ExpressionStatement(defaultAssignment)); } if (usedBreakVariable) { ///Add assignment for the break variable. BinaryExpression defaultBreakAssignment = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(breakVariable, null), GetLiteralExpression(false), typeSystem, null); body.AddStatementAt(0, new ExpressionStatement(defaultBreakAssignment)); } if (usedContinueVariable) { ///Add assignment for the continue variable. BinaryExpression defaultContinueAssignment = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(continueVariable, null), GetLiteralExpression(false), typeSystem, null); body.AddStatementAt(0, new ExpressionStatement(defaultContinueAssignment)); } }
private bool CheckForAssignment(BinaryExpression node) { if (node.Left.CodeNodeType == CodeNodeType.ArgumentReferenceExpression && (node.Left as ArgumentReferenceExpression).Parameter.ParameterType.IsByReference) { throw new Exception("Managed pointer usage not in SSA"); } if (node.Left.CodeNodeType != CodeNodeType.VariableReferenceExpression || !(node.Left as VariableReferenceExpression).Variable.VariableType.IsByReference) { return false; } VariableDefinition byRefVariable = (node.Left as VariableReferenceExpression).Variable.Resolve(); if (variableToAssignExpression.ContainsKey(byRefVariable)) { throw new Exception("Managed pointer usage not in SSA"); } variableToAssignExpression.Add(byRefVariable, node); return true; }
private bool TryGetAssignment(StatementCollection statements, int startIndex, out BinaryExpression binaryExpression) { binaryExpression = null; var statement = statements[startIndex]; if (statement.CodeNodeType != CodeNodeType.ExpressionStatement) { return false; } Expression firstExpression = (statement as ExpressionStatement).Expression; if (firstExpression.CodeNodeType != CodeNodeType.BinaryExpression) { return false; } var result = firstExpression as BinaryExpression; if (!result.IsAssignmentExpression) { return false; } if (!(result.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression || result.Left.CodeNodeType == CodeNodeType.VariableDeclarationExpression || result.Left.CodeNodeType == CodeNodeType.FieldReferenceExpression || result.Left.CodeNodeType == CodeNodeType.ThisReferenceExpression || result.Left.CodeNodeType == CodeNodeType.PropertyReferenceExpression || result.Left.CodeNodeType == CodeNodeType.ArgumentReferenceExpression || result.Left.CodeNodeType == CodeNodeType.UnaryExpression && (result.Left as UnaryExpression).Operand.CodeNodeType == CodeNodeType.ArgumentReferenceExpression)) { return false; } binaryExpression = result; return true; }
private bool IsForeachVariableAssignment(BinaryExpression assignment) { if (assignment == null) { return false; } Expression getCurrentInvocation; if (assignment.Right is CastExpression) { getCurrentInvocation = (assignment.Right as CastExpression).Expression; } else if (assignment.Right is MethodInvocationExpression || assignment.Right is PropertyReferenceExpression) { getCurrentInvocation = assignment.Right; } else { return false; } if (IsGetCurrent(getCurrentInvocation)) { VariableReferenceExpression variable = assignment.Left as VariableReferenceExpression; if (variable == null) { return false; } foreachVariable = variable.Variable.Resolve(); foreachVariableInstructions.AddRange(assignment.UnderlyingSameMethodInstructions); foreachVariableType = assignment.Right.ExpressionType; return true; } return false; }
public override void VisitBinaryExpression(BinaryExpression node) { Visit(node.Left); WriteSpace(); bool isOneSideNull = IsNull(node.Left) || IsNull(node.Right); string @operator = ToString(node.Operator, isOneSideNull); if (this.Language.IsOperatorKeyword(@operator)) { WriteKeyword(@operator); } else { Write(@operator); } if (node.Right.CodeNodeType == CodeNodeType.InitializerExpression) { StartInitializer(node.Right as InitializerExpression); } else { WriteSpace(); } Visit(node.Right); }
public override ICodeNode VisitBinaryExpression(BinaryExpression node) { node = (BinaryExpression)base.VisitBinaryExpression(node); if (!node.Left.HasType) { /// Tests, where the left part of the expression is event fail. return node; } TypeDefinition leftType = node.Left.ExpressionType.Resolve(); if (leftType == null) { return node; } if (leftType.IsEnum && !node.Left.ExpressionType.IsArray) { if (node.Right is LiteralExpression) { node.Right = EnumHelper.GetEnumExpression(leftType, (node.Right as LiteralExpression), typeSystem); } else if (node.Right is CastExpression && (node.Right as CastExpression).Expression is LiteralExpression) { node.Right = EnumHelper.GetEnumExpression(leftType, (node.Right as CastExpression).Expression as LiteralExpression, typeSystem); } } else { if (!node.Right.HasType) { // Tests, where the right part of the expression is delegate fail. return node; } TypeDefinition rightType = node.Right.ExpressionType.Resolve(); if (rightType == null) { return node; } if (rightType.IsEnum && !node.Right.ExpressionType.IsArray) { if (node.Left is LiteralExpression) { node.Left = EnumHelper.GetEnumExpression(rightType, (node.Left as LiteralExpression), typeSystem); } else if (node.Left is CastExpression && (node.Left as CastExpression).Expression is LiteralExpression) { node.Left = EnumHelper.GetEnumExpression(rightType, (node.Left as CastExpression).Expression as LiteralExpression, typeSystem); } } } return node; }
/// <summary> /// The method for updating BinaryExpression. /// </summary> /// <param name="expression">The binary expression to be updated.</param> /// <returns>Returns the updated binary expression.</returns> public override ICodeNode VisitBinaryExpression(BinaryExpression expression) { ///Update the nested expressions first. expression.Left = (Expression)Visit(expression.Left); expression.Right = (Expression)Visit(expression.Right); TypeReference leftType = expression.Left.ExpressionType; leftType = GetElementType(leftType); if (leftType != null) { /// Check for chars. if (leftType.FullName == typeSystem.Char.FullName) { if (expression.Right.CodeNodeType == CodeNodeType.LiteralExpression) { if (IsArithmeticOperator(expression.Operator)) { /// Might need to add cast to char at this point. // return new CastExpression(expression, typeSystem.Char); expression.ExpressionType = typeSystem.Char; return expression; } if (expression.Right.HasType) { TypeReference rightLitType = GetElementType(expression.Right.ExpressionType); if (leftType.FullName == rightLitType.FullName) { return expression; } } LiteralExpression right = expression.Right as LiteralExpression; expression.Right = GetLiteralExpression((char)((int)right.Value), right.MappedInstructions); } TypeReference rightType = GetElementType(expression.Right.ExpressionType); if (rightType.FullName != typeSystem.Char.FullName) { if (expression.Right.CodeNodeType == CodeNodeType.CastExpression && expression.Right.ExpressionType.FullName == typeSystem.UInt16.FullName) { ((CastExpression)expression.Right).TargetType = typeSystem.Char; } else { expression.Right = new CastExpression(expression.Right, typeSystem.Char, null); } } } /// Check for bools. if (leftType.FullName == typeSystem.Boolean.FullName) { if (expression.Right.CodeNodeType == CodeNodeType.LiteralExpression) { if (expression.Operator == BinaryOperator.ValueEquality || expression.Operator == BinaryOperator.ValueInequality || IsBooleanAssignmentOperator(expression.Operator)) { LiteralExpression right = expression.Right as LiteralExpression; bool newVal = true; if (right.Value == null || right.Value.Equals(0) || right.Value.Equals(false) || right.Value.Equals(null)) { newVal = false; } expression.Right = GetLiteralExpression(newVal, right.MappedInstructions); } if (expression.Operator == BinaryOperator.ValueEquality || expression.Operator == BinaryOperator.ValueInequality) { return SimplifyBooleanComparison(expression); } } } } if (expression.Operator == BinaryOperator.ValueEquality || expression.Operator == BinaryOperator.ValueInequality) { TypeReference rightType = GetElementType(expression.Right.ExpressionType); if (rightType != null && leftType != null && rightType.FullName != leftType.FullName) { return FixEqualityComparisonExpression(expression); } } ///Adds downcasts in pointer types. if (expression.IsAssignmentExpression) { if (NeedsPointerCast(expression)) { if (expression.Right.CodeNodeType == CodeNodeType.StackAllocExpression) { expression.Right.ExpressionType = expression.Left.ExpressionType; } else { expression.Right = new CastExpression(expression.Right, expression.Left.ExpressionType, null); } } else if (expression.Left.HasType) { if (expression.Left.ExpressionType.IsByReference || expression.Left.ExpressionType.IsPointer || expression.Left.ExpressionType.IsArray || !expression.Left.ExpressionType.IsPrimitive) { TypeDefinition leftResolved = expression.Left.ExpressionType.Resolve(); if (leftResolved != null && !leftResolved.IsEnum) { if (expression.Right is LiteralExpression) { LiteralExpression rightLit = expression.Right as LiteralExpression; if (rightLit.Value != null && rightLit.Value.Equals(0)) { expression.Right = new LiteralExpression(null, typeSystem, expression.Right.UnderlyingSameMethodInstructions); } } } } } } if (expression.Operator == BinaryOperator.GreaterThan && expression.MappedInstructions.Count() == 1 && expression.MappedInstructions.First().OpCode.Code == Code.Cgt_Un) { LiteralExpression literal = null; if (expression.Right.CodeNodeType == CodeNodeType.LiteralExpression) { literal = expression.Right as LiteralExpression; } else if (expression.Right.CodeNodeType == CodeNodeType.CastExpression) { CastExpression cast = expression.Right as CastExpression; if (cast.Expression.CodeNodeType == CodeNodeType.LiteralExpression) { literal = cast.Expression as LiteralExpression; } } if (literal != null) { if (literal.Value == null || literal.Value.Equals(0)) { expression.Operator = BinaryOperator.ValueInequality; } } } /// Adds cast to object if needed. if (expression.IsObjectComparison) { Expression left = expression.Left; Expression right = expression.Right; TypeReference leftUnresolvedReference; TypeReference rightUnresolvedReference; if (CheckForOverloadedEqualityOperators(expression.Left, out leftUnresolvedReference) && CheckForOverloadedEqualityOperators(expression.Right, out rightUnresolvedReference)) { expression.Left = new CastExpression(left, left.ExpressionType.Module.TypeSystem.Object, left.MappedInstructions, leftUnresolvedReference); expression.Right = new CastExpression(right, right.ExpressionType.Module.TypeSystem.Object, right.MappedInstructions, rightUnresolvedReference); } } return expression; }
/// <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 bool NeedsPointerCast(BinaryExpression expression) { if (!expression.Left.ExpressionType.IsPointer && !expression.Left.ExpressionType.IsByReference) { return false; } return expression.Left.ExpressionType.GetElementType().FullName != expression.Right.ExpressionType.GetElementType().FullName; }
/// <summary> /// Fixes expressions produced by ceq and beq. /// </summary> /// <param name="expression">The comparison expression.</param> /// <returns>Returns the updated binary expression.</returns> private ICodeNode FixEqualityComparisonExpression(BinaryExpression expression) { /// The generated expression is (ValueOnTopOfStack == 0) if (expression.Right is LiteralExpression) { TypeReference leftType = GetElementType(expression.Left.ExpressionType); if (leftType.FullName != typeSystem.Boolean.FullName) { /// Left type is not boolean TypeDefinition resolved = leftType.Resolve(); /// If the type is not primitive, the check should be against 'null', not against '0' if (leftType != null && !leftType.IsPrimitive && (resolved != null && !resolved.IsEnum)) { expression.Right = GetLiteralExpression(null, null); } /// The check against 0 is correct return expression; } /// At this point the left side of 'expression' is boolean LiteralExpression rightLiteral = expression.Right as LiteralExpression; if (rightLiteral.Value.Equals(0) || rightLiteral.Value.Equals(null)) { return new UnaryExpression(UnaryOperator.LogicalNot, expression.Left, null); } else { return expression.Left; } } return expression; }
/// <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; }
internal BinaryExpression VisitAssignExpression(BinaryExpression node) { Expression left = node.Left; TypeDefinition tr = left.ExpressionType.Resolve(); if (tr == null) { return null; } if (tr.BaseType!= null && tr.BaseType.Name == "MulticastDelegate") { Expression right = node.Right; MethodInvocationExpression methodInvocation = right as MethodInvocationExpression; if (right is CastExpression) { methodInvocation = (right as CastExpression).Expression as MethodInvocationExpression; } if (methodInvocation == null) { return null; } if (methodInvocation.Arguments.Count == 2) { Expression firstArgument = methodInvocation.Arguments[0]; Expression secondArgument = methodInvocation.Arguments[1]; BinaryOperator @operator; if (!AreTheSame(firstArgument, left)) { return null; } //if firstArgument == leftSide if (methodInvocation.MethodExpression.Method.Name == "Combine") { @operator = BinaryOperator.AddAssign; } else if (methodInvocation.MethodExpression.Method.Name == "Remove") { @operator = BinaryOperator.SubtractAssign; } else { return null; } List<Instruction> instructions = new List<Instruction>(node.MappedInstructions); instructions.AddRange(methodInvocation.InvocationInstructions); return new BinaryExpression(@operator, left, secondArgument, typeSystem, instructions); } } return null; }
ICodeNode BuildBinaryExpression(BinaryOperator @operator, Expression left, Expression right, TypeReference expressionType, IEnumerable<Instruction> instructions) { BinaryExpression result = new BinaryExpression(@operator, (Expression)codeTransformer.Visit(left), (Expression)codeTransformer.Visit(right), expressionType, typeSystem, instructions, true); if (result.IsComparisonExpression || result.IsLogicalExpression) { result.ExpressionType = left.ExpressionType.Module.TypeSystem.Boolean; } return result; }
public int CompareOperators(BinaryExpression other) { return this.OperatorPriority.CompareTo(other.OperatorPriority); }