//
    // Kompilierung durch mcs-Compiler
    //
    public AssemblyBuilder Compile(AppDomain domain, bool generateInMemory)
    {
        Debug.Log("Aufruf Compiler");

        //settings.SourceFiles des CompilerContextes hält alle dll's und das noch zu kompilierende Script
        CompilerSettings settings = compilerContext.Settings;
        AssemblyBuilder  assembly = null;
        ModuleContainer  module   = new ModuleContainer(compilerContext);

        Parse(module);

        //benötigte Klassen die in der Compile-Methode des mcs Compiler enthalten sind
        AssemblyDefinitionDynamic assemblyDef = new AssemblyDefinitionDynamic(module, settings.OutputFile, settings.OutputFile);

        module.SetDeclaringAssembly(assemblyDef);

        ReflectionImporter importer = new ReflectionImporter(module, compilerContext.BuiltinTypes);

        assemblyDef.Importer = importer;

        DynamicLoader loader = new DynamicLoader(importer, compilerContext);

        loader.LoadReferences(module);

        compilerContext.BuiltinTypes.CheckDefinitions(module);
        assemblyDef.Create(domain, AssemblyBuilderAccess.RunAndSave);

        module.CreateContainer();
        loader.LoadModules(assemblyDef, module.GlobalRootNamespace);
        module.InitializePredefinedTypes();

        module.Define();
        assemblyDef.Resolve();
        assemblyDef.Emit();
        module.CloseContainer();

        return(assemblyDef.Builder);
    }
Ejemplo n.º 2
0
        // Mimicked from https://github.com/kkdevs/Patchwork/blob/master/Patchwork/MonoScript.cs#L124
        public static Assembly Compile(Dictionary <string, byte[]> sources, TextWriter logger = null)
        {
            ReportPrinter reporter = logger == null ? new ConsoleReportPrinter() : new StreamReportPrinter(logger);

            Location.Reset();

            var dllName = $"compiled_{DateTime.Now.Ticks}";

            compiledAssemblies.Add(dllName);

            var ctx = CreateContext(reporter);

            ctx.Settings.SourceFiles.Clear();

            var i = 0;

            SeekableStreamReader GetFile(SourceFile file)
            {
                return(new SeekableStreamReader(new MemoryStream(sources[file.OriginalFullPathName]), Encoding.UTF8));
            }

            foreach (var source in sources)
            {
                ctx.Settings.SourceFiles.Add(new SourceFile(Path.GetFileName(source.Key), source.Key, i, GetFile));
                i++;
            }

            var container = new ModuleContainer(ctx);

            RootContext.ToplevelTypes = container;
            Location.Initialize(ctx.Settings.SourceFiles);

            var session = new ParserSession {
                UseJayGlobalArrays = true, LocatedTokens = new LocatedToken[15000]
            };

            container.EnableRedefinition();

            foreach (var sourceFile in ctx.Settings.SourceFiles)
            {
                var stream = sourceFile.GetInputStream(sourceFile);
                var source = new CompilationSourceFile(container, sourceFile);
                source.EnableRedefinition();
                container.AddTypeContainer(source);
                var parser = new CSharpParser(stream, source, session);
                parser.parse();
            }

            var ass = new AssemblyDefinitionDynamic(container, dllName, $"{dllName}.dll");

            container.SetDeclaringAssembly(ass);

            var importer = new ReflectionImporter(container, ctx.BuiltinTypes);

            ass.Importer = importer;

            var loader = new DynamicLoader(importer, ctx);

            ImportAppdomainAssemblies(a => importer.ImportAssembly(a, container.GlobalRootNamespace));

            loader.LoadReferences(container);
            ass.Create(AppDomain.CurrentDomain, AssemblyBuilderAccess.RunAndSave);
            container.CreateContainer();
            loader.LoadModules(ass, container.GlobalRootNamespace);
            container.InitializePredefinedTypes();
            container.Define();

            if (ctx.Report.Errors > 0)
            {
                logger?.WriteLine("Found errors! Aborting compilation...");
                return(null);
            }

            try
            {
                ass.Resolve();
                ass.Emit();
                container.CloseContainer();
                ass.EmbedResources();
            }
            catch (Exception e)
            {
                logger?.WriteLine($"Failed to compile because {e}");
                return(null);
            }

            return(ass.Builder);
        }
