List <DiagnosticMessage> RunILPostProcessors(ScriptAssembly assembly, string outputTempPath)
        {
            Profiler.BeginSample("CompilationPipeline.RunILPostProcessors");
            var assemblyPath = Path.Combine(outputTempPath, assembly.Filename);

            var resultMessages = new List <DiagnosticMessage>();

            if (!File.Exists(assemblyPath))
            {
                resultMessages.Add(new DiagnosticMessage
                {
                    File           = assemblyPath,
                    MessageData    = $"Could not find {assemblyPath} for post processing",
                    DiagnosticType = DiagnosticType.Error,
                });
            }

            bool isILProcessed = false;
            var  ilPostProcessCompiledAssembly = new ILPostProcessCompiledAssembly(assembly, outputTempPath);

            InMemoryAssembly postProcessedInMemoryAssembly = null;

            foreach (var ilPostProcessor in ILPostProcessors)
            {
                Profiler.BeginSample($"{ilPostProcessor.GetType().FullName}.Process({assembly.Filename})");
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                Console.WriteLine($"  - Starting ILPostProcessor '{ilPostProcessor.GetType().FullName}' on {assembly.Filename}");
                var ilPostProcessorInstance = ilPostProcessor.GetInstance();
                var ilPostProcessResult     = ilPostProcessorInstance.Process(ilPostProcessCompiledAssembly);
                stopwatch.Stop();
                Profiler.EndSample();

                var elapsed = stopwatch.Elapsed;

                Console.WriteLine($"  - Finished ILPostProcessor '{ilPostProcessor.GetType().FullName}' on {assembly.Filename} in {elapsed.TotalSeconds:0.######} seconds");
                postProcessedInMemoryAssembly = ilPostProcessResult?.InMemoryAssembly;

                if (ilPostProcessResult?.InMemoryAssembly != null)
                {
                    isILProcessed = true;
                    ilPostProcessCompiledAssembly.InMemoryAssembly = postProcessedInMemoryAssembly;
                }

                if (ilPostProcessResult?.Diagnostics != null)
                {
                    resultMessages.AddRange(ilPostProcessResult.Diagnostics);
                }
            }

            if (isILProcessed)
            {
                ilPostProcessCompiledAssembly.WriteAssembly();
            }

            Profiler.EndSample();

            return(resultMessages);
        }
        public CompiledAssemblyFromFile(string assemblyPath)
        {
            this.assemblyPath = assemblyPath;
            byte[] peData      = File.ReadAllBytes(assemblyPath);
            string pdbFileName = Path.GetFileNameWithoutExtension(assemblyPath) + ".pdb";

            byte[] pdbData = File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(assemblyPath), pdbFileName));
            InMemoryAssembly = new InMemoryAssembly(peData, pdbData);
        }
        public ILPostProcessResult PostProcessInternal(ICompiledAssembly compiledAssembly)
        {
            AssemblyDefinition assemblyDefinition;

#if MEDICINE_IL_DEBUG
            using (NonAlloc.Benchmark.Start($"GetAssemblyDefinition ({compiledAssembly.Name})"))
#endif
            assemblyDefinition = PostProcessorAssemblyResolver.GetAssemblyDefinitionFor(compiledAssembly);

            try
            {
                CecilExtensions.CurrentModule = assemblyDefinition.MainModule;
                PostProcessorContext context;
#if MEDICINE_IL_DEBUG
                using (NonAlloc.Benchmark.Start($"CreatePostProcessorContext ({compiledAssembly.Name})"))
#endif
                context = new PostProcessorContext(assemblyDefinition.MainModule);

#if MEDICINE_IL_DEBUG
                using (NonAlloc.Benchmark.Start($"MedicineInjection ({compiledAssembly.Name})"))
#endif
                new InjectionPostProcessor(context).ProcessAssembly();

                var pe  = new MemoryStream(capacity: 1024 * 64);
                var pdb = new MemoryStream(capacity: 1024 * 16);

                var writerParameters = new WriterParameters
                {
                    SymbolWriterProvider = new PortablePdbWriterProvider(),
                    SymbolStream         = pdb,
                    WriteSymbols         = true,
                };

                assemblyDefinition.Write(pe, writerParameters);
                var inMemoryAssembly = new InMemoryAssembly(pe.ToArray(), pdb.ToArray());

                return(new ILPostProcessResult(inMemoryAssembly, context.DiagnosticMessages));
            }
            catch (Exception ex)
            {
                var error = new DiagnosticMessage
                {
                    MessageData    = $"Unexpected exception while post-processing assembly {compiledAssembly.Name}:\n{ex}",
                    DiagnosticType = DiagnosticType.Error,
                };
                return(new ILPostProcessResult(compiledAssembly.InMemoryAssembly, new List <DiagnosticMessage> {
                    error
                }));
            }
            finally
            {
                CecilExtensions.CurrentModule.Dispose();
                CecilExtensions.CurrentModule = null;
            }
        }
