public override ICatchClause Rewrite(ICatchClause catchClause)
            {
                _log.Info("Rewriting ITryCatchFinallyStatement: " + catchClause + " Pass: "******".ctor"));
                    expression = new CreateObjectInstance()
                    {
                        MethodToCall = ctor,
                        Type = catchClause.ExceptionContainer.Type
                    };

                }
                return new CatchClause(catchClause)
                {
                    Body = new BlockStatement()
                    {
                        Statements = new ThrowStatement()
                        {
                            Exception = expression
                        }.InList<IStatement>()
                    }
                };
            }
Example #2
0
 public override IExpression Rewrite(IThisReference thisReference) {
   var boundExpression = new BoundExpression();
   boundExpression.Instance = thisReference;
   boundExpression.Definition = iteratorClosure.ThisFieldReference;
   boundExpression.Type = iteratorClosure.ThisFieldReference.Type;
   return boundExpression;
 }
        public override void BuildMethod()
        {
            AddStatement.DeclareInterceptedType(field.ContainingType.ResolvedType);

            Context.Log.WriteTrace("  Adding: var interceptedField = interceptedType.GetField('{0}');", field.Name.Value);
            Context.Block.Statements.Add(
                Declare.Variable<FieldInfo>("interceptedField").As(
                    Call.VirtualMethod("GetField", typeof (string)).ThatReturns<FieldInfo>().WithArguments(
                        Constant.Of(field.Name.Value)).On("interceptedType"))
            );

            AddStatement.DeclareArgumentsList();

            var funcT = SharpMockTypes.Functions[0];
            var funcActualT = new GenericTypeInstanceReference();
            funcActualT.GenericType = funcT;
            funcActualT.GenericArguments.Add(field.Type);

            var accessor = new AnonymousDelegate();
            accessor.Type = funcActualT;
            accessor.ReturnType = field.Type;
            accessor.CallingConvention = CallingConvention.HasThis;

            var accessorBody = new BlockStatement();
            var returnActualField = new ReturnStatement();
            var actualField = new BoundExpression();
            actualField.Type = field.Type;
            actualField.Definition = field;
            returnActualField.Expression = actualField;
            accessorBody.Statements.Add(returnActualField);
            accessor.Body = accessorBody;

            Context.Block.Statements.Add(
                Declare.Variable("local_0", funcActualT).As(accessor)
            );

            AddStatement.DeclareRegistryInterceptor();
            AddStatement.DeclareInvocation();
            AddStatement.SetArgumentsOnInvocation();
            AddStatement.SetOriginalCallOnInvocation();
            AddStatement.SetTargetOnInvocationToNull();

            Context.Block.Statements.Add(
                Do(Call.PropertySetter<MemberInfo>("OriginalCallInfo").WithArguments("interceptedField").On("invocation"))
            );

            AddStatement.CallShouldInterceptOnInterceptor();
            AddStatement.CallInterceptOnInterceptor();

            Context.Block.Statements.Add(
                Declare.Variable("interceptionResult", field.Type).As(
                    ChangeType.Convert(Call.PropertyGetter<object>("Return").On("invocation")).To(field.Type))
            );

            Context.Block.Statements.Add(Return.Variable(Locals["interceptionResult"]));
        }
Example #4
0
 public override void RewriteChildren(BoundExpression boundExpression) {
   BoundField/*?*/ boundField;
   if (this.fieldForCapturedLocalOrParameter.TryGetValue(boundExpression.Definition, out boundField)) {
     boundExpression.Instance = new ThisReference();
     boundExpression.Definition = iteratorClosure.GetReferenceOfFieldUsedByPeers(boundField.Field);
     boundExpression.Type = boundField.Type;
     return;
   }
   base.RewriteChildren(boundExpression);
 }
 public override IExpression Visit(BoundExpression boundExpression)
 {
     var fieldReference = boundExpression.Definition as IFieldReference;
       if (fieldReference != null) {
     if (this.cachedDelegateFieldsOrLocals.ContainsKey(fieldReference.Name.Value))
       return this.cachedDelegateFieldsOrLocals[fieldReference.Name.Value];
     else
       return boundExpression;
       }
       var localDefinition = boundExpression.Definition as ILocalDefinition;
       if (localDefinition != null) {
     if (this.cachedDelegateFieldsOrLocals.ContainsKey(localDefinition.Name.Value))
       return this.cachedDelegateFieldsOrLocals[localDefinition.Name.Value];
     else
       return boundExpression;
       }
       return base.Visit(boundExpression);
 }
 public override IExpression Visit(BoundExpression boundExpression)
 {
     ILocalDefinition/*?*/ local = boundExpression.Definition as ILocalDefinition;
       if (local != null) {
     IExpression substitute = boundExpression;
     if (this.expressionToSubstituteForCompilerGeneratedSingleAssignmentLocal.TryGetValue(local, out substitute)) {
       this.sourceMethodBody.numberOfReferences[local]--;
       return substitute;
     }
       }
       IFieldReference/*?*/ closureField = boundExpression.Definition as IFieldReference;
       if (closureField != null) {
     var unspecializedClosureField = UnspecializedMethods.UnspecializedFieldReference(closureField);
     IBoundExpression/*?*/ binding = null;
     if (this.capturedBinding.TryGetValue(unspecializedClosureField.InternedKey, out binding)) {
       IThisReference thisReference = binding.Instance as IThisReference;
       if (thisReference != null && binding.Definition is Dummy) return thisReference;
       boundExpression.Definition = binding.Definition;
       boundExpression.Instance = binding.Instance;
       return boundExpression;
     }
       }
       IParameterDefinition/*?*/ parameter = boundExpression.Definition as IParameterDefinition;
       if (parameter != null) {
     IParameterDefinition parToSubstitute;
     if (this.parameterMap.TryGetValue(parameter, out parToSubstitute)) {
       boundExpression.Definition = parToSubstitute;
       return boundExpression;
     }
       }
       return base.Visit(boundExpression);
 }