Ejemplo n.º 3
0
        //
        // Main compilation method
        //
        public bool Compile(out AssemblyBuilder outAssembly, AppDomain domain, bool generateInMemory)
        {
            var settings = ctx.Settings;

            outAssembly = null;
            //
            // If we are an exe, require a source file for the entry point or
            // if there is nothing to put in the assembly, and we are not a library
            //
            if (settings.FirstSourceFile == null &&
                ((settings.Target == Target.Exe || settings.Target == Target.WinExe || settings.Target == Target.Module) ||
                 settings.Resources == null))
            {
                Report.Error(2008, "No files to compile were specified");
                return(false);
            }

            if (settings.Platform == Platform.AnyCPU32Preferred && (settings.Target == Target.Library || settings.Target == Target.Module))
            {
                Report.Error(4023, "Platform option `anycpu32bitpreferred' is valid only for executables");
                return(false);
            }

            TimeReporter tr = new TimeReporter(settings.Timestamps);

            ctx.TimeReporter = tr;
            tr.StartTotal();

            var module = new ModuleContainer(ctx);

            RootContext.ToplevelTypes = module;

            tr.Start(TimeReporter.TimerType.ParseTotal);
            Parse(module);
            tr.Stop(TimeReporter.TimerType.ParseTotal);

            if (Report.Errors > 0)
            {
                return(false);
            }

            if (settings.TokenizeOnly || settings.ParseOnly)
            {
                tr.StopTotal();
                tr.ShowStats();
                return(true);
            }

            var    output_file = settings.OutputFile;
            string output_file_name;

            /* if (output_file == null)
             * {
             *   var source_file = settings.FirstSourceFile;
             *
             *   if (source_file == null)
             *   {
             *       Report.Error(1562, "If no source files are specified you must specify the output file with -out:");
             *       return false;
             *   }
             *
             *   output_file_name = source_file.Name;
             *   int pos = output_file_name.LastIndexOf('.');
             *
             *   if (pos > 0)
             *       output_file_name = output_file_name.Substring(0, pos);
             *
             *   output_file_name += settings.TargetExt;
             *   output_file = output_file_name;
             * }
             * else
             * {*/
            output_file_name = Path.GetFileName(output_file);

            /*  if (string.IsNullOrEmpty(Path.GetFileNameWithoutExtension(output_file_name)) ||
             *    output_file_name.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
             * {
             *    Report.Error(2021, "Output file name is not valid");
             *    return false;
             * }
             * }*/


            var assembly = new AssemblyDefinitionDynamic(module, output_file_name, output_file);

            module.SetDeclaringAssembly(assembly);

            var importer = new ReflectionImporter(module, ctx.BuiltinTypes);

            assembly.Importer = importer;

            var loader = new DynamicLoader(importer, ctx);

            loader.LoadReferences(module);

            if (!ctx.BuiltinTypes.CheckDefinitions(module))
            {
                return(false);
            }

            if (!assembly.Create(domain, AssemblyBuilderAccess.RunAndSave))
            {
                return(false);
            }

            module.CreateContainer();

            loader.LoadModules(assembly, module.GlobalRootNamespace);

            module.InitializePredefinedTypes();

            if (settings.GetResourceStrings != null)
            {
                module.LoadGetResourceStrings(settings.GetResourceStrings);
            }

            tr.Start(TimeReporter.TimerType.ModuleDefinitionTotal);
            module.Define();
            tr.Stop(TimeReporter.TimerType.ModuleDefinitionTotal);

            if (Report.Errors > 0)
            {
                return(false);
            }

            if (settings.DocumentationFile != null)
            {
                var doc = new DocumentationBuilder(module);
                doc.OutputDocComment(output_file, settings.DocumentationFile);
            }

            assembly.Resolve();

            if (Report.Errors > 0)
            {
                return(false);
            }


            tr.Start(TimeReporter.TimerType.EmitTotal);
            assembly.Emit();
            tr.Stop(TimeReporter.TimerType.EmitTotal);

            if (Report.Errors > 0)
            {
                return(false);
            }

            tr.Start(TimeReporter.TimerType.CloseTypes);
            module.CloseContainer();
            tr.Stop(TimeReporter.TimerType.CloseTypes);

            tr.Start(TimeReporter.TimerType.Resouces);
            if (!settings.WriteMetadataOnly)
            {
                assembly.EmbedResources();
            }
            tr.Stop(TimeReporter.TimerType.Resouces);

            if (Report.Errors > 0)
            {
                return(false);
            }


            if (!generateInMemory)
            {
                assembly.Save();
            }
            outAssembly = assembly.Builder;


            tr.StopTotal();
            tr.ShowStats();

            return(Report.Errors == 0);
        }
