//private string WriteCSharpFromAST(IExpression expression) { // SourceEmitterOutputString sourceEmitterOutput = new SourceEmitterOutputString(); // SourceEmitter CSSourceEmitter = new SourceEmitter(sourceEmitterOutput); // ExpressionSimplifier es = new ExpressionSimplifier(); // expression = es.Rewrite(expression); // CSSourceEmitter.Traverse(expression); // return sourceEmitterOutput.Data; //} //private string WriteVBFromAST(IExpression expression) { // var sourceEmitterOutput = new VBSourceEmitter.SourceEmitterOutputString(); // var VBSourceEmitter = new VBSourceEmitter.SourceEmitter(this.host, sourceEmitterOutput); // var es = new ExpressionSimplifier(); // expression = es.Rewrite(expression); // VBSourceEmitter.Traverse(expression); // return sourceEmitterOutput.Data; //} /// <summary> /// Writes the exception thrown by this IPrecondition into an "exception" xml element. /// </summary> public void WriteExceptionTo(XmlWriter writer) { if (String.IsNullOrEmpty(this.exception)) return; writer.WriteStartElement("exception"); writer.WriteAttributeString("cref", this.exception); if (!String.IsNullOrEmpty(this.precondition.OriginalSource)) writer.WriteString(BooleanExpressionHelper.NegatePredicate(this.precondition.OriginalSource)); else { this.docTracker.WriteLine("Warning: Writing exception, but no OriginalSource found."); //Emit the condition instead of the OriginalSource SourceEmitterOutputString sourceEmitterOutput = new SourceEmitterOutputString(); SourceEmitter CSSourceEmitter = new SourceEmitter(sourceEmitterOutput); ExpressionSimplifier es = new ExpressionSimplifier(); LogicalNot logicalNot = new LogicalNot(); logicalNot.Operand = this.precondition.Condition; var condition = es.Rewrite(logicalNot); CSSourceEmitter.Traverse(condition); writer.WriteString(sourceEmitterOutput.Data); } writer.WriteEndElement(); }
/// <summary> /// Visits the specified logical not. /// </summary> /// <param name="logicalNot">The logical not.</param> public override void Visit(ILogicalNot logicalNot) { LogicalNot mutableLogicalNot = new LogicalNot(logicalNot); this.resultExpression = this.myCodeCopier.DeepCopy(mutableLogicalNot); }
/// <summary> /// Visits the specified logical not. /// </summary> /// <param name="logicalNot">The logical not.</param> /// <returns></returns> protected virtual IExpression DeepCopy(LogicalNot logicalNot) { return this.DeepCopy((UnaryOperation)logicalNot); }
internal static IExpression InvertCondition(IExpression expression) { Contract.Requires(expression != null); Contract.Ensures(Contract.Result<IExpression>() != null); var binOp = expression as IBinaryOperation; if (binOp != null) return InvertBinaryOperation(binOp); var conditional = expression as Conditional; if (conditional != null) return InvertConditional(conditional); var compileTimeConst = expression as CompileTimeConstant; if (compileTimeConst != null) return InvertCompileTimeConstant(compileTimeConst); var logNot = expression as ILogicalNot; if (logNot != null) return logNot.Operand; var logicalNot = new LogicalNot(); logicalNot.Operand = expression; logicalNot.Type = expression.Type; logicalNot.Locations.AddRange(expression.Locations); return logicalNot; }
private static IExpression InvertBinaryOperation(IBinaryOperation binOp) { Contract.Requires(binOp != null); Contract.Ensures(Contract.Result<IExpression>() != null); BinaryOperation/*?*/ result = null; if (binOp is IEquality && binOp.LeftOperand.Type.TypeCode != PrimitiveTypeCode.Float32 && binOp.LeftOperand.Type.TypeCode != PrimitiveTypeCode.Float64) result = new NotEquality(); else if (binOp is INotEquality && binOp.LeftOperand.Type.TypeCode != PrimitiveTypeCode.Float32 && binOp.LeftOperand.Type.TypeCode != PrimitiveTypeCode.Float64) result = new Equality(); else if (binOp is ILessThan) result = new GreaterThanOrEqual() { IsUnsignedOrUnordered = KeepUnsignedButInvertUnordered(((ILessThan)binOp).IsUnsignedOrUnordered, binOp) }; else if (binOp is ILessThanOrEqual) result = new GreaterThan() { IsUnsignedOrUnordered = KeepUnsignedButInvertUnordered(((ILessThanOrEqual)binOp).IsUnsignedOrUnordered, binOp) }; else if (binOp is IGreaterThan) result = new LessThanOrEqual() { IsUnsignedOrUnordered = KeepUnsignedButInvertUnordered(((IGreaterThan)binOp).IsUnsignedOrUnordered, binOp) }; else if (binOp is IGreaterThanOrEqual) result = new LessThan() { IsUnsignedOrUnordered = KeepUnsignedButInvertUnordered(((IGreaterThanOrEqual)binOp).IsUnsignedOrUnordered, binOp) }; if (result != null) { result.LeftOperand = binOp.LeftOperand; result.RightOperand = binOp.RightOperand; result.Type = binOp.Type; result.Locations.AddRange(binOp.Locations); return result; } LogicalNot logicalNot = new LogicalNot(); logicalNot.Operand = binOp; logicalNot.Type = binOp.Type; logicalNot.Locations.AddRange(binOp.Locations); return logicalNot; }
private bool ReplaceShortCircuitAnd2(BlockStatement b) { Contract.Requires(b != null); bool replacedPattern = false; var statements = b.Statements; for (int i = 0; i < statements.Count-3; i++) { var ifStatement = statements[i] as ConditionalStatement; if (ifStatement == null) continue; var gotoFalseCase = ifStatement.FalseBranch as GotoStatement; if (gotoFalseCase == null) continue; Contract.Assume(ifStatement.TrueBranch is EmptyStatement); var labeledStatement = statements[i+1] as LabeledStatement; if (labeledStatement == null) continue; var gotos = this.gotosThatTarget[(uint)labeledStatement.Label.UniqueKey]; if (gotos != null && gotos.Count > 0) continue; var ifStatement2 = statements[i+2] as ConditionalStatement; if (ifStatement2 == null) continue; var gotoTrueCase = ifStatement2.TrueBranch as GotoStatement; if (gotoTrueCase == null) continue; Contract.Assume(ifStatement2.FalseBranch is EmptyStatement); var labeledStatement2 = statements[i+3] as LabeledStatement; if (labeledStatement2 == null) continue; if (labeledStatement2 == gotoFalseCase.TargetStatement) { gotos = this.gotosThatTarget[(uint)labeledStatement2.Label.UniqueKey]; Contract.Assume(gotos != null && gotos.Count > 0); if (gotos.Count > 1) continue; var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean }; var conditional = new Conditional() { Condition = ifStatement.Condition, ResultIfTrue = ifStatement2.Condition, ResultIfFalse = falseConst, Type = this.host.PlatformType.SystemBoolean }; ifStatement2.Condition = conditional; statements.RemoveRange(i, 2); gotos.Remove(gotoFalseCase); replacedPattern = true; } else { if (gotoFalseCase.TargetStatement != gotoTrueCase.TargetStatement) continue; //actually have a short circuit or here gotos = this.gotosThatTarget[(uint)gotoFalseCase.TargetStatement.Label.UniqueKey]; Contract.Assume(gotos != null && gotos.Count > 0); var trueConst = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean }; var invertedCond = new LogicalNot() { Operand = ifStatement.Condition, Type = this.host.PlatformType.SystemBoolean }; var conditional = new Conditional() { Condition = invertedCond, ResultIfTrue = trueConst, ResultIfFalse = ifStatement2.Condition, Type = this.host.PlatformType.SystemBoolean }; ifStatement2.Condition = conditional; statements.RemoveRange(i, 2); gotos.Remove(gotoFalseCase); replacedPattern = true; } } return replacedPattern; }
private bool ReplaceShortCircuitAnd4(BlockStatement b) { Contract.Requires(b != null); bool replacedPattern = false; var statements = b.Statements; for (int i = 0; i < statements.Count-2; i++) { var ifStatement1 = statements[i] as ConditionalStatement; if (ifStatement1 == null || !(ifStatement1.FalseBranch is EmptyStatement)) continue; var goto1 = ifStatement1.TrueBranch as GotoStatement; if (goto1 == null) continue; var labStat = statements[i+1] as LabeledStatement; if (labStat == null) continue; var gotos1 = this.gotosThatTarget[(uint)labStat.Label.UniqueKey]; if (gotos1 != null && gotos1.Count > 0) continue; var ifStatement2 = statements[i+2] as ConditionalStatement; if (ifStatement2 == null) continue; if (ifStatement2.TrueBranch is EmptyStatement) { var goto2 = ifStatement2.FalseBranch as GotoStatement; if (goto2 == null) continue; if (goto1.TargetStatement != goto2.TargetStatement) continue; var gotos = this.gotosThatTarget[(uint)goto1.TargetStatement.Label.UniqueKey]; if (gotos == null || gotos.Count == 0) continue; var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean }; var notCond1 = new LogicalNot() { Operand = ifStatement1.Condition, Type = this.host.PlatformType.SystemBoolean }; var conditional = new Conditional() { Condition = notCond1, ResultIfTrue = ifStatement2.Condition, ResultIfFalse = falseConst, Type = this.host.PlatformType.SystemBoolean }; ifStatement2.Condition = conditional; statements.RemoveRange(i, 2); gotos.Remove(goto1); replacedPattern = true; } else if (ifStatement2.FalseBranch is EmptyStatement) { var goto2 = ifStatement2.TrueBranch as GotoStatement; if (goto2 == null) continue; if (goto1.TargetStatement != goto2.TargetStatement) continue; var gotos = this.gotosThatTarget[(uint)goto1.TargetStatement.Label.UniqueKey]; if (gotos == null || gotos.Count == 0) continue; var trueConst = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean }; var cond1 = ifStatement1.Condition; var conditional = new Conditional() { Condition = cond1, ResultIfTrue = trueConst, ResultIfFalse = ifStatement2.Condition, Type = this.host.PlatformType.SystemBoolean }; ifStatement2.Condition = conditional; statements.RemoveRange(i, 2); gotos.Remove(goto1); replacedPattern = true; } } return replacedPattern; }
public override IExpression Visit(LogicalNot logicalNot) { if (logicalNot.Type == Dummy.TypeReference) return PatternDecompiler.InvertCondition(this.Visit(logicalNot.Operand)); else if (logicalNot.Operand.Type.TypeCode == PrimitiveTypeCode.Int32) return new Equality() { LeftOperand = this.Visit(logicalNot.Operand), RightOperand = new CompileTimeConstant() { Value = 0, Type = this.host.PlatformType.SystemInt32 }, Type = this.host.PlatformType.SystemBoolean, Locations = logicalNot.Locations }; else { var castIfPossible = logicalNot.Operand as CastIfPossible; if (castIfPossible != null) { var operand = new CheckIfInstance() { Locations = castIfPossible.Locations, Operand = castIfPossible.ValueToCast, Type = this.host.PlatformType.SystemBoolean, TypeToCheck = castIfPossible.TargetType, }; logicalNot.Operand = operand; return logicalNot; } return base.Visit(logicalNot); } }
private bool ReplaceShortCircuitAnd(BlockStatement b) { Contract.Requires(b != null); bool replacedPattern = false; var statements = b.Statements; for (int i = 0; i < statements.Count-6; i++) { var ifStatement = statements[i] as ConditionalStatement; if (ifStatement == null) continue; var gotoFalseCase = ifStatement.FalseBranch as GotoStatement; if (gotoFalseCase == null) continue; Contract.Assume(ifStatement.TrueBranch is EmptyStatement); var labeledStatement = statements[i+1] as LabeledStatement; if (labeledStatement == null) continue; var gotos = this.gotosThatTarget[(uint)labeledStatement.Label.UniqueKey]; if (gotos != null && gotos.Count > 0) continue; var pushTrueCase = statements[i+2] as PushStatement; if (pushTrueCase == null) continue; if (pushTrueCase.ValueToPush.Type.TypeCode != PrimitiveTypeCode.Boolean) continue; var gotoEnd = statements[i+3] as GotoStatement; if (gotoEnd == null) continue; var labeledStatement2 = statements[i+4] as LabeledStatement; if (labeledStatement2 == null || labeledStatement2 != gotoFalseCase.TargetStatement) continue; gotos = this.gotosThatTarget[(uint)labeledStatement2.Label.UniqueKey]; Contract.Assume(gotos != null && gotos.Count > 0); if (gotos.Count > 1) continue; var pushFalseCase = statements[i+5] as PushStatement; if (pushFalseCase == null) continue; var falseCaseVal = pushFalseCase.ValueToPush as CompileTimeConstant; if (falseCaseVal == null || !(falseCaseVal.Value is int)) continue; var endLabel = statements[i+6] as LabeledStatement; if (endLabel == null || gotoEnd.TargetStatement != endLabel) continue; Conditional conditional; if (((int)falseCaseVal.Value) != 0) { var trueConst = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean }; var cond = new LogicalNot() { Operand = ifStatement.Condition, Type = this.host.PlatformType.SystemBoolean }; conditional = new Conditional() { Condition = cond, ResultIfTrue = trueConst, ResultIfFalse = pushTrueCase.ValueToPush, Type = this.host.PlatformType.SystemBoolean }; } else { var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean }; conditional = new Conditional() { Condition = ifStatement.Condition, ResultIfTrue = pushTrueCase.ValueToPush, ResultIfFalse = falseConst, Type = this.host.PlatformType.SystemBoolean }; } pushFalseCase.ValueToPush = conditional; statements.RemoveAt(i+6); statements.RemoveRange(i, 5); replacedPattern = true; } return replacedPattern; }
internal static IExpression InvertCondition(IExpression expression) { IBinaryOperation/*?*/ binOp = expression as IBinaryOperation; if (binOp != null) return InvertBinaryOperation(binOp); ILogicalNot/*?*/ logNot = expression as ILogicalNot; if (logNot != null) return logNot.Operand; LogicalNot logicalNot = new LogicalNot(); logicalNot.Operand = expression; logicalNot.Type = expression.Type; logicalNot.Locations.AddRange(expression.Locations); return logicalNot; }
private void DecompileIfThenElseStatement(BasicBlock b, int i) { List<IStatement> statements = b.Statements; ConditionalStatement/*?*/ conditionalStatement = statements[i++] as ConditionalStatement; if (conditionalStatement == null) return; IExpression condition; var trueBranch = UnwrapSingletonBlock(conditionalStatement.TrueBranch); GotoStatement/*?*/ gotoAfterThen = trueBranch as GotoStatement; if (gotoAfterThen == null) { gotoAfterThen = UnwrapSingletonBlock(conditionalStatement.FalseBranch) as GotoStatement; if (gotoAfterThen == null || !(trueBranch is EmptyStatement)) return; condition = conditionalStatement.Condition; } else { if (!(conditionalStatement.FalseBranch is EmptyStatement)) return; LogicalNot not = new LogicalNot(); not.Operand = conditionalStatement.Condition; condition = not; } //At this point we have: //if (!condition) goto afterThen; var afterThen = this.FindLabeledStatement(statements, i, gotoAfterThen.TargetStatement.Label); if (afterThen == null) return; List<IGotoStatement> branchesToThisLabel; if (this.predecessors.TryGetValue(afterThen, out branchesToThisLabel)) branchesToThisLabel.Remove(gotoAfterThen); BasicBlock ifBlock = this.ExtractBasicBlockUpto(b, i, afterThen); GotoStatement/*?*/ gotoEndif = this.RemoveAndReturnLastGotoStatement(ifBlock); this.Traverse(ifBlock); BasicBlock elseBlock = null; if (gotoEndif != null) { var endif = this.FindLabeledStatement(statements, i, gotoEndif.TargetStatement.Label); if (endif != null) { if (this.predecessors.TryGetValue(gotoEndif.TargetStatement, out branchesToThisLabel)) branchesToThisLabel.Remove(gotoEndif); elseBlock = this.ExtractBasicBlockUpto(b, i, gotoEndif.TargetStatement); elseBlock.Statements.Add(gotoEndif.TargetStatement); this.Traverse(elseBlock); elseBlock.Statements.Remove(gotoEndif.TargetStatement); } else { ifBlock.Statements.Add(gotoEndif); } } conditionalStatement.Condition = condition; conditionalStatement.TrueBranch = ifBlock; if (elseBlock != null) conditionalStatement.FalseBranch = elseBlock; else conditionalStatement.FalseBranch = new EmptyStatement(); return; }
/// <summary> /// Visits the specified logical not. /// </summary> /// <param name="logicalNot">The logical not.</param> /// <returns></returns> public virtual IExpression Visit(LogicalNot logicalNot) { return this.Visit((UnaryOperation)logicalNot); }
/// <summary> /// Rewrites the children of the given logical not expression. /// </summary> public virtual void RewriteChildren(LogicalNot logicalNot) { this.RewriteChildren((UnaryOperation)logicalNot); }
/// <summary> /// Visits the specified logical not. /// </summary> /// <param name="logicalNot">The logical not.</param> public override void Visit(ILogicalNot logicalNot) { LogicalNot mutableLogicalNot = logicalNot as LogicalNot; if (alwaysMakeACopy || mutableLogicalNot == null) mutableLogicalNot = new LogicalNot(logicalNot); this.resultExpression = this.myCodeMutator.Visit(mutableLogicalNot); }