Exemple #4
0
    private InMemoryAssembly CreateOrGetInMemoryAssembly()
    {
        if (m_InMemoryAssembly != null)
        {
            return(m_InMemoryAssembly);
        }

        byte[] peData = File.ReadAllBytes(Path.Combine(m_OutputPath, m_AssemblyFilename));

        var pdbFileName = Path.GetFileNameWithoutExtension(m_AssemblyFilename) + ".pdb";

        byte[] pdbData = File.ReadAllBytes(Path.Combine(m_OutputPath, pdbFileName));

        m_InMemoryAssembly = new InMemoryAssembly(peData, pdbData);
        return(m_InMemoryAssembly);
    }
Exemple #5
0
        public CompiledAssembly(string asmPath, string[] referencePaths, string[] defines)
        {
            var peData = File.ReadAllBytes(asmPath);

            byte[] pdbData = null;
            var    pdbPath = Path.ChangeExtension(asmPath, "pdb");

            if (File.Exists(pdbPath))
            {
                pdbData = File.ReadAllBytes(pdbPath);
            }

            Name             = Path.GetFileNameWithoutExtension(asmPath);
            References       = referencePaths;
            InMemoryAssembly = new InMemoryAssembly(peData, pdbData);
            Defines          = defines;
        }
Exemple #6
0
 public void AddAssembly(InMemoryAssembly assembly)
 {
     Assembly.Load(assembly.Data, null, SecurityContextSource.CurrentAppDomain);
 }
        public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
        {
            //Log.Warning($"Processing {compiledAssembly.Name}");

            // load the InMemoryAssembly peData into a MemoryStream
            byte[] peData = compiledAssembly.InMemoryAssembly.PeData;
            //LogDiagnostics($"  peData.Length={peData.Length} bytes");
            using (MemoryStream stream = new MemoryStream(peData))
                using (ILPostProcessorAssemblyResolver asmResolver = new ILPostProcessorAssemblyResolver(compiledAssembly, Log))
                {
                    // we need to load symbols. otherwise we get:
                    // "(0,0): error Mono.CecilX.Cil.SymbolsNotFoundException: No symbol found for file: "
                    using (MemoryStream symbols = new MemoryStream(compiledAssembly.InMemoryAssembly.PdbData))
                    {
                        ReaderParameters readerParameters = new ReaderParameters {
                            SymbolStream     = symbols,
                            ReadWrite        = true,
                            ReadSymbols      = true,
                            AssemblyResolver = asmResolver,
                            // custom reflection importer to fix System.Private.CoreLib
                            // not being found in custom assembly resolver above.
                            ReflectionImporterProvider = new ILPostProcessorReflectionImporterProvider()
                        };
                        using (AssemblyDefinition asmDef = AssemblyDefinition.ReadAssembly(stream, readerParameters))
                        {
                            // resolving a Mirror.dll type like NetworkServer while
                            // weaving Mirror.dll does not work. it throws a
                            // NullReferenceException in WeaverTypes.ctor
                            // when Resolve() is called on the first Mirror type.
                            // need to add the AssemblyDefinition itself to use.
                            asmResolver.SetAssemblyDefinitionForCompiledAssembly(asmDef);

                            // weave this assembly.
                            Weaver weaver = new Weaver(Log);
                            if (weaver.Weave(asmDef, asmResolver, out bool modified))
                            {
                                //Log.Warning($"Weaving succeeded for: {compiledAssembly.Name}");

                                // write if modified
                                if (modified)
                                {
                                    // when weaving Mirror.dll with ILPostProcessor,
                                    // Weave() -> WeaverTypes -> resolving the first
                                    // type in Mirror.dll adds a reference to
                                    // Mirror.dll even though we are in Mirror.dll.
                                    // -> this would throw an exception:
                                    //    "Mirror references itself" and not compile
                                    // -> need to detect and fix manually here
                                    if (asmDef.MainModule.AssemblyReferences.Any(r => r.Name == asmDef.Name.Name))
                                    {
                                        asmDef.MainModule.AssemblyReferences.Remove(asmDef.MainModule.AssemblyReferences.First(r => r.Name == asmDef.Name.Name));
                                        //Log.Warning($"fixed self referencing Assembly: {asmDef.Name.Name}");
                                    }

                                    MemoryStream     peOut            = new MemoryStream();
                                    MemoryStream     pdbOut           = new MemoryStream();
                                    WriterParameters writerParameters = new WriterParameters
                                    {
                                        SymbolWriterProvider = new PortablePdbWriterProvider(),
                                        SymbolStream         = pdbOut,
                                        WriteSymbols         = true
                                    };

                                    asmDef.Write(peOut, writerParameters);

                                    InMemoryAssembly inMemory = new InMemoryAssembly(peOut.ToArray(), pdbOut.ToArray());
                                    return(new ILPostProcessResult(inMemory, Log.Logs));
                                }
                            }
                            // if anything during Weave() fails, we log an error.
                            // don't need to indicate 'weaving failed' again.
                            // in fact, this would break tests only expecting certain errors.
                            //else Log.Error($"Weaving failed for: {compiledAssembly.Name}");
                        }
                    }
                }

            // always return an ILPostProcessResult with Logs.
            // otherwise we won't see Logs if weaving failed.
            return(new ILPostProcessResult(compiledAssembly.InMemoryAssembly, Log.Logs));
        }