Ejemplo n.º 4
0
		//
		// Main compilation method
		//
		public bool Compile ()
		{
			var settings = ctx.Settings;

			//
			// If we are an exe, require a source file for the entry point or
			// if there is nothing to put in the assembly, and we are not a library
			//
			if (settings.FirstSourceFile == null &&
				((settings.Target == Target.Exe || settings.Target == Target.WinExe || settings.Target == Target.Module) ||
				settings.Resources == null)) {
				Report.Error (2008, "No files to compile were specified");
				return false;
			}

			if (settings.Platform == Platform.AnyCPU32Preferred && (settings.Target == Target.Library || settings.Target == Target.Module)) {
				Report.Error (4023, "Platform option `anycpu32bitpreferred' is valid only for executables");
				return false;
			}

			TimeReporter tr = new TimeReporter (settings.Timestamps);
			ctx.TimeReporter = tr;
			tr.StartTotal ();

			var module = new ModuleContainer (ctx);
			RootContext.ToplevelTypes = module;

			tr.Start (TimeReporter.TimerType.ParseTotal);
			Parse (module);
			tr.Stop (TimeReporter.TimerType.ParseTotal);

			if (Report.Errors > 0)
				return false;

			if (settings.TokenizeOnly || settings.ParseOnly) {
				tr.StopTotal ();
				tr.ShowStats ();
				return true;
			}

			var output_file = settings.OutputFile;
			string output_file_name;
			if (output_file == null) {
				var source_file = settings.FirstSourceFile;

				if (source_file == null) {
					Report.Error (1562, "If no source files are specified you must specify the output file with -out:");
					return false;
				}

				output_file_name = source_file.Name;
				int pos = output_file_name.LastIndexOf ('.');

				if (pos > 0)
					output_file_name = output_file_name.Substring (0, pos);
				
				output_file_name += settings.TargetExt;
				output_file = output_file_name;
			} else {
				output_file_name = Path.GetFileName (output_file);

				if (string.IsNullOrEmpty (Path.GetFileNameWithoutExtension (output_file_name)) ||
					output_file_name.IndexOfAny (Path.GetInvalidFileNameChars ()) >= 0) {
					Report.Error (2021, "Output file name is not valid");
					return false;
				}
			}

#if STATIC
			var importer = new StaticImporter (module);
			var references_loader = new StaticLoader (importer, ctx);

			tr.Start (TimeReporter.TimerType.AssemblyBuilderSetup);
			var assembly = new AssemblyDefinitionStatic (module, references_loader, output_file_name, output_file);
			assembly.Create (references_loader.Domain);
			tr.Stop (TimeReporter.TimerType.AssemblyBuilderSetup);

			// Create compiler types first even before any referenced
			// assembly is loaded to allow forward referenced types from
			// loaded assembly into compiled builder to be resolved
			// correctly
			tr.Start (TimeReporter.TimerType.CreateTypeTotal);
			module.CreateContainer ();
			importer.AddCompiledAssembly (assembly);
			references_loader.CompiledAssembly = assembly;
			tr.Stop (TimeReporter.TimerType.CreateTypeTotal);

			references_loader.LoadReferences (module);

			tr.Start (TimeReporter.TimerType.PredefinedTypesInit);
			if (!ctx.BuiltinTypes.CheckDefinitions (module))
				return false;

			tr.Stop (TimeReporter.TimerType.PredefinedTypesInit);

			references_loader.LoadModules (assembly, module.GlobalRootNamespace);
#else
			var assembly = new AssemblyDefinitionDynamic (module, output_file_name, output_file);
			module.SetDeclaringAssembly (assembly);

			var importer = new ReflectionImporter (module, ctx.BuiltinTypes);
			assembly.Importer = importer;

			var loader = new DynamicLoader (importer, ctx);
			loader.LoadReferences (module);

			if (!ctx.BuiltinTypes.CheckDefinitions (module))
				return false;

			if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save))
				return false;

			module.CreateContainer ();

			loader.LoadModules (assembly, module.GlobalRootNamespace);