Example #7
0
 public override IExpression Rewrite(IDupValue dupValue)
 {
     var depth = this.locals.Count;
     var t = dupValue.Type;
     Contract.Assume(0 < this.locals.Count);
     var local = this.locals.Peek();
     this.locals.Push(local);
     var be = new BoundExpression() { Definition = local, Instance = null, Type = t, };
     return be;
 }
        public override void BuildMethod()
        {
            AddStatement.DeclareInterceptedType(field.ContainingType.ResolvedType);

            Context.Log.WriteTrace("  Adding: var interceptedField = interceptedType.GetField('{0}');", field.Name.Value);
            Context.Block.Statements.Add(
                Declare.Variable<FieldInfo>("interceptedField").As(
                    Call.VirtualMethod("GetField", typeof (string)).ThatReturns<FieldInfo>().WithArguments(
                        Constant.Of(field.Name.Value)).On("interceptedType"))
            );

            AddStatement.DeclareArgumentsList();
            AddStatement.AddArgumentToList(Params["assignedValue"]);

            var actionT = SharpMockTypes.Actions[1];
            var actionActualT = new GenericTypeInstanceReference();
            actionActualT.GenericType = actionT;
            actionActualT.GenericArguments.Add(field.Type);

            var assignment = new AnonymousDelegate();
            assignment.Type = actionActualT;
            assignment.ReturnType = Context.Host.PlatformType.SystemVoid;
            assignment.CallingConvention = CallingConvention.HasThis;

            var parameterDefinition = new ParameterDefinition();
            parameterDefinition.Index = 0;
            parameterDefinition.Type = field.Type;
            parameterDefinition.Name = Context.Host.NameTable.GetNameFor("alteredValue");
            parameterDefinition.ContainingSignature = assignment;

            assignment.Parameters.Add(parameterDefinition);

            var assignmentBody = new BlockStatement();
            var assignActualField = new ExpressionStatement();
            var actualField = new TargetExpression();
            actualField.Type = field.Type;
            actualField.Definition = field;
            var value = new BoundExpression();
            value.Type = field.Type;
            value.Definition = parameterDefinition;
            var assignValueToField = new Assignment();
            assignValueToField.Source = value;
            assignValueToField.Target = actualField;
            assignValueToField.Type = field.Type;
            assignActualField.Expression = assignValueToField;

            actualField.Type = field.Type;
            actualField.Definition = field;

            assignmentBody.Statements.Add(assignActualField);
            assignmentBody.Statements.Add(new ReturnStatement());
            assignment.Body = assignmentBody;

            Context.Block.Statements.Add(
                Declare.Variable("local_0", actionActualT).As(assignment)
            );

            AddStatement.DeclareRegistryInterceptor();
            AddStatement.DeclareInvocation();
            AddStatement.SetArgumentsOnInvocation();
            AddStatement.SetOriginalCallOnInvocation();
            AddStatement.SetTargetOnInvocationToNull();

            Context.Block.Statements.Add(
                Do(Call.PropertySetter<MemberInfo>("OriginalCallInfo").WithArguments("interceptedField").On("invocation"))
            );

            AddStatement.CallShouldInterceptOnInterceptor();
            AddStatement.CallInterceptOnInterceptor();

            Context.Block.Statements.Add(Return.Void());
        }
Example #9
0
 /// <summary>
 /// Visits the specified bound expression.
 /// </summary>
 /// <param name="boundExpression">The bound expression.</param>
 /// <returns></returns>
 protected virtual IExpression DeepCopy(BoundExpression boundExpression)
 {
     if (boundExpression.Instance != null)
     boundExpression.Instance = Substitute(boundExpression.Instance);
       ILocalDefinition/*?*/ loc = boundExpression.Definition as ILocalDefinition;
       if (loc != null)
     boundExpression.Definition = this.GetMutableCopyIfItExists(loc);
       else {
     IParameterDefinition/*?*/ par = boundExpression.Definition as IParameterDefinition;
     if (par != null)
       boundExpression.Definition = this.GetMutableCopyIfItExists(par);
     else {
       IFieldReference/*?*/ field = boundExpression.Definition as IFieldReference;
       boundExpression.Definition = this.Substitute(field);
     }
       }
       boundExpression.Type = this.Substitute(boundExpression.Type);
       return boundExpression;
 }
Example #10
0
 public override IExpression Rewrite(IPopValue popValue)
 {
     var t = popValue.Type;
     Contract.Assume(0 < this.locals.Count);
     var local = this.locals.Pop();
     if (this.inThenBranch) {
       var depth = this.locals.Count;
       if (this.thenBranchPushes != null && this.thenBranchPushes.ContainsKey(depth) && local == this.thenBranchPushes[depth].Target.Definition)
         this.thenBranchPushes.Remove(depth);
     }
     var be = new BoundExpression() { Definition = local, Instance = null, Type = local.Type, };
     return be;
 }
