Example #1
0
 /// <summary>
 /// Add sources that are disposable on entry, such as byref disposables
 /// </summary>
 /// <param name="dictionary"></param>
 private IEnumerable <Instruction> InitialSources(FMap <IParameterDefinition, Instruction> initialParameters)
 {
     foreach (var p in this.currentMethod.Parameters)
     {
         Instruction initialDummyInit;
         if (p.IsByReference && !p.IsOut && IsDisposableType(p.Type) && initialParameters.TryGetValue(p, out initialDummyInit))
         {
             yield return(initialDummyInit);
         }
     }
 }
Example #2
0
        private static Analysis.Instruction ReadLocation(FMap <ILocalDefinition, Analysis.Instruction> currentLocals, FMap <IParameterDefinition, Analysis.Instruction> currentParameters, object localOrParameter)
        {
            Analysis.Instruction result;
            var local = localOrParameter as ILocalDefinition;

            if (local != null)
            {
                currentLocals.TryGetValue(local, out result);
                return(result);
            }
            var param = localOrParameter as IParameterDefinition;

            if (param != null)
            {
                currentParameters.TryGetValue(param, out result);
                return(result);
            }
            return(null);
        }
Example #3
0
        private static void ComputeDataFlowThroughLocals(ControlAndDataFlowGraph <BasicBlock, Instruction> cdg)
        {
            FMap <ILocalDefinition, Microsoft.Cci.Analysis.Instruction> currentLocals;

            var todo       = new Queue <BlockPC>();
            var seen       = new HashSet <BlockPC>();
            var startBlock = cdg.RootBlocks[0];

            FMap <IParameterDefinition, Microsoft.Cci.Analysis.Instruction> currentParameters = new FMap <IParameterDefinition, Microsoft.Cci.Analysis.Instruction>(k => k.Index);

            var initialLocation = GetStartLocation(startBlock);

            // push parameters onto start block
            foreach (var arg in cdg.MethodBody.MethodDefinition.Parameters)
            {
                var initialOp  = new InitialParameterAssignment(arg, initialLocation);
                var initialDef = new Instruction()
                {
                    Operation = initialOp
                };
                currentParameters = currentParameters.Insert(arg, initialDef);
            }
            startBlock.ParamDefs = currentParameters;
            todo.Enqueue(new BlockPC(startBlock.Offset.Singleton()));

            while (todo.Count > 0)
            {
                var currentPC = todo.Dequeue();
                if (seen.Contains(currentPC))
                {
                    continue;
                }
                seen.Add(currentPC);

                var block = cdg.CurrentBlock(currentPC);
                Contract.Assume(block != null);

                currentLocals     = block.LocalDefs;
                currentParameters = block.ParamDefs;

                foreach (var instr in block.Instructions)
                {
                    if (instr.IsMergeNode)
                    {
                        continue;
                    }
                    switch (instr.Operation.OperationCode)
                    {
                    case OperationCode.Starg:
                    case OperationCode.Starg_S:
                        // without pdb we seem to have no parameter info.
                        var pdef = (IParameterDefinition)instr.Operation.Value;
                        if (pdef != null)
                        {
                            currentParameters = currentParameters.Insert(pdef, instr.Operand1);
                        }
                        break;

                    case OperationCode.Stloc:
                    case OperationCode.Stloc_0:
                    case OperationCode.Stloc_1:
                    case OperationCode.Stloc_2:
                    case OperationCode.Stloc_3:
                    case OperationCode.Stloc_S:
                        var ldef = (ILocalDefinition)instr.Operation.Value;
                        currentLocals = currentLocals.Insert(ldef, instr.Operand1);
                        break;

                    case OperationCode.Ldloc:
                    case OperationCode.Ldloc_0:
                    case OperationCode.Ldloc_1:
                    case OperationCode.Ldloc_2:
                    case OperationCode.Ldloc_3:
                    case OperationCode.Ldloc_S:
                        // save the source in Aux
                    {
                        currentLocals.TryGetValue((ILocalDefinition)instr.Operation.Value, out instr.Aux);
                        break;
                    }

                    case OperationCode.Ldarg:
                    case OperationCode.Ldarg_0:
                    case OperationCode.Ldarg_1:
                    case OperationCode.Ldarg_2:
                    case OperationCode.Ldarg_3:
                    case OperationCode.Ldarg_S:
                        // save the source in Aux
                        var pdef2 = (IParameterDefinition)instr.Operation.Value;
                        if (pdef2 == null)
                        {
                            // this parameter. Assume it's never overwritten
                        }
                        else
                        {
                            currentParameters.TryGetValue(pdef2, out instr.Aux);
                        }
                        break;

                    case OperationCode.Stind_I:
                    case OperationCode.Stind_I1:
                    case OperationCode.Stind_I2:
                    case OperationCode.Stind_I4:
                    case OperationCode.Stind_I8:
                    case OperationCode.Stind_R4:
                    case OperationCode.Stind_R8:
                    case OperationCode.Stind_Ref:
                    {
                        var location = cdg.LocalOrParameter(instr.Operand1);
                        UpdateLocation(ref currentLocals, ref currentParameters, location, (Analysis.Instruction)instr.Operand2);

                        break;
                    }

                    case OperationCode.Ldind_I:
                    case OperationCode.Ldind_I1:
                    case OperationCode.Ldind_I2:
                    case OperationCode.Ldind_I4:
                    case OperationCode.Ldind_I8:
                    case OperationCode.Ldind_R4:
                    case OperationCode.Ldind_R8:
                    case OperationCode.Ldind_Ref:
                    case OperationCode.Ldind_U1:
                    case OperationCode.Ldind_U2:
                    case OperationCode.Ldind_U4:
                    {
                        // save the read value in Aux
                        var location = cdg.LocalOrParameter(instr.Operand1);
                        instr.Aux = ReadLocation(currentLocals, currentParameters, location);
                        break;
                    }

                    case OperationCode.Call:
                    case OperationCode.Callvirt:
                    {
                        // update byref / out parameters
                        var methodRef = instr.Operation.Value as IMethodReference;
                        var args      = instr.Operand2 as Instruction[];
                        if (args != null && methodRef != null)
                        {
                            foreach (var p in methodRef.Parameters)
                            {
                                if (p.IsByReference && p.Index < args.Length)
                                {
                                    var arg = args[p.Index];
                                    if (arg != null)
                                    {
                                        var loc         = cdg.LocalOrParameter(arg);
                                        var syntheticOp = new CallByRefAssignment(instr, p);
                                        UpdateLocation(ref currentLocals, ref currentParameters, loc, new Instruction()
                                            {
                                                Operation = syntheticOp, Type = p.Type
                                            });
                                    }
                                }
                            }
                        }
                        break;
                    }
                    }
                    instr.PostLocalDefs = currentLocals;
                    instr.PostParamDefs = currentParameters;
                }
                foreach (var succ in cdg.Successors(currentPC))
                {
                    MergeLocalsAndParameters(cdg.CurrentBlock(succ), currentLocals, currentParameters);
                    todo.Enqueue(succ);
                }
            }
        }