#endif
			module.InitializePredefinedTypes ();

			tr.Start (TimeReporter.TimerType.ModuleDefinitionTotal);
			module.Define ();
			tr.Stop (TimeReporter.TimerType.ModuleDefinitionTotal);

			if (Report.Errors > 0)
				return false;

			if (settings.DocumentationFile != null) {
				var doc = new DocumentationBuilder (module);
				doc.OutputDocComment (output_file, settings.DocumentationFile);
			}

			assembly.Resolve ();
			
			if (Report.Errors > 0)
				return false;


			tr.Start (TimeReporter.TimerType.EmitTotal);
			assembly.Emit ();
			tr.Stop (TimeReporter.TimerType.EmitTotal);

			if (Report.Errors > 0){
				return false;
			}

			tr.Start (TimeReporter.TimerType.CloseTypes);
			module.CloseContainer ();
			tr.Stop (TimeReporter.TimerType.CloseTypes);

			tr.Start (TimeReporter.TimerType.Resouces);
			if (!settings.WriteMetadataOnly)
				assembly.EmbedResources ();
			tr.Stop (TimeReporter.TimerType.Resouces);

			if (Report.Errors > 0)
				return false;

			assembly.Save ();

#if STATIC
			references_loader.Dispose ();
#endif
			tr.StopTotal ();
			tr.ShowStats ();

			return Report.Errors == 0;
		}
