Наследование: Statement, IConditionalStatement
Пример #1
0
        public IIfStatementOptions True(IExpression condition)
        {
            var ifStatement = new ConditionalStatement();
            ifStatement.Condition = condition;

            return new IfStatementOptions(ifStatement);
        }
 public override IStatement Visit(ConditionalStatement conditionalStatement)
 {
     var condition = conditionalStatement.Condition;
       var logicalNot = condition as ILogicalNot;
       if (logicalNot != null) condition = logicalNot.Operand;
       var equal = condition as IEquality;
       if (equal != null && equal.RightOperand is IDefaultValue) condition = equal.LeftOperand;
       var boundExpression = condition as IBoundExpression;
       if (boundExpression != null) {
     var locations = conditionalStatement.Locations;
     var fieldReference = boundExpression.Definition as IFieldReference;
     if (fieldReference != null) {
       if (this.cachedDelegateFieldsOrLocals.ContainsKey(fieldReference.Name.Value)) {
     if (locations.Count == 0)
       return CodeDummy.Block;
     else
       return new EmptyStatement() { Locations = locations, };
       }
     }
     var localDefinition = boundExpression.Definition as ILocalDefinition;
     if (localDefinition != null) {
       if (this.cachedDelegateFieldsOrLocals.ContainsKey(localDefinition.Name.Value)) {
     if (locations.Count == 0)
       return CodeDummy.Block;
     else
       return new EmptyStatement() { Locations = locations, };
       }
     }
       }
       return base.Visit(conditionalStatement);
 }
Пример #3
0
 private Statement ParseBinaryConditionalBranch(IOperation currentOperation)
 {
     BinaryOperation condition;
       switch (currentOperation.OperationCode) {
     case OperationCode.Beq:
     case OperationCode.Beq_S:
       condition = this.ParseBinaryOperation(new Equality());
       break;
     case OperationCode.Bge:
     case OperationCode.Bge_S:
       condition = this.ParseBinaryOperation(new GreaterThanOrEqual());
       break;
     case OperationCode.Bge_Un:
     case OperationCode.Bge_Un_S:
       condition = this.ParseUnsignedBinaryOperation(new GreaterThanOrEqual());
       break;
     case OperationCode.Bgt:
     case OperationCode.Bgt_S:
       condition = this.ParseBinaryOperation(new GreaterThan());
       break;
     case OperationCode.Bgt_Un:
     case OperationCode.Bgt_Un_S:
       condition = this.ParseUnsignedBinaryOperation(new GreaterThan());
       break;
     case OperationCode.Ble:
     case OperationCode.Ble_S:
       condition = this.ParseBinaryOperation(new LessThanOrEqual());
       break;
     case OperationCode.Ble_Un:
     case OperationCode.Ble_Un_S:
       condition = this.ParseUnsignedBinaryOperation(new LessThanOrEqual());
       break;
     case OperationCode.Blt:
     case OperationCode.Blt_S:
       condition = this.ParseBinaryOperation(new LessThan());
       break;
     case OperationCode.Blt_Un:
     case OperationCode.Blt_Un_S:
       condition = this.ParseUnsignedBinaryOperation(new LessThan());
       break;
     case OperationCode.Bne_Un:
     case OperationCode.Bne_Un_S:
     default:
       condition = this.ParseBinaryOperation(new NotEquality());
       break;
       }
       condition.Type = this.platformType.SystemBoolean;
       if (this.host.PreserveILLocations) {
     condition.Locations.Add(currentOperation.Location);
       }
       GotoStatement gotoStatement = MakeGoto(currentOperation);
       ConditionalStatement ifStatement = new ConditionalStatement();
       ifStatement.Condition = condition;
       ifStatement.TrueBranch = gotoStatement;
       ifStatement.FalseBranch = new EmptyStatement();
       return ifStatement;
 }
Пример #4
0
 private Statement ParseUnaryConditionalBranch(IOperation currentOperation)
 {
     Expression condition = this.PopOperandStack();
       var castIfPossible = condition as CastIfPossible;
       if (castIfPossible != null) {
     condition = new CheckIfInstance() {
       Locations = castIfPossible.Locations,
       Operand = castIfPossible.ValueToCast,
       TypeToCheck = castIfPossible.TargetType,
     };
       } else if (condition.Type != Dummy.TypeReference && condition.Type.TypeCode != PrimitiveTypeCode.Boolean) {
     var defaultValue = new DefaultValue() { DefaultValueType = condition.Type, Type = condition.Type };
     condition = new NotEquality() { LeftOperand = condition, RightOperand = defaultValue };
       }
       condition.Type = this.platformType.SystemBoolean;
       GotoStatement gotoStatement = MakeGoto(currentOperation);
       ConditionalStatement ifStatement = new ConditionalStatement();
       ifStatement.Condition = condition;
       switch (currentOperation.OperationCode) {
     case OperationCode.Brfalse:
     case OperationCode.Brfalse_S:
       ifStatement.TrueBranch = new EmptyStatement();
       ifStatement.FalseBranch = gotoStatement;
       break;
     case OperationCode.Brtrue:
     case OperationCode.Brtrue_S:
     default:
       ifStatement.TrueBranch = gotoStatement;
       ifStatement.FalseBranch = new EmptyStatement();
       break;
       }
       return ifStatement;
 }