Example #11
0
 /// <summary>
 /// Visits the specified bound expression.
 /// </summary>
 /// <param name="boundExpression">The bound expression.</param>
 public override void Visit(IBoundExpression boundExpression)
 {
     BoundExpression mutableBoundExpression = boundExpression as BoundExpression;
     if (alwaysMakeACopy || mutableBoundExpression == null) mutableBoundExpression = new BoundExpression(boundExpression);
     this.resultExpression = this.myCodeMutator.Visit(mutableBoundExpression);
 }
Example #12
0
 /// <summary>
 /// Visits the specified bound expression.
 /// </summary>
 /// <param name="boundExpression">The bound expression.</param>
 public override void Visit(IBoundExpression boundExpression)
 {
     BoundExpression mutableBoundExpression = new BoundExpression(boundExpression);
     this.resultExpression = this.myCodeCopier.DeepCopy(mutableBoundExpression);
 }
 /// <summary>
 /// Returns an expression that results in a closure object instance that contains the given field.
 /// If the expression will be evaluated in the body of this.method, the result is a bound expression
 /// that references the local that contains the object. Otherwise it is the "this" argument of the 
 /// anonymous delegate method, possibly with a number of field accesses to chase down the outer closure chain.
 /// </summary>
 /// <param name="closureField">A reference to a field from the "self instance" of a closure class.</param>
 private IExpression GetClosureObjectInstanceContaining(IFieldReference closureField) {
   if (this.isInsideAnonymousMethod) {
     IExpression result = new ThisReference() { Type = this.currentClosureSelfInstance };
     while (result.Type != closureField.ContainingType) {
       var outerClosureField = this.fieldReferencesForUseInsideAnonymousMethods[result.Type];
       result = new BoundExpression() { Instance = result, Definition = outerClosureField, Type = outerClosureField.Type };
     }
     return result;
   } else {
     foreach (var instance in this.closureLocalInstances) {
       if (instance.Type == closureField.ContainingType) return instance;
     }
     return this.currentClosureObject;
   }
 }
 /// <summary>
 /// Rewrites the children of the given bound expression.
 /// </summary>
 public override void RewriteChildren(BoundExpression boundExpression) {
   IFieldReference closureField;
   var map = this.isInsideAnonymousMethod ? this.fieldReferencesForUseInsideAnonymousMethods : this.fieldReferencesForUseInsideThisMethod;
   if (map.TryGetValue(boundExpression.Definition, out closureField)) {
     boundExpression.Instance = this.GetClosureObjectInstanceContaining(closureField);
     boundExpression.Definition = closureField;
     boundExpression.Type = closureField.Type;
     return;
   }
   base.RewriteChildren(boundExpression);
 }
Example #15
0
 /// <summary>
 /// Rewrites the children of the given bound expression.
 /// </summary>
 public virtual void RewriteChildren(BoundExpression boundExpression)
 {
     this.RewriteChildren((Expression)boundExpression);
       if (boundExpression.Instance != null)
     boundExpression.Instance = this.Rewrite(boundExpression.Instance);
       var local = boundExpression.Definition as ILocalDefinition;
       if (local != null)
     boundExpression.Definition = this.RewriteReference(local);
       else {
     var parameter = boundExpression.Definition as IParameterDefinition;
     if (parameter != null)
       boundExpression.Definition = this.RewriteReference(parameter);
     else {
       var fieldReference = (IFieldReference)boundExpression.Definition;
       boundExpression.Definition = this.Rewrite(fieldReference);
     }
       }
 }