Ejemplo n.º 5
0
    public Assembly DoStaticCompile(IEnumerable <object> sources, string prefix = "compiled_")
    {
        reporter.Reset();
        Location.Reset();
        var ctx = BuildContext(reporter);

        ctx.Settings.SourceFiles.Clear();
        int             i        = 0;
        var             allBytes = new MemoryStream();
        List <Assembly> imports  = new List <Assembly>();

        foreach (var fo in sources)
        {
            Assembly impass = fo as Assembly;
            if (impass != null)
            {
                imports.Add(impass);
                continue;
            }
            var    f    = fo as string;
            byte[] fbuf = fo as byte[];
            if (f != null)
            {
                if (!f.EndsWith(".cs"))
                {
                    continue;
                }
                var bname = (f + "\n").ToBytes();
                allBytes.Write(bname, 0, bname.Length);
                fbuf = File.ReadAllBytes(f);
                allBytes.Write(fbuf, 0, fbuf.Length);
            }
            else
            {
                allBytes.Write(fbuf, 0, fbuf.Length);
                f = null;
            }
            i++;
            ctx.Settings.SourceFiles.Add(new SourceFile(f == null ? "<eval>" : Path.GetFileName(f), f ?? "<eval>", i, (o) =>
            {
                return(new SeekableStreamReader(new MemoryStream(fbuf), Encoding.UTF8));
            }));
        }
        string dllname = prefix + (counter++) + ".dll";

        if (tempdir != null)
        {
            if (hashkey != null)
            {
                var hb = hashkey.ToBytes();
                allBytes.Write(hb, 0, hb.Length);
            }

            var hash = prefix + Ext.HashToString(allBytes.ToArray()).Substring(0, 12).ToLower() + ".dll";
            if (hashkey == null)
            {
                hashkey = hash;
            }

            dllname = Path.Combine(tempdir, hash);
            if (File.Exists(dllname))
            {
                var nam = AssemblyName.GetAssemblyName(dllname);
                unloaded.Remove(nam.Name.ToLower());
                return(Assembly.Load(nam));
            }
        }

        var mod = new ModuleContainer(ctx);

        RootContext.ToplevelTypes = mod;
        Location.Initialize(ctx.Settings.SourceFiles);
        var session = new ParserSession()
        {
            UseJayGlobalArrays = true,
            LocatedTokens      = new LocatedToken[15000]
        };

        mod.EnableRedefinition();
        foreach (var finfo in ctx.Settings.SourceFiles)
        {
            var fs   = finfo.GetInputStream(finfo);
            var csrc = new CompilationSourceFile(mod, finfo);
            csrc.EnableRedefinition();
            mod.AddTypeContainer(csrc);
            var parser = new CSharpParser(fs, csrc, session);
            parser.parse();
        }
        Debug.Log("Defining new assembly " + dllname);
        var ass = new AssemblyDefinitionDynamic(mod, Path.GetFileNameWithoutExtension(dllname), dllname);

        mod.SetDeclaringAssembly(ass);
        var importer = new ReflectionImporter(mod, ctx.BuiltinTypes);

        ass.Importer = importer;
        var loader = new DynamicLoader(importer, ctx);

        ImportAssemblies((a) => importer.ImportAssembly(a, mod.GlobalRootNamespace), prefix);
        foreach (var impa in imports)
        {
            importer.ImportAssembly(impa, mod.GlobalRootNamespace);
        }
        loader.LoadReferences(mod);
        ass.Create(AppDomain.CurrentDomain, AssemblyBuilderAccess.RunAndSave);
        mod.CreateContainer();
        loader.LoadModules(ass, mod.GlobalRootNamespace);
        mod.InitializePredefinedTypes();
        mod.Define();
        if (ctx.Report.Errors > 0)
        {
            tw.WriteLine($"{ctx.Report.Errors} errors, aborting.");
            return(null);
        }
        try
        {
            ass.Resolve();
            ass.Emit();
            mod.CloseContainer();
            ass.EmbedResources();
        }
        catch (Exception ex)
        {
            tw.WriteLine($"Link error: " + ex.ToString());
            return(null);
        }
        if (tempdir != null)
        {
            ass.Save();
        }
        return(ass.Builder);
    }