Пример #5
0
 public IfBranchOptions(ConditionalStatement ifStatement)
 {
     this.ifStatement = ifStatement;
 }
 /// <summary>
 /// Rewrites the given anonymous delegate expression.
 /// </summary>
 public override IExpression Rewrite(IAnonymousDelegate anonymousDelegate) {
   if (this.isInsideAnonymousMethod) return base.Rewrite(anonymousDelegate);
   IMethodReference method = this.CreateClosureMethod((AnonymousDelegate)anonymousDelegate);
   var createDelegate = new CreateDelegateInstance() {
     MethodToCallViaDelegate = method,
     Type = anonymousDelegate.Type
   };
   if (!method.IsStatic) {
     //TODO: if there is reason to believe the delegate will be constructed in a loop, but its closure is constructed before the loop, then cache the delegate in a local
     //that is in the same scope as the closure instance
     if (method.ContainingType == this.currentClosureInstance)
       createDelegate.Instance = this.currentClosureObject;
     else //non static peer method
       createDelegate.Instance = new ThisReference() {
         Type = NamedTypeDefinition.SelfInstance((INamedTypeDefinition)this.method.ContainingTypeDefinition, this.host.InternFactory)
       };
   } else if ((method.CallingConvention & CallingConvention.Generic) == 0) {
     //cache the delegate in a static field (we can only do this if method is not generic, i.e. when at most one instance will be created).
     var cache = this.CreateStaticCacheField(anonymousDelegate.Type);
     var boundField = new BoundExpression() { Definition = cache, Type = cache.Type };
     var statements = new List<IStatement>(1);
     var conditional = new ConditionalStatement() {
       Condition = new Equality() {
         LeftOperand = boundField,
         RightOperand = new CompileTimeConstant() { Value = null, Type = cache.Type },
         Type = this.host.PlatformType.SystemBoolean
       },
       TrueBranch = new ExpressionStatement() {
         Expression = new Assignment() {
           Target = new TargetExpression() { Definition = cache, Type = cache.Type },
           Source = createDelegate,
           Type = cache.Type
         }
       }
     };
     statements.Add(conditional);
     return new BlockExpression() {
       BlockStatement = new BlockStatement() { Statements = statements },
       Expression = boundField
     };
   }
   return createDelegate;
 }
Пример #7
0
        public override void RewriteChildren(ConditionalStatement conditionalStatement)
        {
            // exactly the same code as the base visitor. just need to reset stack
            // depth for each branch.

            this.RewriteChildren((Statement)conditionalStatement);

            conditionalStatement.Condition = this.Rewrite(conditionalStatement.Condition);

            var savedInThenBranch = this.inThenBranch;
            var savedInElseBranch = this.inElseBranch;
            this.inThenBranch = true;
            this.inElseBranch = false;

            var savedThenBranchPushes = this.thenBranchPushes;
            this.thenBranchPushes = new Dictionary<int, Assignment>();

            var savedStack = Copy(this.locals);
            conditionalStatement.TrueBranch = this.Rewrite(conditionalStatement.TrueBranch);
            var stackAfterTrue = Copy(this.locals);

            this.locals = Copy(savedStack);
            this.inThenBranch = false;
            this.inElseBranch = true;
            conditionalStatement.FalseBranch = this.Rewrite(conditionalStatement.FalseBranch);

            Contract.Assume(stackAfterTrue.Count == this.locals.Count);
            // and that the things pushed in both branches are type-compatible
            // (one branch might push a bool and the other an int)

            // continuing on with the stack being the one from the else-branch.
            // is that okay? should it be the one from the then-branch?
            // currently it is important that it is the one from the else-branch
            // because of the fixup code in Rewrite(IPushStatement) that deals
            // with the bool/int confusion

            this.inThenBranch = savedInThenBranch;
            this.inElseBranch = savedInElseBranch;
            this.thenBranchPushes = savedThenBranchPushes;
        }
