コード例 #1
0
ファイル: AssemblyResolver.cs プロジェクト: zuvys/ironpython3
        private Assembly _universe_AssemblyResolve(object sender, IKVM.Reflection.ResolveEventArgs args)
        {
            AssemblyName name               = new AssemblyName(args.Name);
            AssemblyName previousMatch      = null;
            int          previousMatchLevel = 0;

            foreach (Assembly asm in _universe.GetAssemblies())
            {
                if (Match(asm.GetName(), name, ref previousMatch, ref previousMatchLevel))
                {
                    return(asm);
                }
            }
            foreach (string file in FindAssemblyPath(name.Name + ".dll"))
            {
                if (Match(AssemblyName.GetAssemblyName(file), name, ref previousMatch, ref previousMatchLevel))
                {
                    return(LoadFile(file));
                }
            }
            if (args.RequestingAssembly != null)
            {
                string path = Path.Combine(Path.GetDirectoryName(args.RequestingAssembly.Location), name.Name + ".dll");
                if (File.Exists(path) && Match(AssemblyName.GetAssemblyName(path), name, ref previousMatch, ref previousMatchLevel))
                {
                    return(LoadFile(path));
                }
            }
            string hintpath;

            if (_hintpaths.TryGetValue(name.FullName, out hintpath))
            {
                string path = Path.Combine(hintpath, name.Name + ".dll");
                if (File.Exists(path) && Match(AssemblyName.GetAssemblyName(path), name, ref previousMatch, ref previousMatchLevel))
                {
                    return(LoadFile(path));
                }
            }
            if (previousMatch != null)
            {
                if (previousMatchLevel == 2)
                {
                    ConsoleOps.Warning("assuming assembly reference '{0}' matches '{1}', you may need to supply runtime policy", previousMatch.FullName, name.FullName);
                    return(LoadFile(new Uri(previousMatch.CodeBase).LocalPath));
                }
                else if (args.RequestingAssembly != null)
                {
                    ConsoleOps.Error(true, "Assembly '{0}' uses '{1}' which has a higher version than referenced assembly '{2}'", args.RequestingAssembly.FullName, name.FullName, previousMatch.FullName);
                }
                else
                {
                    ConsoleOps.Error(true, "Assembly '{0}' was requested which is a higher version than referenced assembly '{1}'", name.FullName, previousMatch.FullName);
                }
            }
            else
            {
                ConsoleOps.Error(true, "unable to find assembly '{0}' {1}", args.Name, args.RequestingAssembly != null ? string.Format("    (a dependency of '{0}')", args.RequestingAssembly.FullName) : string.Empty);
            }
            return(null);
        }
コード例 #2
0
        static int Main(string[] args)
        {
            var files  = new List <string>();
            var config = new Config();

            config.ParseArgs(args);
            if (!config.Validate())
            {
                ConsoleOps.Usage(true);
            }
            ConsoleOps.Info("{0}", config);
            ConsoleOps.Info("compiling...");

            // we don't use the engine, but we create it so we can have a default context.
            ScriptEngine engine = Python.CreateEngine();

            ClrModule.CompileModules(DefaultContext.DefaultCLS, config.Output + ".dll", new Dictionary <string, object> {
                { "mainModule", config.MainName }
            }, config.Files.ToArray());

            if (config.Target != PEFileKinds.Dll)
            {
                GenerateExe(config);
            }

            ConsoleOps.Info("Saved to {0}", config.Output);
            return(0);
        }
コード例 #3
0
ファイル: AssemblyResolver.cs プロジェクト: zuvys/ironpython3
        private Assembly LoadFile(string path)
        {
            string ex = null;

            try {
                using (RawModule module = _universe.OpenRawModule(path)) {
                    if (_mscorlibVersion != null)
                    {
                        // to avoid problems (i.e. weird exceptions), we don't allow assemblies to load that reference a newer version of mscorlib
                        foreach (AssemblyName asmref in module.GetReferencedAssemblies())
                        {
                            if (asmref.Name == "mscorlib" && asmref.Version > _mscorlibVersion)
                            {
                                ConsoleOps.Error(true, "unable to load assembly '{0}' as it depends on a higher version of mscorlib than the one currently loaded", path);
                            }
                        }
                    }
                    Assembly asm = _universe.LoadAssembly(module);
                    if (asm.Location != module.Location && CanonicalizePath(asm.Location) != CanonicalizePath(module.Location))
                    {
                        ConsoleOps.Warning("assembly '{0}' is ignored as previously loaded assembly '{1}' has the same identity '{2}'", path, asm.Location, asm.FullName);
                    }
                    return(asm);
                }
            } catch (IOException x) {
                ex = x.Message;
            } catch (UnauthorizedAccessException x) {
                ex = x.Message;
            } catch (IKVM.Reflection.BadImageFormatException x) {
                ex = x.Message;
            }

            ConsoleOps.Error(true, "unable to load assembly '{0}'" + Environment.NewLine + "    ({1})", path, ex);
            return(null);
        }
