private RewriteStoreLocal(IMetadataHost host, ILRewriter rewriter) : base(host) { this.ilRewriter = rewriter; }
public static MemoryStream RewriteProgramIL(CeleriacArgs celeriacArgs, TypeManager typeManager) { if (String.IsNullOrWhiteSpace(celeriacArgs.AssemblyPath)) { throw new FileNotFoundException("Path to program to be profiled not provided"); } Stream resultStream; var host = typeManager.Host; IModule /*?*/ module = host.LoadUnitFrom(celeriacArgs.AssemblyPath) as IModule; if (module == null || module == Dummy.Module || module == Dummy.Assembly) { throw new FileNotFoundException("Given path is not a PE file containing a CLR" + " assembly, or an error occurred when loading it.", celeriacArgs.AssemblyPath); } if (module.GetAllTypes().Any( type => type.Name.ToString().Equals(ILRewriter.ArgumentStoringClassName))) { throw new InvalidOperationException("Program has already been instrumented."); } string pdbFile = Path.ChangeExtension(module.Location, "pdb"); Assembly mutable = null; using (var pdbReader = LoadPdbReaderAndFile(celeriacArgs, typeManager, module, pdbFile)) { AssemblySummary comparabilityManager = GenerateComparability(celeriacArgs, typeManager, host, module, pdbReader, ref mutable); if (celeriacArgs.GenerateComparability && celeriacArgs.ComparabilityFile == null) { return(null); } ILRewriter mutator = new ILRewriter(host, pdbReader, celeriacArgs, typeManager, comparabilityManager); module = mutator.Visit(mutable, Path.Combine(FindVisitorDir(), VisitorDll)); if (celeriacArgs.EmitNullaryInfo || celeriacArgs.GenerateComparability) { return(null); } // Remove the old PDB file try { File.Delete(pdbFile); } catch (UnauthorizedAccessException) { // If they are running the debugger we might not be able to delete the file // Save the pdb elsewhere in this case. pdbFile = module.Location + ".pdb"; } if (celeriacArgs.SaveProgram != null) { resultStream = new FileStream(celeriacArgs.SaveProgram, FileMode.Create); } else { resultStream = new MemoryStream(); } #if __MonoCS__ // Reading / Writing DEBUG information on Mono is not supported by CCI PdbWriter pdbWriter = null; #else var pdbWriter = new PdbWriter(pdbFile, pdbReader); #endif // Need to not pass in a local scope provider until such time as we have one // that will use the mutator to remap things (like the type of a scope // constant) from the original assembly to the mutated one. using (pdbWriter) { PeWriter.WritePeToStream(module, host, resultStream, pdbReader, null, pdbWriter); } } if (celeriacArgs.SaveProgram != null) { // We aren't going to run the program, so no need to return anything, // but close the file stream. resultStream.Close(); return(null); } else { return((MemoryStream)resultStream); // success } }