Exemple #8
0
        internal void Save(string fileName, bool throwOnError)
        {
            //It is very tempting to use XmlSerializer but it adds 200 ms to the
            //application startup time. Whereas current startup delay for cscs.exe is just a 100 ms.
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml("<CSSConfig/>");

                //write the all most important elements and less important ones only if they have non-default values.
                doc.DocumentElement.AppendChild(doc.CreateElement("defaultArguments")).AppendChild(doc.CreateTextNode(DefaultArguments));
                doc.DocumentElement.AppendChild(doc.CreateElement("defaultRefAssemblies")).AppendChild(doc.CreateTextNode(DefaultRefAssemblies));
                doc.DocumentElement.AppendChild(doc.CreateElement("searchDirs")).AppendChild(doc.CreateTextNode(SearchDirs));
                doc.DocumentElement.AppendChild(doc.CreateElement("useAlternativeCompiler")).AppendChild(doc.CreateTextNode(UseAlternativeCompiler));
                doc.DocumentElement.AppendChild(doc.CreateElement("roslynDir")).AppendChild(doc.CreateTextNode(RoslynDir));
                doc.DocumentElement.AppendChild(doc.CreateElement("consoleEncoding")).AppendChild(doc.CreateTextNode(ConsoleEncoding));
                doc.DocumentElement.AppendChild(doc.CreateElement("autoclass.decorateAsCS6")).AppendChild(doc.CreateTextNode(autoClass_DecorateAsCS6.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("inMemoryAsm")).AppendChild(doc.CreateTextNode(InMemoryAssembly.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("hideCompilerWarnings")).AppendChild(doc.CreateTextNode(HideCompilerWarnings.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("reportDetailedErrorInfo")).AppendChild(doc.CreateTextNode(ReportDetailedErrorInfo.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("enableDbgPrint")).AppendChild(doc.CreateTextNode(enableDbgPrint.ToString()));

                if (hideOptions != HideOptions.HideAll)
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("hideOptions")).AppendChild(doc.CreateTextNode(hideOptions.ToString()));
                }

                if (autoClass_DecorateAlways)
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("autoclass.decorateAlways")).AppendChild(doc.CreateTextNode(autoClass_DecorateAlways.ToString()));
                }

                if (DefaultApartmentState != ApartmentState.STA)
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("defaultApartmentState")).AppendChild(doc.CreateTextNode(DefaultApartmentState.ToString()));
                }

                if (!string.IsNullOrEmpty(precompiler))
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("precompiler")).AppendChild(doc.CreateTextNode(Precompiler));
                }

                if (!string.IsNullOrEmpty(UsePostProcessor))
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("usePostProcessor")).AppendChild(doc.CreateTextNode(UsePostProcessor));
                }

                if (!string.IsNullOrEmpty(CleanupShellCommand))
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("cleanupShellCommand")).AppendChild(doc.CreateTextNode(CleanupShellCommand));
                    doc.DocumentElement.AppendChild(doc.CreateElement("doCleanupAfterNumberOfRuns")).AppendChild(doc.CreateTextNode(DoCleanupAfterNumberOfRuns.ToString()));
                }

                if (ConcurrencyControl != ConcurrencyControl.Standard)
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("concurrencyControl")).AppendChild(doc.CreateTextNode(ConcurrencyControl.ToString()));
                }
#if net35
                if (TargetFramework != "v3.5")
#else
                if (TargetFramework != "v4.0")