コード例 #4
0
ファイル: AssemblyResolver.cs プロジェクト: zuvys/ironpython3
 private IEnumerable <string> FindAssemblyPath(string file)
 {
     if (Path.IsPathRooted(file))
     {
         if (File.Exists(file))
         {
             yield return(file);
         }
     }
     else
     {
         foreach (string dir in _libpaths)
         {
             string path = Path.Combine(dir, file);
             if (File.Exists(path))
             {
                 yield return(path);
             }
             // for legacy compat, we try again after appending .dll
             path = Path.Combine(dir, file + ".dll");
             if (File.Exists(path))
             {
                 ConsoleOps.Warning("Found assembly '{0}' using legacy search rule, please append '.dll' to the reference", file);
                 yield return(path);
             }
         }
     }
 }
コード例 #5
0
        public bool Validate()
        {
            if (Files.Count == 1 && string.IsNullOrWhiteSpace(MainName))
            {
                MainName = Files[0];
            }

            if (Files.Count == 0 && !string.IsNullOrWhiteSpace(MainName))
            {
                Files.Add(MainName);
            }

            if (Files == null || Files.Count == 0 || string.IsNullOrEmpty(MainName))
            {
                ConsoleOps.Error("No files or main defined");
                return(false);
            }

            if (Target != PEFileKinds.Dll && string.IsNullOrEmpty(MainName))
            {
                ConsoleOps.Error("EXEs require /main:<filename> to be specified");
                return(false);
            }

            if (DLLs.Count > 0 && !Standalone)
            {
                ConsoleOps.Error("DLLs can only be used in standalone mode");
                return(false);
            }

            if (string.IsNullOrWhiteSpace(Output) && !string.IsNullOrWhiteSpace(MainName))
            {
                Output     = Path.GetFileNameWithoutExtension(MainName);
                OutputPath = Path.GetDirectoryName(MainName);
            }
            else if (string.IsNullOrWhiteSpace(Output) && Files != null && Files.Count > 0)
            {
                Output     = Path.GetFileNameWithoutExtension(Files[0]);
                OutputPath = Path.GetDirectoryName(Files[0]);
            }

            if (!string.IsNullOrWhiteSpace(Win32Icon) && Target == PEFileKinds.Dll)
            {
                ConsoleOps.Error("DLLs may not have a win32icon");
                return(false);
            }
            else if (!string.IsNullOrWhiteSpace(Win32Icon) && !File.Exists(Win32Icon))
            {
                ConsoleOps.Error($"win32icon '{Win32Icon}' does not exist");
                return(false);
            }

            return(true);
        }
