Beispiel #1
0
        static AssemblyTranslator CreateTranslator(
            Configuration configuration, AssemblyManifest manifest, AssemblyCache assemblyCache
            )
        {
            TypeInfoProvider typeInfoProvider = null;

            Console.Error.WriteLine(
                "// Using .NET framework {0} in {1} GC mode. Tuned GC {2}.",
                Environment.Version.ToString(),
                System.Runtime.GCSettings.IsServerGC ? "server" : "workstation",
#if TARGETTING_FX_4_5
                configuration.TuneGarbageCollection.GetValueOrDefault(true) ? "enabled" : "disabled"
#else
                "disabled (must be built in .NET 4.5 mode)"
#endif
                );

            if (
                configuration.ReuseTypeInfoAcrossAssemblies.GetValueOrDefault(true) &&
                (CachedTypeInfoProvider != null)
                )
            {
                if (CachedTypeInfoProviderConfiguration.Assemblies.Equals(configuration.Assemblies))
                {
                    typeInfoProvider = CachedTypeInfoProvider;
                }
            }

            var translator = new AssemblyTranslator(
                configuration, typeInfoProvider, manifest, assemblyCache,
                onProxyAssemblyLoaded: (name, classification) =>
                Console.Error.WriteLine("// Loaded proxies from '{0}'", ShortenPath(name))
                );

            translator.Decompiling       += MakeProgressHandler("Decompiling ");
            translator.RunningTransforms += MakeProgressHandler("Translating ");
            translator.Writing           += MakeProgressHandler("Writing JS  ");

            translator.AssemblyLoaded += (fn, classification) =>
                                         Console.Error.WriteLine("// Loaded {0} ({1})", ShortenPath(fn), classification);
            translator.CouldNotLoadSymbols     += (fn, ex) => {
            };
            translator.CouldNotResolveAssembly += (fn, ex) =>
                                                  Console.Error.WriteLine("// Could not load module {0}: {1}", fn, ex.Message);
            translator.CouldNotDecompileMethod += (fn, ex) =>
                                                  Console.Error.WriteLine("// Could not decompile method {0}: {1}", fn, ex);

            if (typeInfoProvider == null)
            {
                if (CachedTypeInfoProvider != null)
                {
                    CachedTypeInfoProvider.Dispose();
                }

                CachedTypeInfoProvider = translator.GetTypeInfoProvider();
                CachedTypeInfoProviderConfiguration = configuration;
            }

            return(translator);
        }
Beispiel #2
0
        static AssemblyTranslator CreateTranslator(
            Configuration configuration, AssemblyManifest manifest, AssemblyCache assemblyCache
            )
        {
            TypeInfoProvider typeInfoProvider = null;

            if (
                configuration.ReuseTypeInfoAcrossAssemblies.GetValueOrDefault(true) &&
                (CachedTypeInfoProvider != null)
                )
            {
                if (CachedTypeInfoProviderConfiguration.Assemblies.Equals(configuration.Assemblies))
                {
                    typeInfoProvider = CachedTypeInfoProvider;
                }
            }

            var translator = new AssemblyTranslator(
                configuration, typeInfoProvider, manifest, assemblyCache,
                onProxyAssemblyLoaded: (name, classification) => {
                Console.Error.WriteLine("// Loaded proxies from '{0}'", ShortenPath(name));
            }
                );

            translator.Decompiling       += MakeProgressHandler("Decompiling ");
            translator.RunningTransforms += MakeProgressHandler("Translating ");
            translator.Writing           += MakeProgressHandler("Writing JS  ");

            translator.AssemblyLoaded += (fn, classification) => {
                Console.Error.WriteLine("// Loaded {0} ({1})", ShortenPath(fn), classification);
            };
            translator.CouldNotLoadSymbols     += (fn, ex) => {
            };
            translator.CouldNotResolveAssembly += (fn, ex) => {
                Console.Error.WriteLine("// Could not load module {0}: {1}", fn, ex.Message);
            };
            translator.CouldNotDecompileMethod += (fn, ex) => {
                Console.Error.WriteLine("// Could not decompile method {0}: {1}", fn, ex.Message);
            };

            if (typeInfoProvider == null)
            {
                if (CachedTypeInfoProvider != null)
                {
                    CachedTypeInfoProvider.Dispose();
                }

                CachedTypeInfoProvider = translator.GetTypeInfoProvider();
                CachedTypeInfoProviderConfiguration = configuration;
            }

            return(translator);
        }
