private void ProcessStaticConstructors(ITypeDefinition ty) { if (!rtaAnalyzer.clinitProcessedClasses.Contains(ty) && !Stubber.SuppressM(ty)) { rtaAnalyzer.clinitProcessedClasses.Add(ty); IMethodDefinition clinitMeth = Utils.GetStaticConstructor(ty); if (clinitMeth != null) { Stubber.CheckAndAdd(clinitMeth); } if (ty.BaseClasses.Any()) { ITypeDefinition baseTy = ty.BaseClasses.Single().ResolvedType; ProcessStaticConstructors(baseTy); } foreach (ITypeReference itf in ty.Interfaces) { ITypeDefinition itfD = itf.ResolvedType; ProcessStaticConstructors(itfD); } } }
public MethodCfgAndTac AnalyzeIntraProcedural(IMethodDefinition methodDefinition) { // System.Console.WriteLine("Traversing: {0}", methodDefinition.GetName()); if (Stubber.SuppressM(methodDefinition)) { return(null); } if (methodDefinition.IsExternal) { return(null); } if (methodDefinition.IsAbstract) { return(null); } ITypeDefinition containingDefn = methodDefinition.ContainingTypeDefinition; ISourceLocationProvider sourceLocationProvider = null; if (containingDefn != null) { IModule mod = TypeHelper.GetDefiningUnit(containingDefn) as IModule; if (moduleToPdbMap.ContainsKey(mod)) { sourceLocationProvider = moduleToPdbMap[mod]; } else { if (!(mod == null || mod == Dummy.Module || mod == Dummy.Assembly)) { sourceLocationProvider = GetPdbReader(mod.Location); moduleToPdbMap[mod] = sourceLocationProvider; } } } var disassembler = new Disassembler(host, methodDefinition, sourceLocationProvider); var methodBody = disassembler.Execute(); var cfAnalysis = new ControlFlowAnalysis(methodBody); // var cfg = cfAnalysis.GenerateNormalControlFlow(); var cfg = cfAnalysis.GenerateExceptionalControlFlow(); var domAnalysis = new DominanceAnalysis(cfg); domAnalysis.Analyze(); domAnalysis.GenerateDominanceTree(); var loopAnalysis = new NaturalLoopAnalysis(cfg); loopAnalysis.Analyze(); var domFrontierAnalysis = new DominanceFrontierAnalysis(cfg); domFrontierAnalysis.Analyze(); var splitter = new WebAnalysis(cfg, methodDefinition); splitter.Analyze(); splitter.Transform(); methodBody.UpdateVariables(); var typeAnalysis = new TypeInferenceAnalysis(cfg, methodDefinition.Type); typeAnalysis.Analyze(); var forwardCopyAnalysis = new ForwardCopyPropagationAnalysis(cfg); forwardCopyAnalysis.Analyze(); forwardCopyAnalysis.Transform(methodBody); // backwardCopyAnalysis is buggy - it says so in the source file - see notes in src/test // var backwardCopyAnalysis = new BackwardCopyPropagationAnalysis(cfg); // backwardCopyAnalysis.Analyze(); // backwardCopyAnalysis.Transform(methodBody); var liveVariables = new LiveVariablesAnalysis(cfg); liveVariables.Analyze(); var ssa = new StaticSingleAssignment(methodBody, cfg); ssa.Transform(); ssa.Prune(liveVariables); methodBody.UpdateVariables(); MethodCfgAndTac mct = new MethodCfgAndTac(cfg, methodBody); foreach (IExceptionHandlerBlock ehInfo in disassembler.GetExceptionHandlers()) { if (ehInfo is CatchExceptionHandler) { mct.ehInfoList.Add(ehInfo as CatchExceptionHandler); } } return(mct); }
public void ProcessVirtualInvoke(IMethodDefinition mCallee, ITypeDefinition calleeClass, bool isAddrTaken) { // mCallee is an ordinary method - never a template method. // calleeClass and mCallee are either both stubbed or, both unstubbed - i.e. they are consistent. bool isInterface = calleeClass.IsInterface; IMethodDefinition calleeTemplate = null; if (mCallee is IGenericMethodInstance) { calleeTemplate = (mCallee as IGenericMethodInstance).GenericMethod.ResolvedMethod; } foreach (ITypeDefinition cl in allocClasses) { if (cl is IArrayTypeReference) { continue; } if (!Stubber.SuppressM(cl)) { bool process = false; if (isInterface && Utils.ImplementsInterface(cl, calleeClass)) { process = true; } if (Utils.ExtendsClass(cl, calleeClass)) { process = true; } if (!process) { continue; } IMethodDefinition calleeArg; if (mCallee is IGenericMethodInstance) { calleeArg = calleeTemplate; } else { calleeArg = mCallee; } IMethodDefinition meth = Utils.GetMethodSignMatchRecursive(cl, calleeArg); if (meth == null) { continue; } if (meth.IsGeneric && calleeTemplate != null) { IMethodDefinition instMeth = GenericMethods.RecordInfo(meth, mCallee, /* createIfReqd = */ true); IMethodDefinition addedMeth = Stubber.CheckAndAdd(instMeth); if (addedMeth != null && isAddrTaken) { addrTakenMethods.Add(addedMeth); } } else if (meth.IsGeneric && calleeTemplate == null) { continue; } else if (!meth.IsGeneric && calleeTemplate != null) { continue; } else // meth is not generic and calleeTemplate is null { IMethodDefinition addedMeth = Stubber.CheckAndAdd(meth); if (addedMeth != null && isAddrTaken) { addrTakenMethods.Add(addedMeth); } } } } }