Ejemplo n.º 6
0
        public bool Compile(out AssemblyBuilder assembly, AppDomain domain, bool generateInMemory)
        {
            // Get the current settings
            CompilerSettings settings = context.Settings;

            // Set the result for quick exit
            assembly = null;

            // Check if any source files were supplied
            if (settings.FirstSourceFile == null && (((MCSTarget)settings.Target == MCSTarget.Exe || (MCSTarget)settings.Target == MCSTarget.WinExe || (MCSTarget)settings.Target == MCSTarget.Module) || settings.Resources == null))
            {
                Report.Error(2008, "No source files specified");
                return(false);
            }

            // Check for any invalid settings
            if (settings.Platform == Platform.AnyCPU32Preferred && ((MCSTarget)settings.Target == MCSTarget.Library || (MCSTarget)settings.Target == MCSTarget.Module))
            {
                Report.Error(4023, "The preferred platform '{0}' is only valid on executable outputs", Platform.AnyCPU32Preferred.ToString());
                return(false);
            }

            // Create the time reporter
            TimeReporter time = new TimeReporter(settings.Timestamps);

            context.TimeReporter = time;
            time.StartTotal();

            // Create the module
            ModuleContainer module = new ModuleContainer(context);

            RootContext.ToplevelTypes = module;

            // Start timing the parse stage
            time.Start(TimeReporter.TimerType.ParseTotal);
            {
                // Begin parse
                Parse(module);
            }
            time.Stop(TimeReporter.TimerType.ParseTotal);

            // Check for any errors
            if (Report.Errors > 0)
            {
                return(false);
            }

            // Check for partial compilation
            if (settings.TokenizeOnly == true || settings.ParseOnly == true)
            {
                time.StopTotal();
                time.ShowStats();
                return(true);
            }

            // Get the output file
            string output     = settings.OutputFile;
            string outputName = Path.GetFileName(output);

            // Create an assembly defenition
            AssemblyDefinitionDynamic defenition = new AssemblyDefinitionDynamic(module, outputName, output);

            module.SetDeclaringAssembly(defenition);

            ReflectionImporter importer = new ReflectionImporter(module, context.BuiltinTypes);

            defenition.Importer = importer;

            DynamicLoader loader = new DynamicLoader(importer, context);

            loader.LoadReferences(module);

            // Validate built in types
            if (context.BuiltinTypes.CheckDefinitions(module) == false)
            {
                return(false);
            }

            // Create the assmbly in domain
            if (defenition.Create(domain, AssemblyBuilderAccess.RunAndSave) == false)
            {
                return(false);
            }

            module.CreateContainer();
            loader.LoadModules(defenition, module.GlobalRootNamespace);
            module.InitializePredefinedTypes();

            // Check for any resource strings
            if (settings.GetResourceStrings != null)
            {
                module.LoadGetResourceStrings(settings.GetResourceStrings);
            }

            // Time the module defenition
            time.Start(TimeReporter.TimerType.ModuleDefinitionTotal);
            {
                try
                {
                    // Begin defining
                    module.Define();
                }
                catch
                {
                    // Failed to define module
                    return(false);
                }
            }
            time.Stop(TimeReporter.TimerType.ModuleDefinitionTotal);

            // Check for any errors
            if (Report.Errors > 0)
            {
                return(false);
            }

            // Check for documentation
            if (settings.DocumentationFile != null)
            {
                // Build the xml docs file
                DocumentationBuilder docs = new DocumentationBuilder(module);
                docs.OutputDocComment(output, settings.DocumentationFile);
            }

            defenition.Resolve();

            // Check for documentation errors
            if (Report.Errors > 0)
            {
                return(false);
            }

            // Finally emit the defenition into something useful
            time.Start(TimeReporter.TimerType.EmitTotal);
            {
                // Emit assembly
                defenition.Emit();
            }
            time.Stop(TimeReporter.TimerType.EmitTotal);

            // Check for any emit errors
            if (Report.Errors > 0)
            {
                return(false);
            }

            // Module cleanup
            time.Start(TimeReporter.TimerType.CloseTypes);
            {
                module.CloseContainer();
            }
            time.Stop(TimeReporter.TimerType.CloseTypes);

            // Check for embedded resources
            time.Start(TimeReporter.TimerType.Resouces);
            {
                if (settings.WriteMetadataOnly == false)
                {
                    defenition.EmbedResources();
                }
            }
            time.Stop(TimeReporter.TimerType.Resouces);

            // Embedd errors
            if (Report.Errors > 0)
            {
                return(false);
            }

            // Check for generate in memory
            if (generateInMemory == false)
            {
                defenition.Save();
            }

            // Store the result
            assembly = defenition.Builder;

            time.StopTotal();
            time.ShowStats();

            // Check for errors
            return(Report.Errors == 0);
        }