コード例 #6
0
ファイル: AssemblyResolver.cs プロジェクト: zuvys/ironpython3
        public AssemblyResolver(Universe universe, bool nostdlib, IEnumerable <string> references, IEnumerable <string> libpaths)
        {
            _universe = universe;

            _libpaths.Add(Environment.CurrentDirectory);
            _libpaths.AddRange(libpaths);
            if (!nostdlib)
            {
                _libpaths.Add(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory());
            }

            // items passed in via /lib:<path>
            foreach (string path in libpaths)
            {
                foreach (string dir in path.Split(new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries))
                {
                    if (Directory.Exists(dir))
                    {
                        _libpaths.Add(dir);
                    }
                    else
                    {
                        ConsoleOps.Warning("Directory specified ('{0}') by /lib: does not exist", dir);
                    }
                }
            }

            string envLib = Environment.GetEnvironmentVariable("LIB");

            if (!string.IsNullOrEmpty(envLib))
            {
                foreach (string dir in envLib.Split(new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries))
                {
                    if (Directory.Exists(dir))
                    {
                        _libpaths.Add(dir);
                    }
                    else
                    {
                        ConsoleOps.Warning("Directory specified ('{0}') in LIB does not exist", dir);
                    }
                }
            }

            if (nostdlib)
            {
                _mscorlibVersion = LoadMscorlib(references).GetName().Version;
            }
            else
            {
                _mscorlibVersion = universe.Load("mscorlib").GetName().Version;
            }
            _universe.AssemblyResolve += _universe_AssemblyResolve;
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: zpeach68/ironpython2
        public static int Main(string[] args)
        {
            var files  = new List <string>();
            var config = new Config();

            config.ParseArgs(args);
            if (!config.Validate())
            {
                ConsoleOps.Usage(true);
            }

            // we don't use the engine, but we create it so we can have a default context.
            ScriptEngine engine = Python.CreateEngine(config.PythonOptions);

            ConsoleOps.Info($"IronPython Compiler for {engine.Setup.DisplayName} ({engine.LanguageVersion})");
            ConsoleOps.Info($"{config}");
            ConsoleOps.Info("compiling...");

            var compileOptions = new Dictionary <string, object>()
            {
                { "mainModule", config.MainName },
                { "assemblyFileVersion", config.FileVersion },
                { "copyright", config.Copyright },
                { "productName", config.ProductName },
                { "productVersion", config.ProductVersion },
            };

            try
            {
                ClrModule.CompileModules(DefaultContext.DefaultCLS,
                                         Path.Combine(config.OutputPath, Path.ChangeExtension(config.Output, ".dll")),
                                         compileOptions,
                                         config.Files.ToArray());

                var outputfilename = Path.Combine(config.OutputPath, Path.ChangeExtension(config.Output, ".dll"));
                if (config.Target != PEFileKinds.Dll)
                {
                    outputfilename = Path.Combine(config.OutputPath, Path.ChangeExtension(config.Output, ".exe"));
                    GenerateExe(config);
                }
                ConsoleOps.Info($"Saved to {outputfilename}");
            }
            catch (Exception e)
            {
                Console.WriteLine();
                ConsoleOps.Error(true, e.Message);
            }
            return(0);
        }
コード例 #8
0
ファイル: Config.cs プロジェクト: ife/IronLanguages
        public bool Validate()
        {
            if (Files.Count == 1 && string.IsNullOrEmpty(MainName))
            {
                MainName = Files[0];
            }

            if (Files == null || Files.Count == 0 || string.IsNullOrEmpty(MainName))
            {
                ConsoleOps.Error("No files or main defined");
                return(false);
            }

            if (Target != PEFileKinds.Dll && string.IsNullOrEmpty(MainName))
            {
                ConsoleOps.Error("EXEs require /main:<filename> to be specified");
                return(false);
            }

            if (string.IsNullOrEmpty(Output) && !string.IsNullOrEmpty(MainName))
            {
                Output = Path.GetFileNameWithoutExtension(MainName);
            }
            else if (string.IsNullOrEmpty(Output) && Files != null && Files.Count > 0)
            {
                Output = Path.GetFileNameWithoutExtension(Files[0]);
            }

            if (!string.IsNullOrEmpty(Win32Icon) && Target == PEFileKinds.Dll)
            {
                ConsoleOps.Error("DLLs may not have a win32icon");
                return(false);
            }
            else if (!string.IsNullOrEmpty(Win32Icon) && !File.Exists(Win32Icon))
            {
                ConsoleOps.Error("win32icon '{0}' does not exist", Win32Icon);
                return(false);
            }

            return(true);
        }
コード例 #9
0
ファイル: AssemblyResolver.cs プロジェクト: zuvys/ironpython3
 private Assembly LoadMscorlib(IEnumerable <string> references)
 {
     if (references != null)
     {
         foreach (string r in references)
         {
             try {
                 if (AssemblyName.GetAssemblyName(r).Name == "mscorlib")
                 {
                     return(LoadFile(r));
                 }
             } catch {
             }
         }
     }
     foreach (string mscorlib in FindAssemblyPath("mscorlib.dll"))
     {
         return(LoadFile(mscorlib));
     }
     ConsoleOps.Error(true, "unable to find mscorlib.dll");
     return(null);
 }
コード例 #10
0
ファイル: Program.cs プロジェクト: zuvys/ironpython3
        /// <summary>
        /// Generates the stub .exe file for starting the app
        /// </summary>
        /// <param name="config"></param>
        private static void GenerateExe(Config config)
        {
            var u     = new Universe();
            var aName = new AssemblyName(Path.GetFileNameWithoutExtension(new FileInfo(config.Output).Name));
            var ab    = u.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save, config.OutputPath);
            var mb    = ab.DefineDynamicModule(config.Output, aName.Name + (aName.Name.EndsWith(".exe") ? string.Empty : ".exe"));
            var tb    = mb.DefineType("PythonMain", IKVM.Reflection.TypeAttributes.Public);

            if (!string.IsNullOrEmpty(config.Win32Icon))
            {
                ab.__DefineIconResource(File.ReadAllBytes(config.Win32Icon));
            }

            var attributes = new List <Tuple <string, Type> > {
                Tuple.Create(config.FileVersion, u.Import(typeof(System.Reflection.AssemblyFileVersionAttribute))),
                Tuple.Create(config.ProductName, u.Import(typeof(System.Reflection.AssemblyProductAttribute))),
                Tuple.Create(config.ProductVersion, u.Import(typeof(System.Reflection.AssemblyInformationalVersionAttribute))),
                Tuple.Create(config.Copyright, u.Import(typeof(System.Reflection.AssemblyCopyrightAttribute)))
            };

            foreach (var attr in attributes)
            {
                if (!string.IsNullOrWhiteSpace(config.FileVersion))
                {
                    CustomAttributeBuilder builder = new CustomAttributeBuilder(attr.Item2.GetConstructor(new[] { u.Import(typeof(string)) }), new object[] { attr.Item1 });
                    ab.SetCustomAttribute(builder);
                }
            }

            ab.DefineVersionInfoResource();

            MethodBuilder assemblyResolveMethod = null;
            ILGenerator   gen = null;

            if (config.Standalone)
            {
                ConsoleOps.Info("Generating stand alone executable");
                config.Embed = true;

                foreach (var a in System.AppDomain.CurrentDomain.GetAssemblies())
                {
                    var n = new AssemblyName(a.FullName);
                    if (!a.IsDynamic && a.EntryPoint == null && (n.Name.StartsWith("IronPython") || n.Name == "Microsoft.Dynamic" || n.Name == "Microsoft.Scripting"))
                    {
                        ConsoleOps.Info($"\tEmbedded {n.Name} {n.Version}");
                        var f = new FileStream(a.Location, FileMode.Open, FileAccess.Read);
                        mb.DefineManifestResource("Dll." + n.Name, f, IKVM.Reflection.ResourceAttributes.Public);
                    }
                }

                foreach (var dll in config.DLLs)
                {
                    var name = Path.GetFileNameWithoutExtension(dll);
                    ConsoleOps.Info($"\tEmbedded {name}");
                    var f = new FileStream(dll, FileMode.Open, FileAccess.Read);
                    mb.DefineManifestResource("Dll." + name, f, IKVM.Reflection.ResourceAttributes.Public);
                }

                // we currently do no error checking on what is passed in to the assemblyresolve event handler
                assemblyResolveMethod = tb.DefineMethod("AssemblyResolve", MethodAttributes.Public | MethodAttributes.Static, u.Import(typeof(System.Reflection.Assembly)), new IKVM.Reflection.Type[] { u.Import(typeof(System.Object)), u.Import(typeof(System.ResolveEventArgs)) });
                gen = assemblyResolveMethod.GetILGenerator();
                var s = gen.DeclareLocal(u.Import(typeof(System.IO.Stream))); // resource stream

                gen.Emit(OpCodes.Ldnull);
                gen.Emit(OpCodes.Stloc, s);
                var d = gen.DeclareLocal(u.Import(typeof(byte[]))); // data buffer;
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("GetEntryAssembly"), Type.EmptyTypes);
                gen.Emit(OpCodes.Ldstr, "Dll.");
                gen.Emit(OpCodes.Ldarg_1);    // The event args
                gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.ResolveEventArgs)).GetMethod("get_Name"), Type.EmptyTypes);
                gen.Emit(OpCodes.Newobj, u.Import(typeof(System.Reflection.AssemblyName)).GetConstructor(new IKVM.Reflection.Type[] { u.Import(typeof(string)) }));
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.AssemblyName)).GetMethod("get_Name"), Type.EmptyTypes);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(string)).GetMethod("Concat", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(string)) }), Type.EmptyTypes);
                gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.Reflection.Assembly)).GetMethod("GetManifestResourceStream", new IKVM.Reflection.Type[] { u.Import(typeof(string)) }), Type.EmptyTypes);
                gen.Emit(OpCodes.Stloc, s);
                gen.Emit(OpCodes.Ldloc, s);
                gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.IO.Stream)).GetMethod("get_Length"), Type.EmptyTypes);
                gen.Emit(OpCodes.Newarr, u.Import(typeof(System.Byte)));
                gen.Emit(OpCodes.Stloc, d);
                gen.Emit(OpCodes.Ldloc, s);
                gen.Emit(OpCodes.Ldloc, d);
                gen.Emit(OpCodes.Ldc_I4_0);
                gen.Emit(OpCodes.Ldloc, s);
                gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.IO.Stream)).GetMethod("get_Length"), Type.EmptyTypes);
                gen.Emit(OpCodes.Conv_I4);
                gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.IO.Stream)).GetMethod("Read", new IKVM.Reflection.Type[] { u.Import(typeof(byte[])), u.Import(typeof(int)), u.Import(typeof(int)) }), Type.EmptyTypes);
                gen.Emit(OpCodes.Pop);
                gen.Emit(OpCodes.Ldloc, d);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("Load", new IKVM.Reflection.Type[] { u.Import(typeof(byte[])) }), Type.EmptyTypes);
                gen.Emit(OpCodes.Ret);

                // generate a static constructor to assign the AssemblyResolve handler (otherwise it tries to use IronPython before it adds the handler)
                // the other way of handling this would be to move the call to InitializeModule into a separate method.
                var staticConstructor = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
                gen = staticConstructor.GetILGenerator();
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.AppDomain)).GetMethod("get_CurrentDomain"), Type.EmptyTypes);
                gen.Emit(OpCodes.Ldnull);
                gen.Emit(OpCodes.Ldftn, assemblyResolveMethod);
                gen.Emit(OpCodes.Newobj, u.Import(typeof(System.ResolveEventHandler)).GetConstructor(new IKVM.Reflection.Type[] { u.Import(typeof(object)), u.Import(typeof(System.IntPtr)) }));
                gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.AppDomain)).GetMethod("add_AssemblyResolve"), Type.EmptyTypes);
                gen.Emit(OpCodes.Ret);
            }

            var mainMethod = tb.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, u.Import(typeof(int)), Type.EmptyTypes);

            if (config.Target == PEFileKinds.WindowApplication && config.UseMta)
            {
                mainMethod.SetCustomAttribute(u.Import(typeof(System.MTAThreadAttribute)).GetConstructor(Type.EmptyTypes), new byte[0]);
            }
            else if (config.Target == PEFileKinds.WindowApplication)
            {
                mainMethod.SetCustomAttribute(u.Import(typeof(System.STAThreadAttribute)).GetConstructor(Type.EmptyTypes), new byte[0]);
            }

            gen = mainMethod.GetILGenerator();

            // variables for saving original working directory and return code of script
            var          strVar  = gen.DeclareLocal(u.Import(typeof(string)));
            var          intVar  = gen.DeclareLocal(u.Import(typeof(int)));
            LocalBuilder dictVar = null;

            if (config.PythonOptions.Count > 0)
            {
                var True  = u.Import(typeof(ScriptingRuntimeHelpers)).GetField("True");
                var False = u.Import(typeof(ScriptingRuntimeHelpers)).GetField("False");

                dictVar = gen.DeclareLocal(u.Import(typeof(Dictionary <string, object>)));
                gen.Emit(OpCodes.Newobj, u.Import(typeof(Dictionary <string, object>)).GetConstructor(Type.EmptyTypes));
                gen.Emit(OpCodes.Stloc, dictVar);

                foreach (var option in config.PythonOptions)
                {
                    gen.Emit(OpCodes.Ldloc, dictVar);
                    gen.Emit(OpCodes.Ldstr, option.Key);
                    if (option.Value is int val)
                    {
                        if (val >= -128 && val <= 127)
                        {
                            gen.Emit(OpCodes.Ldc_I4_S, val); // this is more optimized
                        }
                        else
                        {
                            gen.Emit(OpCodes.Ldc_I4, val);
                        }
                        gen.Emit(OpCodes.Box, u.Import(typeof(System.Int32)));
                    }
                    else if (option.Value.Equals(ScriptingRuntimeHelpers.True))
                    {
                        gen.Emit(OpCodes.Ldsfld, True);
                    }
                    else if (option.Value.Equals(ScriptingRuntimeHelpers.False))
                    {
                        gen.Emit(OpCodes.Ldsfld, False);
                    }
                    gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(Dictionary <string, object>)).GetMethod("Add", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(object)) }), Type.EmptyTypes);
                }
            }

            Label tryStart = gen.BeginExceptionBlock();

            // get the ScriptCode assembly...
            if (config.Embed)
            {
                // put the generated DLL into the resources for the stub exe
                var mem = new MemoryStream();
                var rw  = new ResourceWriter(mem);
                rw.AddResource("IPDll." + Path.GetFileNameWithoutExtension(config.Output) + ".dll", File.ReadAllBytes(Path.Combine(config.OutputPath, config.Output) + ".dll"));
                rw.Generate();
                mem.Position = 0;
                mb.DefineManifestResource("IPDll.resources", mem, ResourceAttributes.Public);
                File.Delete(Path.Combine(config.OutputPath, config.Output) + ".dll");

                // generate code to load the resource
                gen.Emit(OpCodes.Ldstr, "IPDll");
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("GetEntryAssembly"), Type.EmptyTypes);
                gen.Emit(OpCodes.Newobj, u.Import(typeof(System.Resources.ResourceManager)).GetConstructor(new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(System.Reflection.Assembly)) }));
                gen.Emit(OpCodes.Ldstr, "IPDll." + Path.GetFileNameWithoutExtension(config.Output) + ".dll");
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Resources.ResourceManager)).GetMethod("GetObject", new IKVM.Reflection.Type[] { u.Import(typeof(string)) }), Type.EmptyTypes);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("Load", new IKVM.Reflection.Type[] { u.Import(typeof(byte[])) }), Type.EmptyTypes);
            }
            else
            {
                // save current working directory
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Environment)).GetMethod("get_CurrentDirectory"), Type.EmptyTypes);
                gen.Emit(OpCodes.Stloc, strVar);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("GetEntryAssembly"), Type.EmptyTypes);
                gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.Reflection.Assembly)).GetMethod("get_Location"), Type.EmptyTypes);
                gen.Emit(OpCodes.Newobj, u.Import(typeof(System.IO.FileInfo)).GetConstructor(new IKVM.Reflection.Type[] { u.Import(typeof(string)) }));
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.IO.FileInfo)).GetMethod("get_Directory"), Type.EmptyTypes);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.IO.DirectoryInfo)).GetMethod("get_FullName"), Type.EmptyTypes);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Environment)).GetMethod("set_CurrentDirectory"), Type.EmptyTypes);
                gen.Emit(OpCodes.Ldstr, config.Output + ".dll");
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.IO.Path)).GetMethod("GetFullPath", new IKVM.Reflection.Type[] { u.Import(typeof(string)) }), Type.EmptyTypes);
                // result of GetFullPath stays on the stack during the restore of the
                // original working directory

                // restore original working directory
                gen.Emit(OpCodes.Ldloc, strVar);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Environment)).GetMethod("set_CurrentDirectory"), Type.EmptyTypes);

                // for the LoadFile() call, the full path of the assembly is still is on the stack
                // as the result from the call to GetFullPath()
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Reflection.Assembly)).GetMethod("LoadFile", new IKVM.Reflection.Type[] { u.Import(typeof(string)) }), Type.EmptyTypes);
            }

            // emit module name
            gen.Emit(OpCodes.Ldstr, "__main__");  // main module name
            gen.Emit(OpCodes.Ldnull);             // no references
            gen.Emit(OpCodes.Ldc_I4_0);           // don't ignore environment variables for engine startup
            if (config.PythonOptions.Count > 0)
            {
                gen.Emit(OpCodes.Ldloc, dictVar);
            }
            else
            {
                gen.Emit(OpCodes.Ldnull);
            }

            // call InitializeModuleEx
            // (this will also run the script)
            // and put the return code on the stack
            gen.EmitCall(OpCodes.Call, u.Import(typeof(PythonOps)).GetMethod("InitializeModuleEx",
                                                                             new IKVM.Reflection.Type[] { u.Import(typeof(System.Reflection.Assembly)), u.Import(typeof(string)), u.Import(typeof(string[])), u.Import(typeof(bool)), u.Import(typeof(Dictionary <string, object>)) }),
                         Type.EmptyTypes);
            gen.Emit(OpCodes.Stloc, intVar);
            gen.BeginCatchBlock(u.Import(typeof(Exception)));

            if (config.Target == PEFileKinds.ConsoleApplication)
            {
                gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.Exception)).GetMethod("get_Message", Type.EmptyTypes), Type.EmptyTypes);
                gen.Emit(OpCodes.Stloc, strVar);
                gen.Emit(OpCodes.Ldstr, config.ErrorMessageFormat);
                gen.Emit(OpCodes.Ldloc, strVar);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Console)).GetMethod("WriteLine", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(string)) }), Type.EmptyTypes);
            }
            else
            {
                gen.EmitCall(OpCodes.Callvirt, u.Import(typeof(System.Exception)).GetMethod("get_Message", Type.EmptyTypes), Type.EmptyTypes);
                gen.Emit(OpCodes.Stloc, strVar);
                gen.Emit(OpCodes.Ldstr, config.ErrorMessageFormat);
                gen.Emit(OpCodes.Ldloc, strVar);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(string)).GetMethod("Format", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(string)) }), Type.EmptyTypes);
                gen.Emit(OpCodes.Ldstr, "Error");
                gen.Emit(OpCodes.Ldc_I4, (int)System.Windows.Forms.MessageBoxButtons.OK);
                gen.Emit(OpCodes.Ldc_I4, (int)System.Windows.Forms.MessageBoxIcon.Error);
                gen.EmitCall(OpCodes.Call, u.Import(typeof(System.Windows.Forms.MessageBox)).GetMethod("Show", new IKVM.Reflection.Type[] { u.Import(typeof(string)), u.Import(typeof(string)), u.Import(typeof(System.Windows.Forms.MessageBoxButtons)), u.Import(typeof(System.Windows.Forms.MessageBoxIcon)) }), Type.EmptyTypes);
                gen.Emit(OpCodes.Pop);
            }

            gen.Emit(OpCodes.Ldc_I4, -1); // return code is -1 to show failure
            gen.Emit(OpCodes.Stloc, intVar);

            gen.EndExceptionBlock();

            gen.Emit(OpCodes.Ldloc, intVar);
            gen.Emit(OpCodes.Ret);

            tb.CreateType();
            ab.SetEntryPoint(mainMethod, config.Target);
            string fileName = aName.Name.EndsWith(".exe") ? aName.Name : aName.Name + ".exe";

            ab.Save(fileName, config.Platform, config.Machine);
        }
