private void TurnOperandStackIntoPushStatements(BasicBlock currentBlock) { int insertPoint = currentBlock.Statements.Count; while (this.operandStack.Count > 0) { Expression operand = this.PopOperandStack(); MethodCall/*?*/ call = operand as MethodCall; if (call != null && call.MethodToCall.Type.TypeCode == PrimitiveTypeCode.Void) { ExpressionStatement expressionStatement = new ExpressionStatement(); expressionStatement.Expression = operand; currentBlock.Statements.Insert(insertPoint, expressionStatement); } else { PushStatement push = new PushStatement(); push.ValueToPush = operand; currentBlock.Statements.Insert(insertPoint, push); } } }
private void TurnOperandStackIntoPushStatements(List<IStatement> statements) { Contract.Requires(statements != null); List<Expression> correspondingPops = null; int insertPoint = statements.Count; while (this.operandStack.Count > 0) { Expression operand = this.PopOperandStack(); if (operand is PopValue) { this.operandStack.Push(operand); break; } Contract.Assume(!(operand.Type is Dummy)); PushStatement push = new PushStatement(); push.ValueToPush = operand; statements.Insert(insertPoint, push); if (correspondingPops == null) correspondingPops = new List<Expression>(this.operandStack.Count); correspondingPops.Add(new PopValue() { Type = operand.Type }); } if (correspondingPops == null) return; for (int i = correspondingPops.Count-1; i >= 0; i--) this.operandStack.Push(correspondingPops[i]); }
private Statement ParseDup() { PushStatement result = new PushStatement(); result.ValueToPush = new Dup(); return result; }
/// <summary> /// Performs some computation with the given push statement. /// </summary> public override void Visit(IPushStatement pushStatement) { PushStatement mutablePushStatement = new PushStatement(pushStatement); this.resultStatement = this.myCodeCopier.DeepCopy(mutablePushStatement); }
/// <summary> /// Visits the specified push statement. /// </summary> /// <param name="pushStatement"></param> /// <returns></returns> protected virtual IStatement DeepCopy(PushStatement pushStatement) { pushStatement.ValueToPush = this.Substitute(pushStatement.ValueToPush); return pushStatement; }
private bool ReplaceShortCircuitAnd5(BlockStatement b) { Contract.Requires(b != null); bool replacedPattern = false; var statements = b.Statements; for (int i = 0; i < statements.Count; i++) { var ifStatement = statements[i] as ConditionalStatement; if (ifStatement == null) continue; var pushTrue = ifStatement.TrueBranch as IPushStatement; if (pushTrue == null) { var trueBlock = ifStatement.TrueBranch as BlockStatement; if (trueBlock != null && trueBlock.Statements.Count == 1) pushTrue = trueBlock.Statements[0] as IPushStatement; } if (pushTrue == null || pushTrue.ValueToPush.Type.TypeCode != PrimitiveTypeCode.Boolean) continue; var pushFalse = ifStatement.FalseBranch as IPushStatement; if (pushFalse == null) { var falseBlock = ifStatement.FalseBranch as BlockStatement; if (falseBlock != null && falseBlock.Statements.Count == 1) pushFalse = falseBlock.Statements[0] as IPushStatement; } if (pushFalse == null) continue; var falseCaseVal = pushFalse.ValueToPush as CompileTimeConstant; if (falseCaseVal == null || !(falseCaseVal.Value is int)) continue; if (0 != (int)falseCaseVal.Value) continue; var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean }; statements[i] = new PushStatement() { ValueToPush = new Conditional() { Condition = ifStatement.Condition, ResultIfTrue = pushTrue.ValueToPush, ResultIfFalse = falseConst, Type = pushTrue.ValueToPush.Type } }; replacedPattern = true; } return replacedPattern; }
private ILocalDefinition ExtractExceptionContainer(DecompiledBlock nestedBlock, ITypeReference exceptionType) { Contract.Requires(nestedBlock != null); Contract.Requires(exceptionType != null); Contract.Ensures(Contract.Result<ILocalDefinition>() != null); Contract.Assume(nestedBlock.Statements.Count > 0); int i = 0; while (nestedBlock.Statements[i] is LocalDeclarationStatement) { i++; Contract.Assume(i < nestedBlock.Statements.Count); }; var firstStatement = nestedBlock.Statements[i++]; var firstBlock = firstStatement as DecompiledBlock; while (firstBlock != null) { Contract.Assume(firstBlock.Statements.Count > 0); i = 0; while (firstBlock.Statements[i] is LocalDeclarationStatement) { i++; Contract.Assume(i < firstBlock.Statements.Count); }; firstStatement = firstBlock.Statements[i++]; nestedBlock = firstBlock; firstBlock = firstStatement as DecompiledBlock; } //Ignoring any local declarations inserted for lexical scopes, any decompiled block that does not start with a nested block, starts with a label. Contract.Assume(firstStatement is LabeledStatement); if (nestedBlock.Statements.Count > i) { var exprStatement = nestedBlock.Statements[i] as ExpressionStatement; if (exprStatement != null) { nestedBlock.Statements.RemoveRange(i-1, 2); if (exprStatement.Expression is PopValue) return Dummy.LocalVariable; var assignment = exprStatement.Expression as Assignment; if (assignment != null && assignment.Source is PopValue) { var local = assignment.Target.Definition as ILocalDefinition; if (local != null) return local; //if not, this is not a recognized code pattern. } } // can't find the local, so just introduce one and leave its value on the stack var ld = new LocalDefinition() { Type = exceptionType, }; var pushStatement = new PushStatement() { ValueToPush = new BoundExpression() { Definition = ld, Type = exceptionType, }, }; nestedBlock.Statements.Insert(0, pushStatement); return ld; } else { //Valid IL should always have at least one instruction to consume the exception value as well as a branch out of the handler block. Contract.Assume(false); return Dummy.LocalVariable; } }
/// <summary> /// Visits the specified push statement. /// </summary> /// <param name="pushStatement">The push statement.</param> /// <returns></returns> public virtual IStatement Visit(PushStatement pushStatement) { pushStatement.ValueToPush = Visit(pushStatement.ValueToPush); return pushStatement; }
/// <summary> /// Rewrites the children of the given push statement. /// </summary> public virtual void RewriteChildren(PushStatement pushStatement) { this.RewriteChildren((Statement)pushStatement); pushStatement.ValueToPush = this.Rewrite(pushStatement.ValueToPush); }
/// <summary> /// Performs some computation with the given push statement. /// </summary> /// <param name="pushStatement"></param> public override void Visit(IPushStatement pushStatement) { PushStatement mutablePushStatement = pushStatement as PushStatement; if (alwaysMakeACopy || mutablePushStatement == null) mutablePushStatement = new PushStatement(pushStatement); this.resultStatement = this.myCodeMutator.Visit(mutablePushStatement); }