Example #16
0
 /// <summary>
 /// If the <paramref name="boundExpression"/> represents a parameter of the target method,
 /// it is replaced with the equivalent parameter of the source method.
 /// </summary>
 /// <param name="boundExpression">The bound expression.</param>
 public override void RewriteChildren(BoundExpression boundExpression) {
   var/*?*/ par = boundExpression.Definition as IParameterDefinition;
   if (par != null && par.ContainingSignature == this.targetMethod) {
     boundExpression.Definition = this.parameters[par.Index];
     if (boundExpression.Instance != null) {
       boundExpression.Instance = this.Rewrite(boundExpression.Instance);
     }
     boundExpression.Type = this.Rewrite(boundExpression.Type);
     return;
   } else {
     base.RewriteChildren(boundExpression);
   }
 }
        /// <summary>
        /// Appends the statements afters the calls used to calculate the max of the tmp of all the calls
        /// </summary>
        protected void AppendStatementsTmpCopy(IMethodDefinition method, List<StatementTmpCopyInformation> statementsTmpCopy, Dictionary<IStatement, IBlockStatement> statementsContainingBlocks, Dictionary<string, GlobalPolyInfo> globalPolyInfoTmp)
        {
            var block = ((BasicBlock)((Microsoft.Cci.ILToCodeModel.SourceMethodBody)method.Body).Block);
            var methodStatements = block.Statements;

            var int32Type = _host.PlatformType.SystemInt32;

            var callNumber = 1;

            var localsInsertedByType = new Dictionary<ITypeReference, List<LocalDeclarationStatement>>();

            foreach (var statementCopyInformation in statementsTmpCopy)
            {
                var stmt = statementCopyInformation.AfterStatement;
                var statements = ((BlockStatement)statementsContainingBlocks[stmt]).Statements;

                var index = statements.IndexOf(stmt);
                if (index >= 0)
                {
                    IExpression initialValue = new BoundExpression() { Type = int32Type, Definition = GetTmpField(statementCopyInformation.CalledMethod, statementCopyInformation.TmpType) };
                    
                    var localDecl = new LocalDeclarationStatement()
                    {
                        InitialValue = initialValue,
                        LocalVariable = new LocalDefinition() { Type = int32Type, Name = _host.NameTable.GetNameFor("tmp_call_" + callNumber) }
                    };

                    callNumber++;

                    var tmpType = statementCopyInformation.TmpType;
                    if (!localsInsertedByType.ContainsKey(tmpType))
                    {
                        localsInsertedByType.Add(tmpType, new List<LocalDeclarationStatement>());
                    }
                    localsInsertedByType[tmpType].Add(localDecl);

                    if (!statementCopyInformation.InsideLoop)
                    {
                        statements.Insert(index + 1, localDecl);

                        var calledMethodName = statementCopyInformation.CalledMethodReference.ToString();
                        var contractLocalExpr = TranslateMethodContractToLocalExpression(
                               statementCopyInformation.CalledMethodReference,
                               stmt,
                               _memoryContractsInformation.MethodsTmpContracts[calledMethodName][statementCopyInformation.TmpType],
                               statementCopyInformation.CalledMethodArguments);

                        if (!_currentInstrInfo.GlobalPolyInfoTmp.ContainsKey(tmpType.ToString()))
                        {
                            _currentInstrInfo.GlobalPolyInfoTmp.Add(tmpType.ToString(), new GlobalPolyInfo());
                        }
                        _currentInstrInfo.GlobalPolyInfoTmp[tmpType.ToString()].MaxCalls.Add(contractLocalExpr);
                    }
                    else
                    {
                        localDecl.InitialValue = new CompileTimeConstant() { Type = int32Type, Value = 0 };
                        var loopContainingStatements = ((BasicBlock)statementsContainingBlocks[statementCopyInformation.LoopStartAt]).Statements;
                        loopContainingStatements.Insert(0, localDecl);
                        
                        bool doRegularInstrumentation = true;

                        if (!_currentInstrInfo.GlobalPolyInfoTmp.ContainsKey(tmpType.ToString()))
                        {
                            _currentInstrInfo.GlobalPolyInfoTmp.Add(tmpType.ToString(), new GlobalPolyInfo());
                        }

                        if (statementCopyInformation.LoopInvariants != null)
                        {
                            //invariants available, calculate the max directly and insert the assignment after the loop
                            
                            var calledMethodName = statementCopyInformation.CalledMethodReference.ToString();
                            if (_memoryContractsInformation.MethodsTmpContracts.ContainsKey(calledMethodName) &&
                                _memoryContractsInformation.MethodsTmpContracts[calledMethodName].ContainsKey(statementCopyInformation.TmpType))
                            {
                                var contractLocalExpr = TranslateMethodContractToLocalExpression(
                                    statementCopyInformation.CalledMethodReference,
                                    stmt,
                                    _memoryContractsInformation.MethodsTmpContracts[calledMethodName][statementCopyInformation.TmpType],
                                    statementCopyInformation.CalledMethodArguments);
                                var maxExprPolyCond = PolytopesCalculator.MaxOver(contractLocalExpr, statementCopyInformation.LoopInvariants, GetMethodFreeVars(_currentMethod));
                                IExpression maxPolyExpr = null;
                                IExpression maxCondExpr = null;

                                if (maxExprPolyCond != null)
                                {
                                    maxPolyExpr = ExpressionGenerator.GenerateExpressionFromString(maxExprPolyCond.Poly, _host, _currentMethod);
                                    maxCondExpr = ExpressionGenerator.GenerateExpressionFromString(maxExprPolyCond.Cond, _host, _currentMethod);
                                }

                                index = loopContainingStatements.IndexOf(statementCopyInformation.LoopEndAt);
                                if (index >= 0 && maxPolyExpr != null && maxCondExpr != null)
                                {
                                    doRegularInstrumentation = false;
                                    loopContainingStatements.Insert(index + 1,
                                        new ConditionalStatement()
                                        {
                                            Condition = maxCondExpr,
                                            TrueBranch = new ExpressionStatement()
                                            {
                                                Expression = new Assignment()
                                                {
                                                    Type = int32Type,
                                                    Source = maxPolyExpr,
                                                    Target = new TargetExpression() { Type = int32Type, Definition = localDecl.LocalVariable }
                                                }
                                            },
                                            FalseBranch = new EmptyStatement()
                                        });

                                    //store in the global poly info
                                    _currentInstrInfo.GlobalPolyInfoTmp[tmpType.ToString()].MaxCallsLoops.Add(maxExprPolyCond);
                                }
                            }
                        }

                        if (doRegularInstrumentation)
                        {
                            //no invariants available or could not calculate max, calculate instrumenting Math.Max calls

                            if (statementCopyInformation.InsideLoop)
                            {
                                _currentInstrInfo.GlobalPolyInfoTmp[tmpType.ToString()].AllContractsRequiredAvailable = false;
                            }
                            index = statements.IndexOf(stmt); //adjust the index, it could have changed because of the previous localDecl insertion
                            statements.Insert(index + 1,
                                new ExpressionStatement()
                                {
                                    Expression = new Assignment()
                                    {
                                        Type = int32Type,
                                        Source = BuildMaxCall(new BoundExpression() { Definition = localDecl.LocalVariable, Type = int32Type }, initialValue),
                                        Target = new TargetExpression() { Type = int32Type, Definition = localDecl.LocalVariable }
                                    }
                                });
                        }
                    }
                }
            }

            var appendToStatementList = ((BasicBlock)statementsContainingBlocks[_currentStatement]).Statements;

            foreach (var tmpType in localsInsertedByType.Keys)
            {
                bool doRegularInstrumentation = true;
                var tmpField = GetTmpField(method, tmpType);
                var globalInfoForTmp = globalPolyInfoTmp[tmpType.ToString()];

                //check if we can calculate the max with the polytopes calculator
                if (globalInfoForTmp.AllContractsRequiredAvailable)
                {
                    var polys = new List<string>();
                    var conds = new List<string>();

                    conds.AddRange(GetMethodRequiresExprs(method));

                    polys.AddRange(globalInfoForTmp.MaxCalls);
                    foreach (var poly in globalInfoForTmp.MaxCallsLoops)
                    {
                        polys.Add(poly.Poly);
                        conds.Add(poly.Cond);
                    }

                    var max = PolytopesCalculator.MaxPoly(polys, conds, GetMethodFreeVars(method));

                    if (max != null)
                    {
                        var condExpr = ExpressionGenerator.GenerateExpressionFromString(max.Cond, _host, method);
                        var maxExpr = ExpressionGenerator.GenerateExpressionFromString(max.Poly, _host, method);

                        if (condExpr != null && maxExpr != null)
                        {
                            InsertStatementAtBottom(appendToStatementList,
                                new ConditionalStatement()
                                {
                                    Condition = condExpr,
                                    TrueBranch =
                                        new ExpressionStatement()
                                        {
                                            Expression = new Assignment()
                                            {
                                                Type = int32Type,
                                                Source = new Addition()
                                                {
                                                    Type = int32Type,
                                                    LeftOperand = new BoundExpression() { Type = int32Type, Definition = tmpField },
                                                    RightOperand = maxExpr
                                                },
                                                Target = new TargetExpression() { Type = int32Type, Definition = tmpField }
                                            }
                                        },
                                    FalseBranch = new EmptyStatement()
                                });

                            doRegularInstrumentation = false;
                        }
                    }
                }

                if (doRegularInstrumentation)
                {
                    var maxExpr = GetMaxExpressionOverLocals(localsInsertedByType[tmpType]);

                    //add the statement tmpField += Math.Max(...);
                    InsertStatementAtBottom(appendToStatementList,
                        new ExpressionStatement()
                        {
                            Expression = new Assignment()
                            {
                                Type = int32Type,
                                Source = new Addition()
                                {
                                    Type = int32Type,
                                    LeftOperand = new BoundExpression() { Type = int32Type, Definition = tmpField },
                                    RightOperand = maxExpr
                                },
                                Target = new TargetExpression() { Type = int32Type, Definition = tmpField }
                            }
                        });
                }
            }
        }