Beispiel #3
0
        static AssemblyTranslator CreateTranslator(
            Configuration configuration, AssemblyManifest manifest, AssemblyCache assemblyCache
        )
        {
            TypeInfoProvider typeInfoProvider = null;

            if (
                configuration.ReuseTypeInfoAcrossAssemblies.GetValueOrDefault(true) &&
                (CachedTypeInfoProvider != null)
            ) {
                if (CachedTypeInfoProviderConfiguration.Assemblies.Equals(configuration.Assemblies))
                    typeInfoProvider = CachedTypeInfoProvider;
            }

            var translator = new AssemblyTranslator(configuration, typeInfoProvider, manifest, assemblyCache);

            translator.Decompiling += MakeProgressHandler("Decompiling   ");
            translator.Optimizing += MakeProgressHandler ("Optimizing    ");
            translator.Writing += MakeProgressHandler    ("Generating JS ");

            translator.AssemblyLoaded += (fn) => {
                Console.Error.WriteLine("// Loaded {0}", ShortenPath(fn));
            };
            translator.CouldNotLoadSymbols += (fn, ex) => {
            };
            translator.CouldNotResolveAssembly += (fn, ex) => {
                Console.Error.WriteLine("// Could not load module {0}: {1}", fn, ex.Message);
            };
            translator.CouldNotDecompileMethod += (fn, ex) => {
                Console.Error.WriteLine("// Could not decompile method {0}: {1}", fn, ex.Message);
            };

            if (typeInfoProvider == null) {
                if (CachedTypeInfoProvider != null)
                    CachedTypeInfoProvider.Dispose();

                CachedTypeInfoProvider = translator.GetTypeInfoProvider();
                CachedTypeInfoProviderConfiguration = configuration;
            }

            return translator;
        }
Beispiel #4
0
        static AssemblyTranslator CreateTranslator(
            Configuration configuration, AssemblyManifest manifest, AssemblyCache assemblyCache,
            Dictionary <string, IEmitterFactory> emitterFactories,
            Dictionary <string, IAnalyzer> analyzers
            )
        {
            TypeInfoProvider typeInfoProvider = null;

            InformationWriteLine(
                "// Using .NET framework {0} in {1} GC mode. Tuned GC {2}.",
                Environment.Version.ToString(),
                System.Runtime.GCSettings.IsServerGC ? "server" : "workstation",
                configuration.TuneGarbageCollection.GetValueOrDefault(true) ? "enabled" : "disabled"
                );

            if (
                configuration.ReuseTypeInfoAcrossAssemblies.GetValueOrDefault(true) &&
                (CachedTypeInfoProvider != null)
                )
            {
                if (CachedTypeInfoProviderConfiguration.Assemblies.Equals(configuration.Assemblies))
                {
                    typeInfoProvider = CachedTypeInfoProvider;
                }
            }

            IEmitterFactory emitterFactory = GetEmitterFactory(configuration, emitterFactories);

            var translator = new AssemblyTranslator(
                configuration, typeInfoProvider, manifest, new AssemblyDataResolver(configuration, assemblyCache),
                onProxyAssemblyLoaded: (name, classification) =>
                InformationWriteLine("// Loaded proxies from '{0}'", ShortenPath(name)),
                emitterFactory: emitterFactory,
                analyzers: analyzers.Values
                );

            translator.Decompiling       += MakeProgressHandler("Decompiling ");
            translator.RunningTransforms += MakeProgressHandler("Translating ");
            translator.Writing           += MakeProgressHandler("Writing JS  ");

            translator.AssemblyLoaded += (fn, classification) =>
                                         InformationWriteLine("// Loaded {0} ({1})", ShortenPath(fn), classification);
            translator.CouldNotLoadSymbols     += (fn, ex) => {
            };
            translator.CouldNotResolveAssembly += (fn, ex) =>
                                                  Console.Error.WriteLine("// Could not load module {0}: {1}", fn, ex.Message);
            translator.CouldNotDecompileMethod += (fn, ex) =>
                                                  Console.Error.WriteLine("// Could not decompile method {0}: {1}", fn, ex);

            if (configuration.ProxyWarnings.GetValueOrDefault(false))
            {
                translator.ProxyNotMatched += (ti) => {
                    Console.Error.WriteLine("// Proxy {0} never matched any types.", ti);
                };

                translator.ProxyMemberNotMatched += (qmi) => {
                    Console.Error.WriteLine("// Proxy member {0} never matched any members.", qmi);
                };
            }

            if (typeInfoProvider == null)
            {
                if (CachedTypeInfoProvider != null)
                {
                    CachedTypeInfoProvider.Dispose();
                }

                CachedTypeInfoProvider = translator.GetTypeInfoProvider();
                CachedTypeInfoProviderConfiguration = configuration;
            }

            return(translator);
        }