コード例 #11
0
ファイル: Config.cs プロジェクト: ife/IronLanguages
        public void ParseArgs(IEnumerable <string> args, List <string> respFiles = null)
        {
            foreach (var a in args)
            {
                var arg = a.Trim();
                if (arg.StartsWith("#"))
                {
                    continue;
                }

                if (arg.StartsWith("/main:"))
                {
                    MainName = Main = arg.Substring(6).Trim('"');
                    // only override the target kind if its currently a DLL
                    if (Target == PEFileKinds.Dll)
                    {
                        Target = PEFileKinds.ConsoleApplication;
                    }
                }
                else if (arg.StartsWith("/out:"))
                {
                    Output = arg.Substring(5).Trim('"');
                }
                else if (arg.StartsWith("/target:"))
                {
                    string tgt = arg.Substring(8).Trim('"');
                    switch (tgt)
                    {
                    case "exe":
                        Target = PEFileKinds.ConsoleApplication;
                        break;

                    case "winexe":
                        Target = PEFileKinds.WindowApplication;
                        break;

                    default:
                        Target = PEFileKinds.Dll;
                        break;
                    }
                }
                else if (arg.StartsWith("/platform:"))
                {
                    string plat = arg.Substring(10).Trim('"');
                    switch (plat)
                    {
                    case "x86":
                        Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.Required32Bit;
                        Machine  = IKVM.Reflection.ImageFileMachine.I386;
                        break;

                    case "x64":
                        Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.PE32Plus;
                        Machine  = IKVM.Reflection.ImageFileMachine.AMD64;
                        break;

                    default:
                        Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly;
                        Machine  = IKVM.Reflection.ImageFileMachine.I386;
                        break;
                    }
                }
                else if (arg.StartsWith("/win32icon:"))
                {
                    Win32Icon = arg.Substring(11).Trim('"');
                }
                else if (arg.StartsWith("/version:"))
                {
                    Version = arg.Substring(9).Trim('"');
                }
                else if (arg.StartsWith("/errfmt:"))
                {
                    ErrorMessageFormat = arg.Substring(8);
                }
                else if (arg.StartsWith("/embed"))
                {
                    Embed = true;
                }
                else if (arg.StartsWith("/standalone"))
                {
                    Standalone = true;
                }
                else if (arg.StartsWith("/mta"))
                {
                    UseMta = true;
                }
                else if (arg.StartsWith("/file_info"))
                {
                    string[] items = arg.Substring(10).Split(':');
                    if (items.Length == 2)
                    {
                        switch (items[0].Trim())
                        {
                        case "version":
                            FileInfoVersion = new Version(items[1].Trim());
                            break;

                        case "product":
                            FileInfoProduct = items[1].Trim();
                            break;

                        case "product_version":
                            FileInfoProductVersion = items[1].Trim();
                            break;

                        case "company":
                            FileInfoCompany = items[1].Trim();
                            break;

                        case "copyright":
                            FileInfoCopyright = items[1].Trim();
                            break;

                        case "trademark":
                            FileInfoTrademark = items[1].Trim();
                            break;

                        default:
                            ConsoleOps.Warning("Unknown File Information option {0}", arg);
                            break;
                        }
                    }
                }
                else if (Array.IndexOf(new string[] { "/?", "-?", "/h", "-h" }, args) >= 0)
                {
                    ConsoleOps.Usage(true);
                }
                else
                {
                    if (arg.StartsWith("@"))
                    {
                        var respFile = Path.GetFullPath(arg.Substring(1));
                        if (respFiles == null)
                        {
                            respFiles = new List <string>();
                        }

                        if (!respFiles.Contains(respFile))
                        {
                            respFiles.Add(respFile);
                            ParseArgs(File.ReadAllLines(respFile), respFiles);
                        }
                        else
                        {
                            ConsoleOps.Warning("Already parsed response file '{0}'", arg.Substring(1));
                        }
                    }
                    else
                    {
                        Files.Add(arg);
                    }
                }
            }
        }
