示例#1
0
 /// <summary>
 /// Visits the specified addition.
 /// </summary>
 /// <param name="addition">The addition.</param>
 /// <returns></returns>
 protected virtual IExpression DeepCopy(Addition addition)
 {
     return this.DeepCopy((BinaryOperation)addition);
 }
示例#2
0
 private Expression ParseAddition(OperationCode currentOpcode)
 {
     Addition addition = new Addition();
       addition.CheckOverflow = currentOpcode != OperationCode.Add;
       if (currentOpcode == OperationCode.Add_Ovf_Un) {
     addition.TreatOperandsAsUnsignedIntegers = true; //force use of unsigned addition, even for cases where the operands are expressions that result in signed values
     return this.ParseUnsignedBinaryOperation(addition);
       } else
     return this.ParseBinaryOperation(addition);
 }
示例#3
0
 /// <summary>
 /// Visits the specified addition.
 /// </summary>
 /// <param name="addition">The addition.</param>
 public override void Visit(IAddition addition)
 {
     Addition/*?*/ mutableAddition = new Addition(addition);
     this.resultExpression = this.myCodeCopier.DeepCopy(mutableAddition);
 }
示例#4
0
    /// <summary>
    /// For a string field, s, the source expression e.s += ""
    /// turns into a specific pattern.
    /// That pattern here looks like:
    /// i:   push e
    /// i+1: push dup.s
    /// i+2: (!= dup (default_value string)) ? goto L2 : empty
    /// i+3: L1
    /// i+4: pop
    /// i+5: push ""
    /// i+6: L2
    /// i+7: pop.s = pop
    /// </summary>
    private bool ReplacePlusAssignForStringPattern(BlockStatement b) {
      Contract.Requires(b != null);
      bool replacedPattern = false;
      var statements = b.Statements;
      for (int i = 0; i < statements.Count - 7; i++) {
        var push1 = statements[i] as PushStatement;
        if (push1 == null) continue;
        var push2 = statements[i + 1] as PushStatement;
        if (push2 == null) continue;
        var boundExpression = push2.ValueToPush as IBoundExpression;
        if (boundExpression == null) continue;
        var dupValue = boundExpression.Instance as IDupValue;
        if (dupValue == null) continue;
        var field = boundExpression.Definition as IFieldReference;
        if (field == null) continue;
        var conditionalStatement = statements[i + 2] as IConditionalStatement;
        if (conditionalStatement == null) continue;
        var notEquality = conditionalStatement.Condition as INotEquality;
        if (notEquality == null) continue;
        var gotoStatement = conditionalStatement.TrueBranch as IGotoStatement;
        if (gotoStatement == null) continue;
        var branchTarget = gotoStatement.TargetStatement;
        var emptyStatement = conditionalStatement.FalseBranch as IEmptyStatement;
        if (emptyStatement == null) continue;
        var labeledStatement = statements[i + 3] as ILabeledStatement;
        if (labeledStatement == null) continue;
        var popStatement = statements[i + 4] as IExpressionStatement;
        if (popStatement == null) continue;
        if (!(popStatement.Expression is IPopValue)) continue;
        var pushEmptyString = statements[i + 5] as IPushStatement;
        if (pushEmptyString == null) continue;
        var emptyString = pushEmptyString.ValueToPush as ICompileTimeConstant;
        if (emptyString == null) continue;
        if (emptyString.Type.TypeCode != PrimitiveTypeCode.String) continue;
        if ((string)emptyString.Value != "") continue;
        labeledStatement = statements[i + 6] as ILabeledStatement;
        if (labeledStatement == null) continue;
        if (labeledStatement.Label != branchTarget.Label) continue;
        var assignStatement = statements[i + 7] as IExpressionStatement;
        if (assignStatement == null) continue;
        var assignment = assignStatement.Expression as IAssignment;
        if (assignment == null) continue;
        if (!(assignment.Source is IPopValue)) continue;
        if (!(assignment.Target.Instance is IPopValue)) continue;
        // REVIEW: should the definition of the target be checked to be the same as "field"? If so, how?

        var plusEqual = new Addition() {
          LeftOperand = new TargetExpression() {
            Definition = assignment.Target.Definition,
            Instance = push1.ValueToPush,
          },
          RightOperand = emptyString,
          ResultIsUnmodifiedLeftOperand = false,
          Type = assignment.Type,
        };

        statements[i] = new ExpressionStatement() {
          Expression = plusEqual,
          Locations = new List<ILocation>(push1.Locations),
        };
        statements.RemoveRange(i + 1, 7);
        replacedPattern = true;
      }
      return replacedPattern;
    }
示例#5
0
 /// <summary>
 /// Visits the specified addition.
 /// </summary>
 /// <param name="addition">The addition.</param>
 /// <returns></returns>
 public virtual IExpression Visit(Addition addition)
 {
     return this.Visit((BinaryOperation)addition);
 }
示例#6
0
 /// <summary>
 /// Rewrites the children of the given addition.
 /// </summary>
 /// <param name="addition"></param>
 public virtual void RewriteChildren(Addition addition)
 {
     this.RewriteChildren((BinaryOperation)addition);
 }
示例#7
0
 /// <summary>
 /// Visits the specified addition.
 /// </summary>
 /// <param name="addition">The addition.</param>
 public override void Visit(IAddition addition)
 {
     Addition/*?*/ mutableAddition = addition as Addition;
     if (alwaysMakeACopy || mutableAddition == null) mutableAddition = new Addition(addition);
     this.resultExpression = this.myCodeMutator.Visit(mutableAddition);
 }