Beispiel #5
0
        /// <summary>
        /// Compiles the provided C# and then translates it into JavaScript.
        /// On success, returns the JS. On failure, throws.
        /// </summary>
        public static CompiledSnippet Compile(string csharp, bool deleteTempFiles)
        {
            var result = new CompiledSnippet {
                OriginalSource = csharp
            };

            int tempDirId = Interlocked.Increment(ref NextTempDirId);
            var tempPath  = Path.Combine(Path.GetTempPath(), "JSIL.Try", tempDirId.ToString());

            if (!Directory.Exists(tempPath))
            {
                Directory.CreateDirectory(tempPath);
            }

            try {
                string resultPath, entryPointName, compilerOutput, resultFullName;

                long compileStarted = DateTime.UtcNow.Ticks;

                CompileAssembly(
                    tempPath, csharp,
                    out compilerOutput, out resultPath,
                    out resultFullName, out entryPointName
                    );

                result.CompileElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - compileStarted).TotalSeconds;

                if ((resultPath == null) || !File.Exists(resultPath))
                {
                    if (String.IsNullOrWhiteSpace(compilerOutput))
                    {
                        throw new Exception("Compile failed with unknown error.");
                    }
                    else
                    {
                        throw new Exception(compilerOutput);
                    }
                }

                var translatorConfiguration = new Configuration {
                    ApplyDefaults = false,
                    Assemblies    =
                    {
                        Stubbed =
                        {
                            "mscorlib,",
                            "System.*",
                            "Microsoft.*"
                        },
                        Ignored =
                        {
                            "Microsoft.VisualC,",
                            "Accessibility,",
                            "SMDiagnostics,",
                            "System.EnterpriseServices,",
                            "JSIL.Meta,"
                        }
                    },
                    FrameworkVersion = 4.0,
                    GenerateSkeletonsForStubbedAssemblies = false,
                    GenerateContentManifest = false,
                    IncludeDependencies     = false,
                    UseSymbols = true,
                    UseThreads = false
                };

                var translatorOutput = new StringBuilder();

                var typeInfo = CachedTypeInfo.Value;

                // Don't use a cached type provider if this snippet contains a proxy.
                bool disableCaching = csharp.Contains("JSProxy");

                using (var translator = new AssemblyTranslator(
                           translatorConfiguration,
                           // Reuse the cached type info provider, if one exists.
                           disableCaching ? null : typeInfo,
                           // Can't reuse a manifest meaningfully here.
                           null,
                           // Reuse the assembly cache so that mscorlib doesn't get loaded every time.
                           AssemblyCache
                           )) {
                    translator.CouldNotDecompileMethod += (s, exception) => {
                        lock (translatorOutput)
                            translatorOutput.AppendFormat(
                                "Could not decompile method '{0}': {1}{2}",
                                s, exception.Message, Environment.NewLine
                                );
                    };

                    translator.CouldNotResolveAssembly += (s, exception) => {
                        lock (translatorOutput)
                            translatorOutput.AppendFormat(
                                "Could not resolve assembly '{0}': {1}{2}",
                                s, exception.Message, Environment.NewLine
                                );
                    };

                    translator.Warning += (s) => {
                        lock (translatorOutput)
                            translatorOutput.AppendLine(s);
                    };

                    var translateStarted  = DateTime.UtcNow.Ticks;
                    var translationResult = translator.Translate(resultPath, true);

                    AssemblyTranslator.GenerateManifest(
                        translator.Manifest, Path.GetDirectoryName(resultPath), translationResult
                        );

                    result.EntryPoint = String.Format(
                        "{0}.{1}",
                        translator.Manifest.GetPrivateToken(resultFullName).IDString,
                        entryPointName
                        );

                    result.Warnings         = translatorOutput.ToString().Trim();
                    result.TranslateElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - translateStarted).TotalSeconds;
                    result.JavaScript       = translationResult.WriteToString();

                    if (typeInfo != null)
                    {
                        // Remove the temporary assembly from the type info provider.
                        typeInfo.Remove(translationResult.Assemblies.ToArray());
                    }
                    else if (!disableCaching)
                    {
                        // We didn't have a type info provider to reuse, so store the translator's.
                        CachedTypeInfo.Value = typeInfo = translator.GetTypeInfoProvider();
                    }

                    /*
                     * result.Warnings += String.Format(
                     *  "{1} assemblies loaded{0}",
                     *  Environment.NewLine, AppDomain.CurrentDomain.GetAssemblies().Length
                     * );
                     */

                    /*
                     * result.Warnings += String.Format(
                     *  "TypeInfo.Count = {1}{0}AssemblyCache.Count = {2}{0}",
                     *  Environment.NewLine, TypeInfo.Count, AssemblyCache.Count
                     * );
                     */
                }

                /*
                 *
                 * GC.Collect();
                 *
                 * result.Warnings += String.Format(
                 *  "{1} byte(s) GC heap {0}",
                 *  Environment.NewLine, GC.GetTotalMemory(true)
                 * );
                 */

                return(result);
            } finally {
                try {
                    if (deleteTempFiles)
                    {
                        Directory.Delete(tempPath, true);
                    }
                } catch (Exception exc) {
                    Console.WriteLine("Failed to empty temporary directory: {0}", exc.Message);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Compiles the provided C# and then translates it into JavaScript.
        /// On success, returns the JS. On failure, throws.
        /// </summary>
        public static CompiledSnippet Compile(string csharp, bool deleteTempFiles)
        {
            var result = new CompiledSnippet {
                OriginalSource = csharp
            };

            int tempDirId = Interlocked.Increment(ref NextTempDirId);
            var tempPath = Path.Combine(Path.GetTempPath(), "JSIL.Try", tempDirId.ToString());

            if (!Directory.Exists(tempPath))
                Directory.CreateDirectory(tempPath);

            try {
                string resultPath, entryPointName, compilerOutput, resultFullName;

                long compileStarted = DateTime.UtcNow.Ticks;

                CompileAssembly(
                    tempPath, csharp,
                    out compilerOutput, out resultPath,
                    out resultFullName, out entryPointName
                );

                result.CompileElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - compileStarted).TotalSeconds;

                if ((resultPath == null) || !File.Exists(resultPath)) {
                    if (String.IsNullOrWhiteSpace(compilerOutput))
                        throw new Exception("Compile failed with unknown error.");
                    else
                        throw new Exception(compilerOutput);
                }

                var translatorConfiguration = new Configuration {
                    ApplyDefaults = false,
                    Assemblies = {
                        Stubbed = {
                            "mscorlib,",
                            "System.*",
                            "Microsoft.*"
                        },
                        Ignored = {
                            "Microsoft.VisualC,",
                            "Accessibility,",
                            "SMDiagnostics,",
                            "System.EnterpriseServices,",
                            "JSIL.Meta,"
                        }
                    },
                    FrameworkVersion = 4.0,
                    GenerateSkeletonsForStubbedAssemblies = false,
                    GenerateContentManifest = false,
                    IncludeDependencies = false,
                    UseSymbols = true,
                    UseThreads = false
                };

                var translatorOutput = new StringBuilder();

                var typeInfo = CachedTypeInfo.Value;

                // Don't use a cached type provider if this snippet contains a proxy.
                bool disableCaching = csharp.Contains("JSProxy");

                using (var translator = new AssemblyTranslator(
                    translatorConfiguration,
                    // Reuse the cached type info provider, if one exists.
                    disableCaching ? null : typeInfo,
                    // Can't reuse a manifest meaningfully here.
                    null,
                    // Reuse the assembly cache so that mscorlib doesn't get loaded every time.
                    AssemblyCache
                )) {
                    translator.CouldNotDecompileMethod += (s, exception) => {
                        lock (translatorOutput)
                            translatorOutput.AppendFormat(
                                "Could not decompile method '{0}': {1}{2}",
                                s, exception.Message, Environment.NewLine
                            );
                    };

                    translator.CouldNotResolveAssembly += (s, exception) => {
                        lock (translatorOutput)
                            translatorOutput.AppendFormat(
                                "Could not resolve assembly '{0}': {1}{2}",
                                s, exception.Message, Environment.NewLine
                            );
                    };

                    translator.Warning += (s) => {
                        lock (translatorOutput)
                            translatorOutput.AppendLine(s);
                    };

                    var translateStarted = DateTime.UtcNow.Ticks;
                    var translationResult = translator.Translate(resultPath, true);

                    AssemblyTranslator.GenerateManifest(
                        translator.Manifest, Path.GetDirectoryName(resultPath), translationResult
                    );

                    result.EntryPoint = String.Format(
                        "{0}.{1}",
                        translator.Manifest.GetPrivateToken(resultFullName).IDString,
                        entryPointName
                    );

                    result.Warnings = translatorOutput.ToString().Trim();
                    result.TranslateElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - translateStarted).TotalSeconds;
                    result.JavaScript = translationResult.WriteToString();

                    if (typeInfo != null) {
                        // Remove the temporary assembly from the type info provider.
                        typeInfo.Remove(translationResult.Assemblies.ToArray());
                    } else if (!disableCaching) {
                        // We didn't have a type info provider to reuse, so store the translator's.
                        CachedTypeInfo.Value = typeInfo = translator.GetTypeInfoProvider();
                    }

                    /*
                    result.Warnings += String.Format(
                        "{1} assemblies loaded{0}",
                        Environment.NewLine, AppDomain.CurrentDomain.GetAssemblies().Length
                    );
                     */

                    /*
                    result.Warnings += String.Format(
                        "TypeInfo.Count = {1}{0}AssemblyCache.Count = {2}{0}",
                        Environment.NewLine, TypeInfo.Count, AssemblyCache.Count
                    );
                        */
                }

                /*

                GC.Collect();

                result.Warnings += String.Format(
                    "{1} byte(s) GC heap {0}",
                    Environment.NewLine, GC.GetTotalMemory(true)
                );
                 */

                return result;
            } finally {

                try {
                    if (deleteTempFiles)
                        Directory.Delete(tempPath, true);
                } catch (Exception exc) {
                    Console.WriteLine("Failed to empty temporary directory: {0}", exc.Message);
                }
            }
        }