コード例 #1
0
ファイル: DebugLiveness.cs プロジェクト: danielwidmann/esharp
        public static Dictionary <ILInstruction, string> DebugLocalLiveness(ILFunction method, IEnumerable <ILVariable> variables)       //DecompilerContext context,
        {
            var insts    = LivenessHelper.GetInstructions(method);
            var live_in  = insts.Select(x => "").ToList();
            var live_out = insts.Select(x => "").ToList();

            Liveness.ControlFlow(insts, out int[][] succ, out int[][] pres);

            foreach (var v in variables)
            {
                var live = Liveness.CalcLiveness(insts, v, succ, pres);

                for (int idx = 0; idx < live.Length; idx++)
                {
                    if (live[idx].LiveIn)
                    {
                        live_in[idx] += v.Name + ",";
                    }
                    if (live[idx].LiveOut)
                    {
                        live_out[idx] += v.Name + ",";
                    }
                }
            }

            var zipped = live_in.Zip(live_out, (x, y) => "[" + x + "|" + y + "]").ToArray();

            var d = new Dictionary <ILInstruction, string>();

            for (int i = 0; i < insts.Count; i++)
            {
                d.Add(insts[i], zipped[i]);
            }

            return(d);
        }
コード例 #2
0
        public void Run(ILFunction function, ILTransformContext context)
        {
            var insts = LivenessHelper.GetInstructions(function);

            if (insts.Count == 1)
            {
                // empty body, skip method
                return;
            }

            // skip marked methods
            //if (function.CecilMethod.CustomAttributes.Any(x => x.AttributeType.Name == "ManualRefCounting"))
            if (function.Method.GetAttributes().Any(x => x.AttributeType.Name == "ManualRefCounting"))
            {
                return;
            }

            IEnumerable <ILVariable> vars = function.Variables;

            var usedVars = new List <ILVariable>();

            foreach (var v in vars)
            {
                //var aliasSource = TypeInference.GetAliasSource(v);

                //// don't ref count parameters like this. Todo check for out and ref parameters (does O work already?)
                //if (aliasSource?.Kind == VariableKind.Parameter && aliasSource.StackType == StackType.O)
                //	continue;

                // no typeof intermediate variables
                if (v.StoreInstructions.Count == 1 && (v.StoreInstructions.First() as StLoc)?.Value is LdTypeToken)
                {
                    continue;
                }

                // skip variables that only contain NULL, etc
                if (TypeInference.GetVariableType(v) == null)
                {
                    continue;
                }

                // only reference types or valuetypes that require ref counting
                if (TypeInference.GetVariableType(v).Kind == TypeKind.Pointer)
                {
                    continue;

                    var pType    = TypeInference.GetVariableType(v) as ICSharpCode.Decompiler.TypeSystem.PointerType;
                    var elemType = pType.ElementType;

                    //if (!elemType.IsReferenceType.Value)
                    //	continue;
                    if (!elemType.IsReferenceType.Value && !elemType.GetMethods().Any(x => x.Name.EndsWith("_AddRef")))
                    {
                        continue;
                    }
                }
                else
                {
                    if (!TypeInference.GetVariableType(v).IsReferenceType.Value&& !TypeInference.GetVariableType(v).GetMethods().Any(x => x.Name.EndsWith("_AddRef")))
                    {
                        continue;
                    }
                }


                // references are not supported in C
                Debug.Assert(TypeInference.GetVariableType(v).Kind != TypeKind.ByReference);


                //todo: are the following two needed?
                //if (TypeInference.GetVariableType(v).Kind == TypeKind.Pointer)
                //	continue;

                //if (TypeInference.GetVariableType(v).Kind == TypeKind.ByReference)
                //	continue;

                usedVars.Add(v);
            }

            vars = usedVars.ToArray();

            var liveDebug = DebugLiveness.DebugLocalLiveness(function, vars);

            AddRefCountingLocalLiveness(insts, vars);

            ILAstDebugPrinter.DebugIlAst(function, "after_ref", liveDebug);

            // Add casts to make compiler happy
            // Todo: I would prefer to access base field insead. No easy representation at this stage though.
            // Todo: move to own optimization
            foreach (var c in function.Body.Descendants.OfType <CallInstruction>())
            {
                for (int idx = 0; idx < c.Method.Parameters.Count; idx++)
                {
                    var p     = c.Method.Parameters[idx];
                    var value = c.Arguments[idx];

                    var argType = TypeInference.GetInstType(value);
                    var pType   = p.Type;

                    if (argType != null && argType != pType)
                    {
                        value.ReplaceWith(new CastClass(value.Clone(), pType));
                    }
                }
            }
        }