Pushes a value onto an implicit operand stack.
상속: Statement, IPushStatement
예제 #1
0
 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);
     }
       }
 }
예제 #2
0
 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]);
 }
예제 #3
0
 private Statement ParseDup()
 {
     PushStatement result = new PushStatement();
       result.ValueToPush = new Dup();
       return result;
 }
예제 #4
0
파일: Copier.cs 프로젝트: riverar/devtools
 /// <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);
 }
예제 #5
0
파일: Copier.cs 프로젝트: riverar/devtools
 /// <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;
 }
예제 #6
0
 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;
 }
예제 #7
0
    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;
      }
    }
예제 #8
0
파일: Mutator.cs 프로젝트: riverar/devtools
 /// <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;
 }
예제 #9
0
파일: Mutator.cs 프로젝트: riverar/devtools
 /// <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);
 }
예제 #10
0
파일: Mutator.cs 프로젝트: riverar/devtools
 /// <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);
 }