コード例 #12
0
        public void ParseArgs(IEnumerable <string> args, List <string> respFiles = null)
        {
            var helpStrings = new string[] { "/?", "-?", "/h", "-h" };

            foreach (var a in args)
            {
                var arg = a.Trim();
                if (arg.StartsWith("#", StringComparison.Ordinal))
                {
                    continue;
                }

                if (arg.StartsWith("/main:", StringComparison.Ordinal))
                {
                    MainName = Main = arg.Substring(6).Trim('"');
                    // only override the target kind if its currently a DLL
                    if (Target == PEFileKinds.Dll)
                    {
                        Target = PEFileKinds.ConsoleApplication;
                    }
                }
                else if (arg.StartsWith("/out:", StringComparison.Ordinal))
                {
                    Output = arg.Substring(5).Trim('"');
                }
                else if (arg.StartsWith("/target:", StringComparison.Ordinal))
                {
                    string tgt = arg.Substring(8).Trim('"');
                    switch (tgt)
                    {
                    case "exe":
                        Target = PEFileKinds.ConsoleApplication;
                        break;

                    case "winexe":
                        Target = PEFileKinds.WindowApplication;
                        break;

                    default:
                        Target = PEFileKinds.Dll;
                        break;
                    }
                }
                else if (arg.StartsWith("/platform:", StringComparison.Ordinal))
                {
                    string plat = arg.Substring(10).Trim('"');
                    switch (plat)
                    {
                    case "x86":
                        Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.Required32Bit;
                        Machine  = IKVM.Reflection.ImageFileMachine.I386;
                        break;

                    case "x64":
                        Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.PE32Plus;
                        Machine  = IKVM.Reflection.ImageFileMachine.AMD64;
                        break;

                    default:
                        Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly;
                        Machine  = IKVM.Reflection.ImageFileMachine.AMD64;
                        break;
                    }
                }
                else if (arg.StartsWith("/win32icon:", StringComparison.Ordinal))
                {
                    Win32Icon = arg.Substring(11).Trim('"');
                }
                else if (arg.StartsWith("/fileversion:", StringComparison.Ordinal))
                {
                    FileVersion = arg.Substring(13).Trim('"');
                }
                else if (arg.StartsWith("/productversion:", StringComparison.Ordinal))
                {
                    ProductVersion = arg.Substring(16).Trim('"');
                }
                else if (arg.StartsWith("/productname:", StringComparison.Ordinal))
                {
                    ProductName = arg.Substring(13).Trim('"');
                }
                else if (arg.StartsWith("/copyright:", StringComparison.Ordinal))
                {
                    Copyright = arg.Substring(11).Trim('"');
                }
                else if (arg.StartsWith("/errfmt:", StringComparison.Ordinal))
                {
                    ErrorMessageFormat = arg.Substring(8);
                }
                else if (arg.Equals("/embed", StringComparison.Ordinal))
                {
                    Embed = true;
                }
                else if (arg.Equals("/standalone", StringComparison.Ordinal))
                {
                    Standalone = true;
                }
                else if (arg.Equals("/mta", StringComparison.Ordinal))
                {
                    UseMta = true;
                }
                else if (arg.Equals("/sta", StringComparison.Ordinal))
                {
                    UseSta = true;
                }
                else if (arg.StartsWith("/recurse:", StringComparison.Ordinal))
                {
                    string pattern = arg.Substring(9);
                    if (string.IsNullOrWhiteSpace(pattern))
                    {
                        ConsoleOps.Error(true, "Missing pattern for /recurse option");
                    }
                    foreach (var f in Directory.EnumerateFiles(Environment.CurrentDirectory, pattern))
                    {
                        Files.Add(Path.GetFullPath(f));
                    }
                }
                else if (Array.IndexOf(helpStrings, arg) >= 0)
                {
                    ConsoleOps.Usage(true);
                }
                else if (arg.StartsWith("/py:", StringComparison.Ordinal))
                {
                    // if you add a parameter that takes a different type then
                    // ScriptingRuntimeHelpers.True/False or int
                    // you need ot also modify Program.cs for standalone generation.
                    string[] pyargs = arg.Substring(4).Trim('"').Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    switch (pyargs[0])
                    {
                    case "-X:Frames":
                        PythonOptions["Frames"] = ScriptingRuntimeHelpers.True;
                        break;

                    case "-X:FullFrames":
                        PythonOptions["Frames"] = PythonOptions["FullFrames"] = ScriptingRuntimeHelpers.True;
                        break;

                    case "-X:Tracing":
                        PythonOptions["Tracing"] = ScriptingRuntimeHelpers.True;
                        break;

                    case "-X:GCStress":
                        int gcStress;
                        if (!int.TryParse(pyargs[1], out gcStress) || (gcStress <0 || gcStress> GC.MaxGeneration))
                        {
                            ConsoleOps.Error(true, $"The argument for the {pyargs[1]} option must be between 0 and {GC.MaxGeneration}.");
                        }

                        PythonOptions["GCStress"] = gcStress;
                        break;

                    case "-X:MaxRecursion":
                        // we need about 6 frames for starting up, so 10 is a nice round number.
                        int limit;
                        if (!int.TryParse(pyargs[1], out limit) || limit < 10)
                        {
                            ConsoleOps.Error(true, $"The argument for the {pyargs[1]} option must be an integer >= 10.");
                        }

                        PythonOptions["RecursionLimit"] = limit;
                        break;

                    case "-X:EnableProfiler":
                        PythonOptions["EnableProfiler"] = ScriptingRuntimeHelpers.True;
                        break;

                    case "-X:LightweightScopes":
                        PythonOptions["LightweightScopes"] = ScriptingRuntimeHelpers.True;
                        break;

                    case "-X:Debug":
                        PythonOptions["Debug"] = ScriptingRuntimeHelpers.True;
                        break;
                    }
                }
                else
                {
                    if (arg.StartsWith("@", StringComparison.Ordinal))
                    {
                        var respFile = Path.GetFullPath(arg.Substring(1));
                        if (respFiles == null)
                        {
                            respFiles = new List <string>();
                        }

                        if (!respFiles.Contains(respFile))
                        {
                            respFiles.Add(respFile);
                            ParseArgs(File.ReadAllLines(respFile), respFiles);
                        }
                        else
                        {
                            ConsoleOps.Warning($"Already parsed response file '{arg.Substring(1)}'");
                        }
                    }
                    else
                    {
                        if (arg.ToLower().EndsWith(".dll", StringComparison.Ordinal))
                        {
                            DLLs.Add(arg);
                        }
                        else
                        {
                            Files.Add(arg);
                        }
                    }
                }
            }
        }