Пример #8
0
 /// <summary>
 /// Visits the specified conditional statement.
 /// </summary>
 /// <param name="conditionalStatement">The conditional statement.</param>
 /// <returns></returns>
 protected virtual IStatement DeepCopy(ConditionalStatement conditionalStatement)
 {
     conditionalStatement.Condition = Substitute(conditionalStatement.Condition);
       conditionalStatement.TrueBranch = Substitute(conditionalStatement.TrueBranch);
       conditionalStatement.FalseBranch = Substitute(conditionalStatement.FalseBranch);
       return conditionalStatement;
 }
Пример #9
0
 /// <summary>
 /// Visits the specified conditional statement.
 /// </summary>
 /// <param name="conditionalStatement">The conditional statement.</param>
 public override void Visit(IConditionalStatement conditionalStatement)
 {
     ConditionalStatement mutableConditionalStatement = new ConditionalStatement(conditionalStatement);
     this.resultStatement = this.myCodeCopier.DeepCopy(mutableConditionalStatement);
 }
        // i   :  loc := e0;
        // i+1 :  if (loc) S0; else S1;
        //
        //  ==>
        //
        //        if (e0) S0; else S1;
        //
        // and delete statement i
        //
        // This is done only if loc is in this.branchConditionLocals
        //
        private void FindPattern(List<IStatement> statements)
        {
            for (int i = 0; i < statements.Count - 1; i++) {
            IExpressionStatement/*?*/ expressionStatement = statements[i] as IExpressionStatement;
            if (expressionStatement == null) continue;
            IAssignment/*?*/ assignmentStatement = expressionStatement.Expression as IAssignment;
            if (assignmentStatement == null) continue;
            if (assignmentStatement.Source is Pop) continue;
            ILocalDefinition/*?*/ localDefinition = assignmentStatement.Target.Definition as ILocalDefinition;
            if (localDefinition == null) continue;
            if (localDefinition.Type.TypeCode != PrimitiveTypeCode.Boolean) continue; // cheaper test than looking in the table
            if (!this.branchConditionLocals.ContainsKey(localDefinition)) continue;

            IConditionalStatement/*?*/ conditional = statements[i + 1] as IConditionalStatement;
            if (conditional == null) continue;
            BoundExpression/*?*/ boundExpression = conditional.Condition as BoundExpression;
            if (boundExpression == null) continue;
            ILocalDefinition/*?*/ localDefinition2 = boundExpression.Definition as ILocalDefinition;
            if (localDefinition2 == null) continue;
            if (localDefinition != localDefinition2) continue;

            var newLocs = new List<ILocation>(expressionStatement.Locations);
            newLocs.AddRange(conditional.Locations);

            statements[i + 1] = new ConditionalStatement() {
              Condition = assignmentStatement.Source,
              TrueBranch = conditional.TrueBranch,
              FalseBranch = conditional.FalseBranch,
              Locations = newLocs,
            };
            this.sourceMethodBody.numberOfAssignments[localDefinition]--;
            this.sourceMethodBody.numberOfReferences[localDefinition]--;

            statements.RemoveAt(i);
              }
        }