#endif
                { doc.DocumentElement.AppendChild(doc.CreateElement("targetFramework")).AppendChild(doc.CreateTextNode(TargetFramework)); }

                if (useSurrogatepHostingProcess)
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("useSurrogatepHostingProcess")).AppendChild(doc.CreateTextNode(useSurrogatepHostingProcess.ToString()));
                }

                if (!openEndDirectiveSyntax)
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("openEndDirectiveSyntax")).AppendChild(doc.CreateTextNode(openEndDirectiveSyntax.ToString()));
                }

                if (!CustomHashing)
                {
                    doc.DocumentElement.AppendChild(doc.CreateElement("customHashing")).AppendChild(doc.CreateTextNode(CustomHashing.ToString()));
                }

                //note node.ParentNode.InsertAfter(doc.CreateComment("") injects int node inner text and it is not what we want
                //very simplistic formatting
                var xml = doc.InnerXml.Replace("><", ">\n  <")
                          .Replace(">\n  </", "></")
                          .Replace("></CSSConfig>", ">\n</CSSConfig>");

                xml = CommentElement(xml, "consoleEncoding", "if 'default' then system default is used; otherwise specify the name of the encoding (e.g. 'utf-8')");
                xml = CommentElement(xml, "autoclass.decorateAsCS6", "if 'true' auto-class decoration will inject C# 6 specific syntax expressions (e.g. 'using static dbg;')");
                xml = CommentElement(xml, "autoclass.decorateAlways", "if 'true' decorate classless scripts unconditionally; otherwise only if a top level class-less 'main' detected. Not used yet.");
                xml = CommentElement(xml, "useAlternativeCompiler", "Custom script compiler. For example C# 7 (Roslyn): '%CSSCRIPT_DIR%!lib!CSSRoslynProvider.dll'".Replace('!', Path.DirectorySeparatorChar));
                xml = CommentElement(xml, "roslynDir", "Location of Roslyn compilers to be used by custom script compilers. For example C# 7 (Roslyn): /usr/lib/mono/4.5");
                xml = CommentElement(xml, "enableDbgPrint", "Gets or sets a value indicating whether to enable Python-like print methods (e.g. dbg.print(DateTime.Now))");

                File.WriteAllText(fileName, xml);
            }
            catch
            {
                if (throwOnError)
                {
                    throw;
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Saves CS-Script application settings to a file (.dat).
        /// </summary>
        /// <param name="fileName">File name of the .dat file</param>
        public void Save(string fileName)
        {
            //It is very tempting to use XmlSerializer but it adds 200 ms to the
            //application startup time. Whereas current startup delay for cscs.exe is just a 100 ms.
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml("<CSSConfig/>");
                doc.DocumentElement.AppendChild(doc.CreateElement("defaultArguments")).AppendChild(doc.CreateTextNode(DefaultArguments));
                doc.DocumentElement.AppendChild(doc.CreateElement("defaultApartmentState")).AppendChild(doc.CreateTextNode(DefaultApartmentState.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("reportDetailedErrorInfo")).AppendChild(doc.CreateTextNode(ReportDetailedErrorInfo.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("useAlternativeCompiler")).AppendChild(doc.CreateTextNode(UseAlternativeCompiler));
                doc.DocumentElement.AppendChild(doc.CreateElement("usePostProcessor")).AppendChild(doc.CreateTextNode(UsePostProcessor));
                doc.DocumentElement.AppendChild(doc.CreateElement("searchDirs")).AppendChild(doc.CreateTextNode(SearchDirs));
                doc.DocumentElement.AppendChild(doc.CreateElement("cleanupShellCommand")).AppendChild(doc.CreateTextNode(CleanupShellCommand));
                doc.DocumentElement.AppendChild(doc.CreateElement("doCleanupAfterNumberOfRuns")).AppendChild(doc.CreateTextNode(DoCleanupAfterNumberOfRuns.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("hideOptions")).AppendChild(doc.CreateTextNode(hideOptions.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("hideCompilerWarnings")).AppendChild(doc.CreateTextNode(HideCompilerWarnings.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("inMemoryAsm")).AppendChild(doc.CreateTextNode(InMemoryAssembly.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("ConcurrencyControl")).AppendChild(doc.CreateTextNode(ConcurrencyControl.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("TragetFramework")).AppendChild(doc.CreateTextNode(TargetFramework));
                doc.DocumentElement.AppendChild(doc.CreateElement("ConsoleEncoding")).AppendChild(doc.CreateTextNode(ConsoleEncoding));
                doc.DocumentElement.AppendChild(doc.CreateElement("defaultRefAssemblies")).AppendChild(doc.CreateTextNode(DefaultRefAssemblies));
                doc.DocumentElement.AppendChild(doc.CreateElement("useSurrogatepHostingProcess")).AppendChild(doc.CreateTextNode(useSurrogatepHostingProcess.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("openEndDirectiveSyntax")).AppendChild(doc.CreateTextNode(openEndDirectiveSyntax.ToString()));
                doc.DocumentElement.AppendChild(doc.CreateElement("Precompiler")).AppendChild(doc.CreateTextNode(Precompiler));
                doc.DocumentElement.AppendChild(doc.CreateElement("CustomHashing")).AppendChild(doc.CreateTextNode(CustomHashing.ToString()));

                doc.Save(fileName);
            }
            catch { }
        }