Example #18
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;
    }
Example #19
0
    /// <summary>
    /// Create two properties: object Current and T Current as the closure class implements both the 
    /// generic and non-generic version of ienumerator. 
    /// 
    /// Current Implementation generates getters, but not the property.
    /// </summary>
    /// <param name="iteratorClosure">Information about the closure created when compiling the current iterator method</param>
    private void CreateIteratorClosureProperties(IteratorClosureInformation iteratorClosure) {
      // Non-generic version of the get_Current, which returns the generic version of get_Current. 
      MethodDefinition getterNonGenericCurrent = new MethodDefinition() {
        Attributes = new List<ICustomAttribute>(1),
        InternFactory = this.host.InternFactory,
        Name = this.host.NameTable.GetNameFor("System.Collections.IEnumerator.get_Current")
      };
      CustomAttribute debuggerHiddenAttribute = new CustomAttribute();
      debuggerHiddenAttribute.Constructor = this.DebuggerHiddenCtor;
      getterNonGenericCurrent.Attributes.Add(debuggerHiddenAttribute);
      getterNonGenericCurrent.CallingConvention |= CallingConvention.HasThis;
      getterNonGenericCurrent.Visibility |= TypeMemberVisibility.Public;
      getterNonGenericCurrent.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      getterNonGenericCurrent.Type = this.host.PlatformType.SystemObject;
      getterNonGenericCurrent.IsSpecialName = true;
      getterNonGenericCurrent.IsVirtual = true;
      getterNonGenericCurrent.IsNewSlot = true;
      getterNonGenericCurrent.IsHiddenBySignature = true;
      getterNonGenericCurrent.IsSealed = true;
      iteratorClosure.NonGenericGetCurrent = getterNonGenericCurrent;
      IMethodReference originalMethod = Dummy.MethodReference;
      foreach (ITypeMemberReference tref in iteratorClosure.NonGenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)) {
        originalMethod = tref as IMethodReference; if (originalMethod != null) break;
      }
      // assert originalMethod != Dummy
      MethodImplementation getterImplementation = new MethodImplementation() {
        ContainingType = iteratorClosure.ClosureDefinition,
        ImplementingMethod = getterNonGenericCurrent,
        ImplementedMethod = originalMethod
      };
      iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(getterImplementation);

      List<IStatement> statements = new List<IStatement>();
      IFieldReference currentField = iteratorClosure.CurrentFieldReference;
      BoundExpression thisDotCurr = new BoundExpression() {
        Definition = currentField,
        Instance = new ThisReference(),
        Locations = iteratorClosure.ClosureDefinition.Locations,
        Type = currentField.Type
      };
      IExpression returnExpression;
      if (!iteratorClosure.ElementType.IsValueType && TypeHelper.TypesAreAssignmentCompatible(iteratorClosure.ElementType.ResolvedType, this.host.PlatformType.SystemObject.ResolvedType)) {
        returnExpression = thisDotCurr;
      } else {
        Conversion convertion = new Conversion() {
          CheckNumericRange = false,
          Type = this.host.PlatformType.SystemObject,
          TypeAfterConversion = getterNonGenericCurrent.Type,
          ValueToConvert = thisDotCurr
        };
        returnExpression = convertion;
      }
      ReturnStatement returnCurrent = new ReturnStatement() {
        Expression = returnExpression,
        Locations = iteratorClosure.ClosureDefinition.Locations
      };
      statements.Add(returnCurrent);
      BlockStatement block = new BlockStatement() { Statements = statements };
      SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider);
      body.IsNormalized = true;
      body.LocalsAreZeroed = true;
      body.Block = block;
      body.MethodDefinition = getterNonGenericCurrent;
      getterNonGenericCurrent.Body = body;

      // Create generic version of get_Current, the body of which is simply returning this.current.
      MethodDefinition getterGenericCurrent = new MethodDefinition() {
        Attributes = new List<ICustomAttribute>(1),
        InternFactory = this.host.InternFactory,
        Name = this.host.NameTable.GetNameFor("System.Collections.Generic.IEnumerator<" + iteratorClosure.ElementType.ToString() +">.get_Current")
      };
      getterGenericCurrent.Attributes.Add(debuggerHiddenAttribute);

      getterGenericCurrent.CallingConvention |= CallingConvention.HasThis;
      getterGenericCurrent.Visibility |= TypeMemberVisibility.Public;
      getterGenericCurrent.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      getterGenericCurrent.Type = iteratorClosure.ElementType;
      getterGenericCurrent.IsSpecialName = true;
      getterGenericCurrent.IsVirtual = true;
      getterGenericCurrent.IsNewSlot = true;
      getterGenericCurrent.IsHiddenBySignature = true;
      getterGenericCurrent.IsSealed = true;
      iteratorClosure.GenericGetCurrent = getterGenericCurrent;
      originalMethod = Dummy.MethodReference;
      foreach (ITypeMemberReference tref in iteratorClosure.GenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)) {
        originalMethod = tref as IMethodReference; if (originalMethod != null) break;
      }
      MethodImplementation getterImplementation2 = new MethodImplementation() {
        ContainingType = iteratorClosure.ClosureDefinition,
        ImplementingMethod = getterGenericCurrent,
        ImplementedMethod = originalMethod
      };
      iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(getterImplementation2);

      statements = new List<IStatement>();
      currentField = iteratorClosure.CurrentFieldReference;
      BoundExpression thisDotCurrent = new BoundExpression() {
        Definition = currentField, Instance = new ThisReference(), Locations = iteratorClosure.ClosureDefinition.Locations, Type = currentField.Type
      };
      returnCurrent = new ReturnStatement() {
        Expression = thisDotCurrent,
        Locations = iteratorClosure.ClosureDefinition.Locations
      };
      statements.Add(returnCurrent);
      block = new BlockStatement() { Statements = statements };
      body = new SourceMethodBody(this.host, this.sourceLocationProvider);
      body.LocalsAreZeroed = true;
      body.Block = block;
      body.MethodDefinition = getterGenericCurrent;
      getterGenericCurrent.Body = body;
    }
 private Expression ParseBoundExpression(Instruction instruction) {
   Contract.Requires(instruction != null);
   IOperation currentOperation = instruction.Operation;
   if (currentOperation.Value == null)
     return new ThisReference();
   BoundExpression result = new BoundExpression();
   result.Alignment = this.alignment;
   result.Definition = currentOperation.Value;
   result.IsVolatile = this.sawVolatile;
   switch (currentOperation.OperationCode) {
     case OperationCode.Ldarg:
     case OperationCode.Ldarg_0:
     case OperationCode.Ldarg_1:
     case OperationCode.Ldarg_2:
     case OperationCode.Ldarg_3:
     case OperationCode.Ldarg_S:
       var par = result.Definition as IParameterDefinition;
       Contract.Assume(par != null);
       result.Type = par.IsByReference ? new ManagedPointerTypeReference() { TargetType = par.Type, InternFactory = this.host.InternFactory } :  par.Type;
       break;
     case OperationCode.Ldsfld:
       var field = result.Definition as IFieldReference;
       Contract.Assume(field != null);
       result.Type = field.Type;
       break;
     case OperationCode.Ldfld:
       result.Instance = this.PopOperandStack();
       goto case OperationCode.Ldsfld;
     case OperationCode.Ldloc:
     case OperationCode.Ldloc_0:
     case OperationCode.Ldloc_1:
     case OperationCode.Ldloc_2:
     case OperationCode.Ldloc_3:
     case OperationCode.Ldloc_S:
       if (this.instructionsThatMakeALastUseOfALocalVersion.Contains(instruction)) {
         this.instructionsThatMakeALastUseOfALocalVersion.Remove(instruction);
         this.bindingsThatMakeALastUseOfALocalVersion.Add(result);
       }
       Contract.Assume(result.Definition is ILocalDefinition);
       var locDef = (ILocalDefinition)result.Definition;
       var local = result.Definition = this.GetLocalWithSourceName(locDef);
       this.numberOfReferencesToLocal[local] =
         this.numberOfReferencesToLocal.ContainsKey(local) ?
         this.numberOfReferencesToLocal[local] + 1 :
         1;
       result.Type = locDef.IsReference ? new ManagedPointerTypeReference() { TargetType = locDef.Type, InternFactory = this.host.InternFactory } :  locDef.Type;
       break;
   }
   this.alignment = 0;
   this.sawVolatile = false;
   return result;
 }
 public static IExpression GenerateExpressionFromString(string strExpr, IMetadataHost host, IMethodDefinition method)
 {
     strExpr = Normalize(strExpr);
     string rpn = GetRPN(strExpr);
     Stack<IExpression> stVals = new Stack<IExpression>();
     RPNEnumerator rpnEnum = new RPNEnumerator(rpn);
     var int32Type = host.PlatformType.SystemInt32;
     var boolType = host.PlatformType.SystemBoolean;
     while (rpnEnum.MoveNext())
     {
         RPNValue rpnVal = (RPNValue)rpnEnum.Current;
         if (rpnVal.type == RPNValueType.OPERAND)
         {
             if (reNum.IsMatch(rpnVal.val))
             {
                 stVals.Push(new CompileTimeConstant() { Type = int32Type, Value = int.Parse(rpnVal.val.Replace(':', '-')) });
             }
             else
             {
                 IExpression expr = null;
                 var exprParts = rpnVal.val.Split('.');
                 if (exprParts[0] == "this")
                 {
                     expr = new ThisReference() { Type = method.ContainingType.ResolvedType };
                 }
                 else
                 {
                     foreach (var arg in method.Parameters)
                     {
                         if (arg.Name.Value == exprParts[0])
                         {
                             expr = new BoundExpression() { Type = arg.Type.ResolvedType, Definition = arg };
                             break;
                         }
                     }
                 }
                 if (expr != null && exprParts.Length > 1)
                 {
                     for (int i = 1; i < exprParts.Length; i++)
                     {
                         expr = GetExprWithAccesor(expr, exprParts[i], host);
                     }
                 }
                 if (expr == null || expr.Type.ResolvedType != int32Type.ResolvedType)
                 {
                     return null;
                 }
                 stVals.Push(expr);
             }
         }
         else
         {
             var v1 = stVals.Pop();
             var v2 = stVals.Pop();
             if      (rpnVal.val == "+") stVals.Push(new Addition() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "-") stVals.Push(new Subtraction() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "*") stVals.Push(new Multiplication() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "/") stVals.Push(new Division() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "=") stVals.Push(new Equality() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "&") stVals.Push(new Conditional() { Type = boolType, Condition = v2, ResultIfTrue = v1, ResultIfFalse = new CompileTimeConstant() { Type = int32Type, Value = 0 } });
             else if (rpnVal.val == "|") stVals.Push(new Conditional() { Type = boolType, Condition = v2, ResultIfTrue = new CompileTimeConstant() { Type = int32Type, Value = 1 }, ResultIfFalse = v1 });
             else if (rpnVal.val == ">") stVals.Push(new GreaterThan() { Type = boolType, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "<") stVals.Push(new LessThan() { Type = boolType, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "%") stVals.Push(new GreaterThanOrEqual() { Type = boolType, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "#") stVals.Push(new LessThanOrEqual() { Type = boolType, LeftOperand = v2, RightOperand = v1 });
             else return null;
         }
     }
     if (stVals.Count > 0)
     {
         return stVals.Pop();
     }
     return null;
 }
 /// <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;
 }
Example #23
0
 /// <summary>
 /// The source expression "new C(){ f1 = e1, f2 = e2, ... }" (where the f's can be fields
 /// or properties) turns into "cgl = new C(); cgl.f1 = e1; cg1.f2 = e2; ...".
 /// ("cgl" means "compiler-generated local".)
 /// Turn it into a block expression whose Statements are the statements above (but where
 /// the first one becomes a local declaration statement), and with an Expression that is
 /// just the local, cgl', where cgl' is a freshly created local.
 /// </summary>
 private bool ReplaceCompilerGeneratedLocalUsedForInitializersPattern(BlockStatement b) {
   Contract.Requires(b != null);
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 0; i < statements.Count - 1; i++) {
     var expressionStatement = statements[i] as ExpressionStatement;
     if (expressionStatement == null) continue;
     var assignment = expressionStatement.Expression as Assignment;
     if (assignment == null) continue;
     var local = assignment.Target.Definition as ILocalDefinition;
     if (local == null || local is CapturedLocalDefinition) continue;
     if (this.numberOfAssignmentsToLocal[local] != 1) continue;
     if (this.sourceLocationProvider != null) {
       bool isCompilerGenerated;
       var sourceName = this.sourceLocationProvider.GetSourceNameFor(local, out isCompilerGenerated);
       if (!isCompilerGenerated) continue;
     }
     var createObject = assignment.Source as ICreateObjectInstance;
     if (createObject == null) continue;
     if (!this.singleUseExpressionChecker.ExpressionCanBeMovedAndDoesNotReference(assignment.Source, local)) continue;
     var j = 1;
     while (i + j < statements.Count - 1 && IsAssignmentToFieldOrProperty(local, statements[i + j])) j++;
     if (j == 1) continue;
     if (this.numberOfReferencesToLocal[local] != (uint)j) continue;
     Contract.Assume(i + j < statements.Count); //i < statements.Count-1 and (j == 1 or the loop above established i+j < statements.Count-1)
     Contract.Assume(statements[i + j] != null);
     if (LocalFinder.LocalOccursIn(statements[i+j], local) && this.singleAssignmentReferenceFinder.LocalCanBeReplacedIn(statements[i + j], local)) {
       var newLocal = new LocalDefinition() {
         Name = this.host.NameTable.GetNameFor(local.Name.Value + "_prime"),
         MethodDefinition = local.MethodDefinition,
         Type = local.Type,
       };
       var lds = new LocalDeclarationStatement() {
         InitialValue = assignment.Source,
         LocalVariable = newLocal,
       };
       var stmts = new List<IStatement>(j) { lds, };
       var boundExpression = new BoundExpression() { Definition = newLocal, Instance = null, Type = newLocal.Type, };
       foreach (var s in statements.GetRange(i + 1, j - 1)) {
         Contract.Assume(s != null);
         this.singleAssignmentLocalReplacer.Replace(boundExpression, local, s);
         stmts.Add(s);
       }
       var blockExpression = new BlockExpression() {
         BlockStatement = new BlockStatement() {
           Statements = stmts,
         },
         Expression = new BoundExpression() { Definition = newLocal, Instance = null, Type = newLocal.Type, },
         Type = newLocal.Type,
       };
       if (this.singleAssignmentLocalReplacer.Replace(blockExpression, local, statements[i + j])) {
         this.numberOfAssignmentsToLocal[newLocal] = 1;
         this.numberOfReferencesToLocal[newLocal] = (uint)j;
         this.numberOfAssignmentsToLocal[local]--;
         this.numberOfReferencesToLocal[local] = 0;
         statements.RemoveRange(i, j);
         replacedPattern = true;
       } else
         Contract.Assume(false); // replacement should succeed since the combination of LocalOccursIn and LocalCanBeReplacedIn returned true
     }
   }
   return replacedPattern;
 }
Example #24
0
 private Expression ParseBoundExpression(IOperation currentOperation)
 {
     if (currentOperation.Value == null)
     return new ThisReference();
       BoundExpression result = new BoundExpression();
       result.Alignment = this.alignment;
       result.Definition = currentOperation.Value;
       result.IsVolatile = this.sawVolatile;
       var parameter = result.Definition as IParameterDefinition;
       if (parameter != null) {
     result.Type = parameter.Type;
     if (parameter.IsByReference) result.Type = Immutable.ManagedPointerType.GetManagedPointerType(result.Type, this.host.InternFactory);
       } else {
     var local = result.Definition as ILocalDefinition;
     if (local != null) {
       result.Definition = this.GetLocalWithSourceName(local);
       result.Type = local.Type;
       if (local.IsReference) result.Type = Immutable.ManagedPointerType.GetManagedPointerType(result.Type, this.host.InternFactory);
     } else {
       var field = (IFieldReference)result.Definition;
       result.Type = field.Type;
     }
       }
       switch (currentOperation.OperationCode) {
     case OperationCode.Ldfld:
       result.Instance = this.PopOperandStack();
       break;
     case OperationCode.Ldloc:
     case OperationCode.Ldloc_0:
     case OperationCode.Ldloc_1:
     case OperationCode.Ldloc_2:
     case OperationCode.Ldloc_3:
     case OperationCode.Ldloc_S:
       this.numberOfReferences[result.Definition] =
     this.numberOfReferences.ContainsKey(result.Definition) ?
     this.numberOfReferences[result.Definition] + 1 :
     1;
       break;
       }
       this.alignment = 0;
       this.sawVolatile = false;
       return result;
 }
Example #25
0
 /// <summary>
 /// Visits the specified bound expression.
 /// </summary>
 /// <param name="boundExpression">The bound expression.</param>
 /// <returns></returns>
 public virtual IExpression Visit(BoundExpression boundExpression)
 {
     if (boundExpression.Instance != null)
     boundExpression.Instance = Visit(boundExpression.Instance);
       ILocalDefinition/*?*/ loc = boundExpression.Definition as ILocalDefinition;
       if (loc != null)
     boundExpression.Definition = this.VisitReferenceTo(loc);
       else {
     IParameterDefinition/*?*/ par = boundExpression.Definition as IParameterDefinition;
     if (par != null)
       boundExpression.Definition = this.VisitReferenceTo(par);
     else {
       IFieldReference/*?*/ field = boundExpression.Definition as IFieldReference;
       boundExpression.Definition = this.Visit(field);
     }
       }
       boundExpression.Type = this.Visit(boundExpression.Type);
       return boundExpression;
 }