private AbstractStackState <VariabilityInfo> HandleLdsfld(ILInstruction ili, AbstractStackState <VariabilityInfo> pre) { FieldInfo field = (FieldInfo)ili.Operand; FieldFacts fieldFacts = FactUniverse.Instance.GetFacts(field); EVariability fieldVar = fieldFacts.IsWritten || fieldFacts.IsSubMutated ? EVariability.ExternVariable : EVariability.Constant; VariabilityInfo newVar = VariabilityInfo.CreateBySingleDef(fieldVar, ili.Index); return(pre .Push(newVar) .UniqueSuccessor()); }
/// <summary> /// Returns the stronger of two variability classifications in order Constant, LocalVariable, ExternVariable /// </summary> /// <param name="a">first variability</param> /// <param name="b">second variability</param> /// <returns>stronger of both variabilities</returns> public static EVariability Stronger(EVariability a, EVariability b) { switch (a) { case EVariability.ExternVariable: return(EVariability.ExternVariable); case EVariability.LocalVariable: return(b == EVariability.ExternVariable ? EVariability.ExternVariable : EVariability.LocalVariable); case EVariability.Constant: return(b); default: throw new NotImplementedException(); } }
private AbstractStackState <VariabilityInfo> HandleCall(ILInstruction ili, AbstractStackState <VariabilityInfo> pre, bool isCalli) { MethodBase callee = (MethodBase)ili.Operand; bool hasThis = callee.CallingConvention.HasFlag(CallingConventions.HasThis); EVariability callVar = EVariability.Constant; ParameterInfo[] args = callee.GetParameters(); MethodFacts myFacts = FactUniverse.Instance.GetFacts(Method); MethodFacts calleeFacts = FactUniverse.Instance.GetFacts(callee); AbstractStackState <VariabilityInfo> next = pre; if (hasThis) { callVar = VariabilityOperations.Stronger(callVar, pre[0].Variability); next = pre.Pop(); } for (int i = 0; i < args.Length; i++) { callVar = VariabilityOperations.Stronger(callVar, next[0].Variability); next = next.Pop(); } if (!calleeFacts.IsSideEffectFree) { callVar = EVariability.ExternVariable; } if (calleeFacts.IsStaticEvaluation) { callVar = EVariability.Constant; } if (isCalli) { next = pre.Pop(); } VariabilityInfo callVarI = VariabilityInfo.CreateBySingleDef(callVar, ili.Index); next = UpdateStackState(ili, callVarI, next); Type returnType; if (callee.IsFunction(out returnType)) { next = next.Push(callVarI); } return(next.UniqueSuccessor()); }
private AbstractStackState <VariabilityInfo> HandleLdfld(ILInstruction ili, AbstractStackState <VariabilityInfo> pre) { FieldInfo field = (FieldInfo)ili.Operand; int index = Array.IndexOf(_localizedFields, field); if (index >= 0) { return(HandleLdloc(null, pre.Pop(), _localizedFieldsBaseIndex + index)); } else { FieldFacts fieldFacts = FactUniverse.Instance.GetFacts(field); EVariability fieldVar = fieldFacts.IsWritten || fieldFacts.IsSubMutated ? EVariability.ExternVariable : EVariability.Constant; VariabilityInfo newVar = VariabilityInfo.CreateBySingleDef(fieldVar, ili.Index); return(pre .Pop() .Push(newVar) .UniqueSuccessor()); } }
/// <summary> /// Constructs an instance based on a variability and a single reaching definition /// </summary> /// <param name="var">variability classification</param> /// <param name="def">one and only reaching definition</param> /// <returns>an instance representing the supplied arguments</returns> public static VariabilityInfo CreateBySingleDef(EVariability var, int def) { return(new VariabilityInfo(var, new int[] { def })); }
/// <summary> /// Constructs a new instance given a variability and reaching definitions /// </summary> /// <param name="variability">Variability classification</param> /// <param name="definitions">Reaching definitions</param> public VariabilityInfo(EVariability variability, IEnumerable <int> definitions) { Variability = variability; Definitions = definitions; }
private void DecompileAndEnqueueCallees(CodeDescriptor cd, object instance, object[] arguments, MethodCallInfo mymci = null) { IPackageOrComponentDescriptor owner = cd.Owner as IPackageOrComponentDescriptor; var rmd = cd.Method.GetCustomOrInjectedAttribute<RewriteMethodDefinition>(); IDecompilationResult result; var md = cd as MethodDescriptor; var pd = cd as ProcessDescriptor; if (pd != null) _context.CurrentProcess = pd.Instance; else _context.CurrentProcess = md.CallingProcess.Instance; EVariability[] argVar; if (md == null) argVar = new EVariability[0]; else argVar = md.ArgVariabilities; if (rmd != null) { result = rmd.Rewrite(_context, cd, instance, arguments); } else if (cd.Method.IsMoveNext()) { var decomp = new AsyncMethodDecompiler(_context, cd, instance, arguments); result = decomp.Decompile(); cd.Implementation = result.Decompiled; cd.GenuineImplementation = result.Decompiled; } else { var decomp = new MSILDecompiler(cd, instance, arguments, argVar); if (cd is ProcessDescriptor) { decomp.Template.DisallowReturnStatements = true; } decomp.Template.DisallowConditionals = true; if (mymci != null) mymci.Inherit(decomp.Template); result = decomp.Decompile(); cd.Implementation = result.Decompiled; cd.GenuineImplementation = result.Decompiled; } foreach (var mci in result.CalledMethods) { _methodQ.Enqueue(mci); } foreach (var fri in result.ReferencedFields) { AnalyzeFieldRef(fri, cd); } _allMethods.Add(cd); }
private void DecompileAndEnqueueCallees(CodeDescriptor cd, object instance, object[] arguments, MethodCallInfo mymci = null) { IPackageOrComponentDescriptor owner = cd.Owner as IPackageOrComponentDescriptor; var rmd = cd.Method.GetCustomOrInjectedAttribute <RewriteMethodDefinition>(); IDecompilationResult result; var md = cd as MethodDescriptor; var pd = cd as ProcessDescriptor; if (pd != null) { _context.CurrentProcess = pd.Instance; } else { _context.CurrentProcess = md.CallingProcess.Instance; } EVariability[] argVar; if (md == null) { argVar = new EVariability[0]; } else { argVar = md.ArgVariabilities; } if (rmd != null) { result = rmd.Rewrite(_context, cd, instance, arguments); } else if (cd.Method.IsMoveNext()) { var decomp = new AsyncMethodDecompiler(_context, cd, instance, arguments); result = decomp.Decompile(); cd.Implementation = result.Decompiled; cd.GenuineImplementation = result.Decompiled; } else { var decomp = new MSILDecompiler(cd, instance, arguments, argVar); if (cd is ProcessDescriptor) { decomp.Template.DisallowReturnStatements = true; } decomp.Template.DisallowConditionals = true; if (mymci != null) { mymci.Inherit(decomp.Template); } result = decomp.Decompile(); cd.Implementation = result.Decompiled; cd.GenuineImplementation = result.Decompiled; } foreach (var mci in result.CalledMethods) { _methodQ.Enqueue(mci); } foreach (var fri in result.ReferencedFields) { AnalyzeFieldRef(fri, cd); } _allMethods.Add(cd); }