Пример #11
0
    /// <summary>
    /// Create the body of the generic version of GetEnumerator for the iterator closure class.
    /// 
    /// The body's pseudo code. 
    /// {
    ///   if (Thread.CurrentThread.ManagedThreadId == this.l_initialThreadId AND this.state == -2) {
    ///     this.state = 0;
    ///     return this;
    ///   }
    ///   else {
    ///     return a new copy of the iterator instance with state being zero.
    ///   }
    /// }
    /// </summary>
    private BlockStatement GetBodyOfGenericGetEnumerator(IteratorClosureInformation iteratorClosure) {
      var thisDotState = new BoundExpression() {
        Definition = iteratorClosure.StateFieldReference,
        Instance = new ThisReference(),
        Type = this.host.PlatformType.SystemInt32
      };
      var thisDotThreadId = new BoundExpression() {
        Definition = iteratorClosure.InitThreadIdFieldReference,
        Instance = new ThisReference(),
        Type = this.host.PlatformType.SystemInt32
      };
      var currentThreadId = new MethodCall() {
        MethodToCall = ThreadDotManagedThreadId.Getter,
        ThisArgument = ThreadDotCurrentThread,
        Type = this.host.PlatformType.SystemInt32
      };
      var stateEqMinus2 = new Equality() { LeftOperand = thisDotState, RightOperand = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32, Value = -2 }, Type = this.host.PlatformType.SystemBoolean };
      var threadIdEqCurrentThreadId = new Equality { LeftOperand = thisDotThreadId, RightOperand = currentThreadId, Type = this.host.PlatformType.SystemBoolean };

      var thisDotStateEq0 = new ExpressionStatement() {
        Expression = new Assignment() {
          Source = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32, Value = 0 },
          Target = new TargetExpression() {
            Definition = iteratorClosure.StateFieldReference,
            Instance = new ThisReference(),
            Type = this.host.PlatformType.SystemInt32
          },
          Type = this.host.PlatformType.SystemInt32
        },
      };
      var returnThis = new BlockStatement();
      returnThis.Statements.Add(thisDotStateEq0);
      returnThis.Statements.Add(new ReturnStatement() { Expression = new ThisReference() });
      var returnNew = new BlockStatement();
      var args = new List<IExpression>();
      args.Add(new CompileTimeConstant() { Value = 0, Type = this.host.PlatformType.SystemInt32 });
      var closureInstanceLocalDecl = new LocalDeclarationStatement() {
        LocalVariable = new LocalDefinition() {
          Name = this.host.NameTable.GetNameFor("local0"),
          Type = iteratorClosure.ClosureDefinitionReference
        },
        InitialValue = new CreateObjectInstance() {
          MethodToCall = iteratorClosure.ConstructorReference,
          Arguments = args,
          Type = iteratorClosure.ClosureDefinitionReference
        }
      };
      var returnNewClosureInstance = new ReturnStatement() {
        Expression = new BoundExpression() {
          Instance = null,
          Type = iteratorClosure.ClosureDefinitionReference,
          Definition = closureInstanceLocalDecl.LocalVariable
        }
      };
      returnNew.Statements.Add(closureInstanceLocalDecl);
      if (!method.IsStatic) {
        ExpressionStatement assignThisDotThisToNewClosureDotThis = new ExpressionStatement() {
          Expression = new Assignment() {
            Source = new BoundExpression() {
              Definition = iteratorClosure.ThisFieldReference,
              Instance = new ThisReference(),
              Type = iteratorClosure.ClosureDefinitionReference
            },
            Type = iteratorClosure.ClosureDefinition,
            Target = new TargetExpression() {
              Instance = new BoundExpression() {
                Instance = null,
                Definition = closureInstanceLocalDecl.LocalVariable,
                Type = iteratorClosure.ClosureDefinitionReference
              },
              Definition = iteratorClosure.ThisFieldReference,
              Type = iteratorClosure.ClosureDefinitionReference
            }
          }
        };
        returnNew.Statements.Add(assignThisDotThisToNewClosureDotThis);
      }
      returnNew.Statements.Add(returnNewClosureInstance);

      ConditionalStatement returnThisOrNew = new ConditionalStatement() {
        Condition = new Conditional() {
          Condition = stateEqMinus2,
          ResultIfTrue = threadIdEqCurrentThreadId,
          ResultIfFalse = new CompileTimeConstant() { Type = this.host.PlatformType.SystemBoolean, Value = false },
          Type = this.host.PlatformType.SystemBoolean
        },
        TrueBranch = returnThis,
        FalseBranch = returnNew
      };
      BlockStatement block = new BlockStatement();
      block.Statements.Add(returnThisOrNew);
      return block;
    }
Пример #12
0
 /// <summary>
 /// Rewrites the children of the given conditional statement.
 /// </summary>
 public virtual void RewriteChildren(ConditionalStatement conditionalStatement)
 {
     this.RewriteChildren((Statement)conditionalStatement);
       conditionalStatement.Condition = this.Rewrite(conditionalStatement.Condition);
       conditionalStatement.TrueBranch = this.Rewrite(conditionalStatement.TrueBranch);
       conditionalStatement.FalseBranch = this.Rewrite(conditionalStatement.FalseBranch);
 }
Пример #13
0
 /// <summary>
 /// Visits the specified conditional statement.
 /// </summary>
 /// <param name="conditionalStatement">The conditional statement.</param>
 public override void Visit(IConditionalStatement conditionalStatement)
 {
     ConditionalStatement mutableConditionalStatement = conditionalStatement as ConditionalStatement;
     if (alwaysMakeACopy || mutableConditionalStatement == null) mutableConditionalStatement = new ConditionalStatement(conditionalStatement);
     this.resultStatement = this.myCodeMutator.Visit(mutableConditionalStatement);
 }
Пример #14
0
 /// <summary>
 /// Visits the specified conditional statement.
 /// </summary>
 /// <param name="conditionalStatement">The conditional statement.</param>
 /// <returns></returns>
 public virtual IStatement Visit(ConditionalStatement conditionalStatement)
 {
     conditionalStatement.Condition = Visit(conditionalStatement.Condition);
       conditionalStatement.TrueBranch = Visit(conditionalStatement.TrueBranch);
       conditionalStatement.FalseBranch = Visit(conditionalStatement.FalseBranch);
       return conditionalStatement;
 }