Esempio n. 1
0
        private void PopulatePackageAssembliesFromPackageContent(Package package, Entity.Package packageEntity, PackageVersion packageVersionEntity)
        {
            var uniqueAssemblies = new Dictionary <string, AssemblyName>();
            var coreAssembly     = typeof(object).Assembly;

            using var byteStream = new MemoryStream(package.Content);
            using var archive    = ArchiveFactory.Open(byteStream);
            using var lc         = new MetadataLoadContext(new ZipAssemblyResolver(archive, coreAssembly), coreAssembly.FullName);
            foreach (var archiveEntry in archive.Entries)
            {
                if (archiveEntry.IsDirectory ||
                    (!archiveEntry.Key.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase) && !archiveEntry.Key.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)))
                {
                    continue;
                }

                System.Reflection.Assembly assembly;

                using var entryStream = archiveEntry.ExtractToStream();
                try
                {
                    assembly = lc.LoadFromStream(entryStream);
                }
                catch (FileLoadException)
                {
                    Logger.LogError($"{packageEntity.Name} (v{packageVersionEntity.Version}) - {archiveEntry.Key} - could not be loaded.");
                    continue;
                }
                catch (Exception e)
                {
                    Logger.LogError(e, $"{packageEntity.Name} (v{packageVersionEntity.Version}) - {archiveEntry.Key} - threw an exception.");
                    continue;
                }

                foreach (var referencedAssembly in assembly.GetReferencedAssemblies())
                {
                    if (!uniqueAssemblies.ContainsKey(referencedAssembly.FullName))
                    {
                        uniqueAssemblies.Add(referencedAssembly.FullName, referencedAssembly);
                    }
                }

                var assemblyName = assembly.GetName();
                Logger.LogDebug($"Processing assembly {assemblyName.Name}, version={assemblyName.Version}");

                var assemblyEntity               = GetOrAddAssemblyEntity(assemblyName);
                var assemblyVersionEntity        = GetOrAddAssemblyVersionEntity(assemblyEntity, assemblyName);
                var packageAssemblyVersionEntity = GetOrAddPackageAssemblyVersionEntity(packageEntity, packageVersionEntity, assemblyEntity, assemblyVersionEntity);
                packageAssemblyVersionEntity.ReferenceIncluded = true;
            }

            foreach (var uniqueAssembly in uniqueAssemblies.Values)
            {
                Logger.LogDebug($"Processing referenced assembly {uniqueAssembly.Name}, version={uniqueAssembly.Version}");

                var assemblyEntity        = GetOrAddAssemblyEntity(uniqueAssembly);
                var assemblyVersionEntity = GetOrAddAssemblyVersionEntity(assemblyEntity, uniqueAssembly);

                GetOrAddPackageAssemblyVersionEntity(packageEntity, packageVersionEntity, assemblyEntity, assemblyVersionEntity);
            }
        }
Esempio n. 2
0
        public static void TestEHClauses()
        {
            using (MetadataLoadContext lc = new MetadataLoadContext(new CoreMetadataAssemblyResolver(), "mscorlib"))
            {
                Assembly coreAssembly = lc.LoadFromStream(TestUtils.CreateStreamForCoreAssembly());
                Assembly a            = lc.LoadFromByteArray(TestData.s_AssemblyWithEhClausesImage);

                Type gt   = a.GetType("G`1", throwOnError: true);
                Type et   = a.GetType("MyException`2", throwOnError: true);
                Type gtP0 = gt.GetGenericTypeParameters()[0];
                Type etP0 = et.GetGenericTypeParameters()[0];
                Type etP1 = et.GetGenericTypeParameters()[1];
                {
                    MethodInfo m    = gt.GetMethod("Catch");
                    Type       theM = m.GetGenericArguments()[0];

                    MethodBody body = m.GetMethodBody();
                    IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses;
                    Assert.Equal(1, ehs.Count);
                    ExceptionHandlingClause eh = ehs[0];
                    Assert.Equal(ExceptionHandlingClauseOptions.Clause, eh.Flags);
                    Assert.Equal(1, eh.TryOffset);
                    Assert.Equal(15, eh.TryLength);
                    Assert.Equal(16, eh.HandlerOffset);
                    Assert.Equal(16, eh.HandlerLength);
                    Assert.Throws <InvalidOperationException>(() => eh.FilterOffset);
                    Assert.Equal(et.MakeGenericType(gtP0, theM), eh.CatchType);
                }

                {
                    Type sysInt32  = coreAssembly.GetType("System.Int32", throwOnError: true);
                    Type sysSingle = coreAssembly.GetType("System.Single", throwOnError: true);

                    MethodInfo m = gt.MakeGenericType(sysInt32).GetMethod("Catch").MakeGenericMethod(sysSingle);

                    MethodBody body = m.GetMethodBody();
                    IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses;
                    Assert.Equal(1, ehs.Count);
                    ExceptionHandlingClause eh = ehs[0];
                    Assert.Equal(ExceptionHandlingClauseOptions.Clause, eh.Flags);
                    Assert.Equal(1, eh.TryOffset);
                    Assert.Equal(15, eh.TryLength);
                    Assert.Equal(16, eh.HandlerOffset);
                    Assert.Equal(16, eh.HandlerLength);
                    Assert.Throws <InvalidOperationException>(() => eh.FilterOffset);
                    Assert.Equal(et.MakeGenericType(sysInt32, sysSingle), eh.CatchType);
                }

                {
                    MethodInfo m    = gt.GetMethod("Finally");
                    MethodBody body = m.GetMethodBody();
                    IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses;
                    Assert.Equal(1, ehs.Count);
                    ExceptionHandlingClause eh = ehs[0];
                    Assert.Equal(ExceptionHandlingClauseOptions.Finally, eh.Flags);
                    Assert.Equal(1, eh.TryOffset);
                    Assert.Equal(15, eh.TryLength);
                    Assert.Equal(16, eh.HandlerOffset);
                    Assert.Equal(14, eh.HandlerLength);
                    Assert.Throws <InvalidOperationException>(() => eh.FilterOffset);
                    Assert.Throws <InvalidOperationException>(() => eh.CatchType);
                }

                {
                    MethodInfo m    = gt.GetMethod("Fault");
                    MethodBody body = m.GetMethodBody();
                    IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses;
                    Assert.Equal(1, ehs.Count);
                    ExceptionHandlingClause eh = ehs[0];
                    Assert.Equal(ExceptionHandlingClauseOptions.Fault, eh.Flags);
                    Assert.Equal(1, eh.TryOffset);
                    Assert.Equal(15, eh.TryLength);
                    Assert.Equal(16, eh.HandlerOffset);
                    Assert.Equal(14, eh.HandlerLength);
                    Assert.Throws <InvalidOperationException>(() => eh.FilterOffset);
                    Assert.Throws <InvalidOperationException>(() => eh.CatchType);
                }

                {
                    MethodInfo m    = gt.GetMethod("Filter");
                    MethodBody body = m.GetMethodBody();
                    IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses;
                    Assert.Equal(1, ehs.Count);
                    ExceptionHandlingClause eh = ehs[0];
                    Assert.Equal(ExceptionHandlingClauseOptions.Filter, eh.Flags);
                    Assert.Equal(1, eh.TryOffset);
                    Assert.Equal(15, eh.TryLength);
                    Assert.Equal(40, eh.HandlerOffset);
                    Assert.Equal(16, eh.HandlerLength);
                    Assert.Equal(16, eh.FilterOffset);
                    Assert.Throws <InvalidOperationException>(() => eh.CatchType);
                }
            }
        }
Esempio n. 3
0
        static int Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: dotnet MetadataLoadContextSample.dll <assembly path>");
                return(0);
            }

            string inputFile = args[0];

            try
            {
                //get the array of runtime assemblies
                //this will allow us to at least inspect types depending only on BCL
                string[] runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");

                //create the list of assembly paths consisting of runtime assemblies and the input file
                var paths = new List <string>(runtimeAssemblies);
                paths.Add(inputFile);

                //create MetadataLoadContext that can resolve assemblies using the created list
                var resolver = new PathAssemblyResolver(paths);
                var mlc      = new MetadataLoadContext(resolver);

                using (mlc)
                {
                    //load assembly into MetadataLoadContext
                    Assembly     assembly = mlc.LoadFromAssemblyPath(inputFile);
                    AssemblyName name     = assembly.GetName();

                    //print assembly attribute information
                    Console.WriteLine(name.Name + " has following attributes: ");

                    foreach (CustomAttributeData attr in assembly.GetCustomAttributesData())
                    {
                        try
                        {
                            Console.WriteLine(attr.AttributeType);
                        }
                        catch (FileNotFoundException ex)
                        {
                            //we are missing the required dependency assembly
                            Console.WriteLine("Error: " + ex.Message);
                        }
                    }

                    Console.WriteLine();

                    //print assembly type information
                    Console.WriteLine(name.Name + " contains following types: ");

                    foreach (TypeInfo t in assembly.GetTypes())
                    {
                        try
                        {
                            Type baseType = t.BaseType;

                            if (t.IsClass)
                            {
                                Console.Write("class ");
                            }
                            else if (t.IsValueType)
                            {
                                if (String.Equals(baseType?.FullName, "System.Enum", StringComparison.InvariantCulture))
                                {
                                    Console.Write("enum ");
                                }
                                else
                                {
                                    Console.Write("struct ");
                                }
                            }
                            else if (t.IsInterface)
                            {
                                Console.Write("interface ");
                            }

                            Console.Write(t.FullName);

                            if (t.IsClass && !String.Equals(baseType.FullName, "System.Object", StringComparison.InvariantCulture))
                            {
                                Console.Write(" : " + baseType.FullName);
                            }

                            Console.WriteLine();
                        }
                        catch (System.IO.FileNotFoundException ex)
                        {
                            //we are missing the required dependency assembly
                            Console.WriteLine("Error: " + ex.Message);
                        }
                    }
                }

                return(0);
            }
            catch (IOException ex)
            {
                Console.WriteLine("I/O error occured when trying to load assembly: ");
                Console.WriteLine(ex.ToString());
                return(1);
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine("Access denied when trying to load assembly: ");
                Console.WriteLine(ex.ToString());
                return(1);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Convert MarshalAsAttribute data into CustomAttributeData form. Returns null if the core assembly cannot be loaded or if the necessary
        /// types aren't in the core assembly.
        /// </summary>
        public static CustomAttributeData?TryComputeMarshalAsCustomAttributeData(Func <MarshalAsAttribute> marshalAsAttributeComputer, MetadataLoadContext loader)
        {
            // Make sure all the necessary framework types exist in this MetadataLoadContext's core assembly. If one doesn't, skip.
            CoreTypes ct = loader.GetAllFoundCoreTypes();

            if (ct[CoreType.String] == null ||
                ct[CoreType.Boolean] == null ||
                ct[CoreType.UnmanagedType] == null ||
                ct[CoreType.VarEnum] == null ||
                ct[CoreType.Type] == null ||
                ct[CoreType.Int16] == null ||
                ct[CoreType.Int32] == null)
            {
                return(null);
            }
            ConstructorInfo?ci = loader.TryGetMarshalAsCtor();

            if (ci == null)
            {
                return(null);
            }

            Func <CustomAttributeArguments> argumentsPromise =
                () =>
            {
                // The expensive work goes in here. It will not execute unless someone invokes the Constructor/NamedArguments properties on
                // the CustomAttributeData.

                MarshalAsAttribute ma = marshalAsAttributeComputer();

                Type attributeType = ci.DeclaringType !;

                CustomAttributeTypedArgument[]      cats = { new CustomAttributeTypedArgument(ct[CoreType.UnmanagedType] !, (int)(ma.Value)) };
Esempio n. 5
0
    public override bool Execute()
    {
        if (!File.Exists(MainAssembly))
        {
            throw new ArgumentException($"File MainAssembly='{MainAssembly}' doesn't exist.");
        }
        if (!File.Exists(MainJS))
        {
            throw new ArgumentException($"File MainJS='{MainJS}' doesn't exist.");
        }

        var paths = new List <string>();

        _assemblies = new Dictionary <string, Assembly>();

        // Collect and load assemblies used by the app
        foreach (var v in AssemblySearchPaths !)
        {
            var dir = v.ItemSpec;
            if (!Directory.Exists(dir))
            {
                throw new ArgumentException($"Directory '{dir}' doesn't exist or not a directory.");
            }
            paths.Add(dir);
        }
        _resolver = new Resolver(paths);
        var mlc = new MetadataLoadContext(_resolver, "System.Private.CoreLib");

        var mainAssembly = mlc.LoadFromAssemblyPath(MainAssembly);

        Add(mlc, mainAssembly);

        if (ExtraAssemblies != null)
        {
            foreach (var item in ExtraAssemblies)
            {
                var refAssembly = mlc.LoadFromAssemblyPath(item.ItemSpec);
                Add(mlc, refAssembly);
            }
        }

        // Create app
        Directory.CreateDirectory(AppDir !);
        Directory.CreateDirectory(Path.Join(AppDir, "managed"));
        foreach (var assembly in _assemblies !.Values)
        {
            File.Copy(assembly.Location, Path.Join(AppDir, "managed", Path.GetFileName(assembly.Location)), true);
        }
        foreach (var f in new string[] { "dotnet.wasm", "dotnet.js", "dotnet.timezones.blat" })
        {
            File.Copy(Path.Join(MicrosoftNetCoreAppRuntimePackDir, "native", f), Path.Join(AppDir, f), true);
        }
        File.Copy(MainJS !, Path.Join(AppDir, "runtime.js"), true);

        var filesToMap = new Dictionary <string, List <string> >();

        if (FilesToIncludeInFileSystem != null)
        {
            string supportFilesDir = Path.Join(AppDir, "supportFiles");
            Directory.CreateDirectory(supportFilesDir);

            foreach (var item in FilesToIncludeInFileSystem)
            {
                string?targetPath = item.GetMetadata("TargetPath");
                if (string.IsNullOrEmpty(targetPath))
                {
                    targetPath = Path.GetFileName(item.ItemSpec);
                }

                // We normalize paths from `\` to `/` as MSBuild items could use `\`.
                targetPath = targetPath.Replace('\\', '/');

                string?directory = Path.GetDirectoryName(targetPath);

                if (!string.IsNullOrEmpty(directory))
                {
                    Directory.CreateDirectory(Path.Join(supportFilesDir, directory));
                }
                else
                {
                    directory = "/";
                }

                File.Copy(item.ItemSpec, Path.Join(supportFilesDir, targetPath), true);

                if (filesToMap.TryGetValue(directory, out List <string>?files))
                {
                    files.Add(Path.GetFileName(targetPath));
                }
                else
                {
                    files = new List <string>();
                    files.Add(Path.GetFileName(targetPath));
                    filesToMap[directory] = files;
                }
            }
        }

        using (var sw = File.CreateText(Path.Join(AppDir, "mono-config.js")))
        {
            sw.WriteLine("config = {");
            sw.WriteLine("\tvfs_prefix: \"managed\",");
            sw.WriteLine("\tdeploy_prefix: \"managed\",");
            sw.WriteLine("\tenable_debugging: 0,");
            sw.WriteLine("\tassembly_list: [");
            foreach (var assembly in _assemblies.Values)
            {
                sw.Write("\t\t\"" + Path.GetFileName(assembly.Location) + "\"");
                sw.WriteLine(",");
            }
            sw.WriteLine("\t],");
            sw.WriteLine("\tfiles_to_map: [");
            foreach (KeyValuePair <string, List <string> > keyValuePair in filesToMap)
            {
                sw.WriteLine("\t{");
                sw.WriteLine($"\t\tdirectory: \"{keyValuePair.Key}\",");
                sw.WriteLine("\t\tfiles: [");
                foreach (string file in keyValuePair.Value)
                {
                    sw.WriteLine($"\t\t\t\"{file}\",");
                }
                sw.WriteLine("\t\t],");
                sw.WriteLine("\t},");
            }
            sw.WriteLine("\t],");
            sw.WriteLine("}");
        }

        using (var sw = File.CreateText(Path.Join(AppDir, "run-v8.sh")))
        {
            sw.WriteLine("v8 --expose_wasm runtime.js -- --run " + Path.GetFileName(MainAssembly) + " $*");
        }

        return(true);
    }
Esempio n. 6
0
        public void CompareMemoryNormal()
        {
            List <string> originals = new();
            Dictionary <ulong, string> hashDictionary = new();

            hashDictionary.EnsureCapacity(500_000);

            var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
            var paths             = new List <string>(runtimeAssemblies);
            var resolver          = new PathAssemblyResolver(paths);
            var mlc = new MetadataLoadContext(resolver);

            var before = GC.GetTotalMemory(true);

            Assembly assembly;

            using (mlc)
            {
                assembly         = mlc.LoadFromAssemblyPath("WolvenKit.Common.dll");
                using var stream = assembly.GetManifestResourceStream(s_used);

                // read KARK header
                var oodleCompression = stream.ReadStruct <uint>();
                if (oodleCompression != Oodle.KARK)
                {
                    throw new DecompressionException($"Incorrect hash file.");
                }

                var outputsize = stream.ReadStruct <uint>();

                // read the rest of the stream
                var outputbuffer = new byte[outputsize];
                var inbuffer     = stream.ToByteArray(true);
                Oodle.Decompress(inbuffer, outputbuffer);


                using (var ms = new MemoryStream(outputbuffer))
                    using (var sr = new StreamReader(ms))
                    {
                        string line;
                        while ((line = sr.ReadLine()) != null)
                        {
                            var hash = FNV1A64HashAlgorithm.HashString(line);

                            if (hashDictionary.ContainsKey(hash))
                            {
                                continue;
                            }
                            hashDictionary.Add(hash, line);
                        }
                    }
            }

            var    after = GC.GetTotalMemory(true);
            double diff  = after - before;

            Console.WriteLine($"Memory: {diff.ToString()}");

            // compare
            var failed = 0;

            foreach (var s in originals)
            {
                var hash = FNV1A64HashAlgorithm.HashString(s);

                var gottenString = hashDictionary[hash].ToString();
                if (!gottenString.Equals(s))
                {
                    failed++;
                }
            }
        }
Esempio n. 7
0
        public void Execute(GeneratorExecutionContext context)
        {
            if (context.SyntaxReceiver is not SyntaxReceiver receiver)
            {
                // nothing to do yet
                return;
            }

            // For debugging
            // System.Diagnostics.Debugger.Launch();

            var metadataLoadContext = new MetadataLoadContext(context.Compilation);
            var assembly            = metadataLoadContext.MainAssembly;
            var uControllerAssembly = metadataLoadContext.LoadFromAssemblyName("uController");

            var models = new List <HttpModel>();

            var endpointRouteBuilderType = context.Compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Routing.IEndpointRouteBuilder");

            foreach (var(memberAccess, handlerType) in receiver.MapHandlers)
            {
                var semanticModel = context.Compilation.GetSemanticModel(memberAccess.Expression.SyntaxTree);
                var typeInfo      = semanticModel.GetTypeInfo(memberAccess.Expression);

                if (!SymbolEqualityComparer.Default.Equals(typeInfo.Type, endpointRouteBuilderType))
                {
                    continue;
                }

                semanticModel = context.Compilation.GetSemanticModel(handlerType.SyntaxTree);
                typeInfo      = semanticModel.GetTypeInfo(handlerType);

                var type  = assembly.GetType(typeInfo.Type.ToDisplayString());
                var model = HttpModel.FromType(type, uControllerAssembly);
                models.Add(model);
            }

            int number         = 0;
            var sb             = new StringBuilder();
            var formattedTypes = new HashSet <string>();

            foreach (var(invocation, argument) in receiver.MapActions)
            {
                var           types  = new List <string>();
                IMethodSymbol method = default;

                var semanticModel = context.Compilation.GetSemanticModel(invocation.SyntaxTree);

                switch (argument)
                {
                case IdentifierNameSyntax identifierName:
                {
                    var si = semanticModel.GetSymbolInfo(identifierName);
                    if (si.CandidateReason == CandidateReason.OverloadResolutionFailure)
                    {
                        // We need to generate the method
                        method = si.CandidateSymbols.SingleOrDefault() as IMethodSymbol;
                    }
                }
                break;

                case ParenthesizedLambdaExpressionSyntax lambda:
                {
                    var si = semanticModel.GetSymbolInfo(lambda);
                    method = si.Symbol as IMethodSymbol;
                }
                break;

                default:
                    continue;
                }

                if (method == null)
                {
                    continue;
                }

                foreach (var p in method.Parameters)
                {
                    types.Add(p.Type.ToDisplayString());
                }

                types.Add(method.ReturnType.ToDisplayString());

                var formattedTypeArgs = string.Join(",", types);

                if (!formattedTypes.Add(formattedTypeArgs))
                {
                    continue;
                }

                formattedTypeArgs = method.ReturnsVoid ? string.Join(",", types.Take(types.Count - 1)) : formattedTypeArgs;
                var delegateType = method.ReturnsVoid ? "System.Action" : "System.Func";

                var text = @$ "        public static void MapAction(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, {delegateType}<{formattedTypeArgs}> callback)
        {{
            
        }}
";
                sb.Append(text);
                number++;
            }

            var mapActionsText = $@"
namespace Microsoft.AspNetCore.Routing
{{
    public static class MapActionsExtensions
    {{
{sb}
    }}
}}";

            context.AddSource($"MapActionsExtensions", SourceText.From(mapActionsText, Encoding.UTF8));

            foreach (var model in models)
            {
                var gen        = new CodeGenerator(model, metadataLoadContext);
                var rawSource  = gen.Generate();
                var sourceText = SourceText.From(rawSource, Encoding.UTF8);

                // For debugging
                //var comp = context.Compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(sourceText));
                //var diagnosrics = comp.GetDiagnostics();

                context.AddSource(model.HandlerType.Name + "RouteExtensions", sourceText);

                //if (gen.FromBodyTypes.Any())
                //{
                //    var jsonGenerator = new JsonCodeGenerator(metadataLoadContext, model.HandlerType.Namespace);
                //    var generatedConverters = jsonGenerator.Generate(gen.FromBodyTypes, out var helperSource);
                //}
            }
        }
        public static void ResolveToAssemblyNameCombinations()
        {
            using (TempDirectory dir = new TempDirectory())
                using (TempFile core = new TempFile(Path.Combine(dir.Path, TestData.s_PhonyCoreAssemblySimpleName), TestData.s_PhonyCoreAssemblyImage))
                    using (TempFile tf1 = new TempFile(Path.Combine(dir.Path, TestData.s_SimpleVersionedShortName), TestData.s_SimpleSignedVersioned100Image))
                    {
                        var resolver = new PathAssemblyResolver(new string[] { core.Path, tf1.Path });

                        using (MetadataLoadContext lc = new MetadataLoadContext(resolver, TestData.s_PhonyCoreAssemblySimpleName))
                        {
                            Assert.Equal(1, lc.GetAssemblies().Count());

                            Assembly assembly = lc.LoadFromAssemblyName(TestData.s_SimpleVersionedShortName);
                            Assert.NotNull(assembly);

                            // Name

                            {
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(TestData.s_SimpleVersionedShortName.ToUpper());
                                Assert.NotNull(assemblyAgain);
                            }

                            AssemblyName assemblyName = new AssemblyName(TestData.s_SimpleVersionedShortName);

                            // Version

                            {
                                assemblyName.Version = new Version(999, 998);
                                lc.LoadFromAssemblyName(assemblyName);
                                Assert.Equal(2, lc.GetAssemblies().Count());
                            }

                            {
                                assemblyName.Version = null;
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName);
                                Assert.Same(assembly, assemblyAgain);
                            }

                            {
                                assemblyName.Version = new Version(0, 0, 0, 0);
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName);
                                Assert.Same(assembly, assemblyAgain);
                            }

                            {
                                assemblyName.Version = assembly.GetName().Version;
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName);
                                Assert.Same(assembly, assemblyAgain);
                            }

                            // CultureName; match not required

                            {
                                assemblyName.CultureName = "en";
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName);
                                Assert.Same(assembly, assemblyAgain);
                            }

                            {
                                assemblyName.CultureName = "";
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName);
                                Assert.Same(assembly, assemblyAgain);
                            }

                            {
                                assemblyName.CultureName = null;
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName);
                                Assert.Same(assembly, assemblyAgain);
                            }

                            assemblyName.CultureName = assembly.GetName().CultureName;

                            // PublicKeyToken

                            assemblyName.SetPublicKeyToken(new byte[] { 1 });
                            Assert.Throws <FileNotFoundException>(() => lc.LoadFromAssemblyName(assemblyName));

                            {
                                assemblyName.SetPublicKeyToken(null);
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName);
                                Assert.Same(assembly, assemblyAgain);
                            }

                            {
                                assemblyName.SetPublicKeyToken(Array.Empty <byte>());
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName);
                                Assert.Same(assembly, assemblyAgain);
                            }

                            {
                                assemblyName.SetPublicKeyToken(assembly.GetName().GetPublicKeyToken());
                                Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName);
                                Assert.Same(assembly, assemblyAgain);
                            }

                            // None of the above should have affected the number of loaded assemblies.
                            Assert.Equal(2, lc.GetAssemblies().Count());
                        }
                    }
        }
 /// <summary>
 /// The binding algorithm. This method is called when an Assembly is to be returned from a given AssemblyName.
 /// This occurs when MetadataLoadContext.LoadAssemblyByName() is called or when a Type from one assembly has a
 /// dependency on another assembly.
 ///
 /// It should use MetadataLoadContext.LoadFromStream(), LoadFromAssemblyPath()
 /// or LoadFromByteArray() to load the requested assembly and return it.
 /// </summary>
 ///<remarks>
 /// To indicate the failure to find an assembly, the handler should return null rather than throwing an exception. Returning null commits
 /// the failure so that future attempts to load that name will fail without re-invoking the handler.
 ///
 /// If the handler throws an exception, the exception will be passed through to the application that invoked the operation that triggered
 /// the binding. The MetadataLoadContext will not catch it and no binding will occur.
 ///
 /// The handler will generally not be called more than once for the same name, unless two threads race to load the same assembly.
 /// Even in that case, one result will win and be atomically bound to the name.
 ///
 /// The MetadataLoadContext intentionally performs no ref-def matching on the returned assembly as what constitutes a ref-def match is a policy.
 /// It is also the kind of arbitrary restriction that MetadataLoadContext strives to avoid.
 ///
 /// The MetadataLoadContext cannot consume assemblies from other MetadataLoadContexts or other type providers (such as the underlying runtime's own Reflection system.)
 /// If a handler returns such an assembly, the MetadataLoadContext throws a FileLoadException.
 /// </remarks>
 public abstract Assembly Resolve(MetadataLoadContext context, AssemblyName assemblyName);
Esempio n. 10
0
    public override bool Execute()
    {
        if (!File.Exists(MainAssembly))
        {
            throw new ArgumentException($"File MainAssembly='{MainAssembly}' doesn't exist.");
        }
        if (!File.Exists(MainJS))
        {
            throw new ArgumentException($"File MainJS='{MainJS}' doesn't exist.");
        }

        var paths = new List <string> ();

        Assemblies = new Dictionary <string, Assembly> ();

        // Collect and load assemblies used by the app
        foreach (var v in AssemblySearchPaths !)
        {
            var dir = v.ItemSpec;
            if (!Directory.Exists(dir))
            {
                throw new ArgumentException($"Directory '{dir}' doesn't exist or not a directory.");
            }
            paths.Add(dir);
        }
        Resolver = new Resolver(paths);
        var mlc = new MetadataLoadContext(Resolver, "System.Private.CoreLib");

        var mainAssembly = mlc.LoadFromAssemblyPath(MainAssembly);

        Add(mlc, mainAssembly);

        if (ExtraAssemblies != null)
        {
            foreach (var item in ExtraAssemblies)
            {
                var refAssembly = mlc.LoadFromAssemblyPath(item.ItemSpec);
                Add(mlc, refAssembly);
            }
        }

        // Create app
        Directory.CreateDirectory(AppDir !);
        Directory.CreateDirectory(Path.Join(AppDir, "managed"));
        foreach (var assembly in Assemblies !.Values)
        {
            File.Copy(assembly.Location, Path.Join(AppDir, "managed", Path.GetFileName(assembly.Location)), true);
        }
        foreach (var f in new string [] { "dotnet.wasm", "dotnet.js" })
        {
            File.Copy(Path.Join(RuntimePackDir, "native", "wasm", "release", f), Path.Join(AppDir, f), true);
        }
        File.Copy(MainJS !, Path.Join(AppDir, Path.GetFileName(MainJS !)), true);

        using (var sw = File.CreateText(Path.Join(AppDir, "mono-config.js"))) {
            sw.WriteLine("config = {");
            sw.WriteLine("\tvfs_prefix: \"managed\",");
            sw.WriteLine("\tdeploy_prefix: \"managed\",");
            sw.WriteLine("\tenable_debugging: 0,");
            sw.WriteLine("\tfile_list: [");
            foreach (var assembly in Assemblies.Values)
            {
                sw.Write("\"" + Path.GetFileName(assembly.Location) + "\"");
                sw.Write(", ");
            }
            sw.WriteLine("],");
            sw.WriteLine("}");
        }

        using (var sw = File.CreateText(Path.Join(AppDir, "run-v8.sh"))) {
            sw.WriteLine("v8 --expose_wasm runtime.js -- --enable-gc --run " + Path.GetFileName(MainAssembly) + " $*");
        }

        return(true);
    }
Esempio n. 11
0
    public override bool Execute()
    {
        if (!File.Exists(MainAssembly))
        {
            throw new ArgumentException($"File MainAssembly='{MainAssembly}' doesn't exist.");
        }
        if (!File.Exists(MainJS))
        {
            throw new ArgumentException($"File MainJS='{MainJS}' doesn't exist.");
        }

        var paths = new List <string>();

        _assemblies = new Dictionary <string, Assembly>();

        // Collect and load assemblies used by the app
        foreach (var v in AssemblySearchPaths !)
        {
            var dir = v.ItemSpec;
            if (!Directory.Exists(dir))
            {
                throw new ArgumentException($"Directory '{dir}' doesn't exist or not a directory.");
            }
            paths.Add(dir);
        }
        _resolver = new Resolver(paths);
        var mlc = new MetadataLoadContext(_resolver, "System.Private.CoreLib");

        var mainAssembly = mlc.LoadFromAssemblyPath(MainAssembly);

        Add(mlc, mainAssembly);

        if (ExtraAssemblies != null)
        {
            foreach (var item in ExtraAssemblies)
            {
                var refAssembly = mlc.LoadFromAssemblyPath(item.ItemSpec);
                Add(mlc, refAssembly);
            }
        }

        // Create app
        Directory.CreateDirectory(AppDir !);
        Directory.CreateDirectory(Path.Join(AppDir, "managed"));
        foreach (var assembly in _assemblies !.Values)
        {
            File.Copy(assembly.Location, Path.Join(AppDir, "managed", Path.GetFileName(assembly.Location)), true);
        }
        foreach (var f in new string[] { "dotnet.wasm", "dotnet.js", "dotnet.timezones.blat", "icudt.dat" })
        {
            File.Copy(Path.Join(MicrosoftNetCoreAppRuntimePackDir, "native", f), Path.Join(AppDir, f), true);
        }
        File.Copy(MainJS !, Path.Join(AppDir, "runtime.js"), true);

        using (var sw = File.CreateText(Path.Join(AppDir, "mono-config.js")))
        {
            sw.WriteLine("config = {");
            sw.WriteLine("\tassembly_root: \"managed\",");
            sw.WriteLine("\tenable_debugging: 0,");
            sw.WriteLine("\tassets: [");

            foreach (var assembly in _assemblies.Values)
            {
                sw.WriteLine($"\t\t{{ behavior: \"assembly\", name: \"{Path.GetFileName(assembly.Location)}\" }},");
            }

            if (FilesToIncludeInFileSystem != null)
            {
                string supportFilesDir = Path.Join(AppDir, "supportFiles");
                Directory.CreateDirectory(supportFilesDir);

                var i = 0;
                foreach (var item in FilesToIncludeInFileSystem)
                {
                    string?targetPath = item.GetMetadata("TargetPath");
                    if (string.IsNullOrEmpty(targetPath))
                    {
                        targetPath = Path.GetFileName(item.ItemSpec);
                    }

                    // We normalize paths from `\` to `/` as MSBuild items could use `\`.
                    targetPath = targetPath.Replace('\\', '/');

                    var generatedFileName = $"{i++}_{Path.GetFileName(item.ItemSpec)}";

                    File.Copy(item.ItemSpec, Path.Join(supportFilesDir, generatedFileName), true);

                    var actualItemName = "supportFiles/" + generatedFileName;

                    sw.WriteLine("\t\t{");
                    sw.WriteLine("\t\t\tbehavior: \"vfs\",");
                    sw.WriteLine($"\t\t\tname: \"{actualItemName}\",");
                    sw.WriteLine($"\t\t\tvirtual_path: \"{targetPath}\",");
                    sw.WriteLine("\t\t},");
                }
            }

            var enableRemote  = (RemoteSources != null) && (RemoteSources !.Length > 0);
            var sEnableRemote = enableRemote ? "true" : "false";

            sw.WriteLine($"\t\t{{ behavior: \"icu\", name: \"icudt.dat\", load_remote: {sEnableRemote} }},");

            sw.WriteLine("\t],");

            if (enableRemote)
            {
                sw.WriteLine("\tremote_sources: [");
                foreach (var source in RemoteSources !)
                {
                    sw.WriteLine("\t\t\"" + source.ItemSpec + "\", ");
                }
                sw.WriteLine("\t],");
            }

            sw.WriteLine("};");
        }

        using (var sw = File.CreateText(Path.Join(AppDir, "run-v8.sh")))
        {
            sw.WriteLine("v8 --expose_wasm runtime.js -- --run " + Path.GetFileName(MainAssembly) + " $*");
        }

        return(true);
    }
Esempio n. 12
0
 void Add(MetadataLoadContext mlc, Assembly assembly)
 {
     Assemblies ![assembly.GetName().Name !] = assembly;
Esempio n. 13
0
        private bool LoadAllDlls()
        {
            try
            {
                var matcher = new Matcher();
                foreach (var pattern in _config.DllPatterns)
                {
                    matcher.AddInclude(pattern.Trim());
                }

                var loadedPaths = new List <string>();
                var assemblies  = new List <(Assembly Assembly, string XmlCommentsFile)>();
                var result      = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(_config.BasePath)));

                var addedDlls = new List <string>();
                var dllPaths  = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll").ToList();

                foreach (var dll in result.Files)
                {
                    var fullPath = Path.Join(_config.BasePath, dll.Path);
                    var fileName = Path.GetFileName(fullPath);
                    if (!addedDlls.Contains(fileName))
                    {
                        dllPaths.Add(fullPath);
                        addedDlls.Add(fileName);
                    }
                }

                var resolver = new CustomMetadataAssemblyResolver(new PathAssemblyResolver(dllPaths));
                var mlc      = new MetadataLoadContext(resolver);

                foreach (var dll in result.Files)
                {
                    if (!dll.Path.EndsWith(".dll"))
                    {
                        Console.WriteLine($"The file {dll.Path} matched the pattern but is not a dll, skipping");
                    }
                    else
                    {
                        var fullPath = Path.Join(_config.BasePath, dll.Path);
                        if (loadedPaths.Contains(fullPath))
                        {
                            continue;
                        }

                        loadedPaths.Add(fullPath);

                        try
                        {
                            var assembly = mlc.LoadFromAssemblyPath(fullPath);

                            var xmlCommentsFilePath = Path.ChangeExtension(fullPath, ".xml");
                            if (!File.Exists(xmlCommentsFilePath))
                            {
                                xmlCommentsFilePath = null;
                            }

                            if (!assemblies.Contains((assembly, xmlCommentsFilePath)))
                            {
                                assemblies.Add((assembly, xmlCommentsFilePath));
                            }
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Could not load dll file " + fullPath + ", skipping...");
                        }
                    }
                }

                if (!assemblies.Any())
                {
                    Console.Error.WriteLine($"No dlls were found matching the pattern {string.Join(", ", _config.DllPatterns)}");
                    return(false);
                }

                _generatorContext = new GeneratorContext(assemblies);

                return(true);
            }
            catch (ReflectionTypeLoadException ex)
            {
                Console.Error.WriteLine($"Error loading one or more types when opening the dll files in pattern {string.Join(", ", _config.DllPatterns)}");
                foreach (var lex in ex.LoaderExceptions)
                {
                    Console.Error.Write(lex.ToString());
                }
                return(false);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Unable to open the dll files in pattern {string.Join(", ", _config.DllPatterns)}: {ex.Message}");
                return(false);
            }
        }
Esempio n. 14
0
        private bool IsPluginAssembly(string assemblyPath)
        {
            using (Stream stream = File.OpenRead(assemblyPath))
                using (var reader = new PEReader(stream))
                {
                    if (!reader.HasMetadata)
                    {
                        return(false);
                    }

                    if (_options.TypeFinderCriterias?.Any() != true)
                    {
                        // If there are no resolvers, assume that each DLL is a plugin
                        return(true);
                    }

                    var runtimeDirectory  = RuntimeEnvironment.GetRuntimeDirectory();
                    var runtimeAssemblies = Directory.GetFiles(runtimeDirectory, "*.dll");
                    var paths             = new List <string>(runtimeAssemblies)
                    {
                        assemblyPath
                    };

                    if (_options.PluginLoadContextOptions.AdditionalRuntimePaths?.Any() == true)
                    {
                        foreach (var additionalRuntimePath in _options.PluginLoadContextOptions.AdditionalRuntimePaths)
                        {
                            var dlls = Directory.GetFiles(additionalRuntimePath, "*.dll");
                            paths.AddRange(dlls);
                        }
                    }

                    if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Always)
                    {
                        var hostApplicationPath = Environment.CurrentDirectory;
                        var hostDlls            = Directory.GetFiles(hostApplicationPath, "*.dll", SearchOption.AllDirectories);

                        paths.AddRange(hostDlls);

                        AddSharedFrameworkDlls(hostApplicationPath, runtimeDirectory, paths);
                    }
                    else if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Never)
                    {
                        var pluginPath       = Path.GetDirectoryName(assemblyPath);
                        var dllsInPluginPath = Directory.GetFiles(pluginPath, "*.dll", SearchOption.AllDirectories);

                        paths.AddRange(dllsInPluginPath);
                    }
                    else if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Selected)
                    {
                        foreach (var hostApplicationAssembly in _options.PluginLoadContextOptions.HostApplicationAssemblies)
                        {
                            var assembly = Assembly.Load(hostApplicationAssembly);
                            paths.Add(assembly.Location);
                        }
                    }

                    paths = paths.Distinct().ToList();

                    var resolver = new PathAssemblyResolver(paths);

                    // We use the metadata (readonly) versions of the assemblies before loading them
                    using (var metadataContext = new MetadataLoadContext(resolver))
                    {
                        var metadataPluginLoadContext = new MetadataTypeFindingContext(metadataContext);
                        var readonlyAssembly          = metadataContext.LoadFromAssemblyPath(assemblyPath);

                        var typeFinder = new TypeFinder();

                        foreach (var finderCriteria in _options.TypeFinderCriterias)
                        {
                            var typesFound = typeFinder.Find(finderCriteria.Value, readonlyAssembly, metadataPluginLoadContext);

                            if (typesFound?.Any() == true)
                            {
                                return(true);
                            }
                        }
                    }
                }

            return(false);
        }
Esempio n. 15
0
        private bool IsPluginAssembly(string assemblyPath)
        {
            using (Stream stream = File.OpenRead(assemblyPath))
                using (var reader = new PEReader(stream))
                {
                    if (!reader.HasMetadata)
                    {
                        return(false);
                    }

                    if (_options.TypeFinderOptions?.TypeFinderCriterias?.Any() != true)
                    {
                        // If there are no type finders configured, assume that each DLL is a plugin
                        return(true);
                    }

                    var runtimeDirectory  = RuntimeEnvironment.GetRuntimeDirectory();
                    var runtimeAssemblies = Directory.GetFiles(runtimeDirectory, "*.dll");
                    var paths             = new List <string>(runtimeAssemblies)
                    {
                        assemblyPath
                    };

                    if (_options.PluginLoadContextOptions.AdditionalRuntimePaths?.Any() == true)
                    {
                        foreach (var additionalRuntimePath in _options.PluginLoadContextOptions.AdditionalRuntimePaths)
                        {
                            var dlls = Directory.GetFiles(additionalRuntimePath, "*.dll");
                            paths.AddRange(dlls);
                        }
                    }

                    if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Always)
                    {
                        var hostApplicationPath = Environment.CurrentDirectory;
                        var hostDlls            = Directory.GetFiles(hostApplicationPath, "*.dll", SearchOption.AllDirectories);

                        paths.AddRange(hostDlls);

                        AddSharedFrameworkDlls(hostApplicationPath, runtimeDirectory, paths);
                    }
                    else if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Never)
                    {
                        var pluginPath       = Path.GetDirectoryName(assemblyPath);
                        var dllsInPluginPath = Directory.GetFiles(pluginPath, "*.dll", SearchOption.AllDirectories);

                        paths.AddRange(dllsInPluginPath);
                    }
                    else if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Selected)
                    {
                        foreach (var hostApplicationAssembly in _options.PluginLoadContextOptions.HostApplicationAssemblies)
                        {
                            var assembly = Assembly.Load(hostApplicationAssembly);
                            paths.Add(assembly.Location);
                        }
                    }

                    paths = paths.Distinct().ToList();

                    // Also make sure to include only one dll of each. If same dll is found from multiple locations, use the first found dll and remove the others.
                    var duplicateDlls = paths.Select(x => new { FullPath = x, FileName = Path.GetFileName(x) }).GroupBy(x => x.FileName)
                                        .Where(x => x.Count() > 1)
                                        .ToList();

                    var removed = new List <string>();

                    foreach (var duplicateDll in duplicateDlls)
                    {
                        foreach (var duplicateDllPath in duplicateDll.Skip(1))
                        {
                            removed.Add(duplicateDllPath.FullPath);
                        }
                    }

                    foreach (var re in removed)
                    {
                        paths.Remove(re);
                    }

                    var resolver = new PathAssemblyResolver(paths);

                    // We use the metadata (readonly) versions of the assemblies before loading them
                    using (var metadataContext = new MetadataLoadContext(resolver))
                    {
                        var metadataPluginLoadContext = new MetadataTypeFindingContext(metadataContext);
                        var readonlyAssembly          = metadataContext.LoadFromAssemblyPath(assemblyPath);

                        var typeFinder = new TypeFinder();

                        foreach (var finderCriteria in _options.TypeFinderOptions.TypeFinderCriterias)
                        {
                            var typesFound = typeFinder.Find(finderCriteria, readonlyAssembly, metadataPluginLoadContext);

                            if (typesFound?.Any() == true)
                            {
                                return(true);
                            }
                        }
                    }
                }

            return(false);
        }
        private void AddLoadedAssemblies(AssemblyInformation assembly, Assembly?msAssembly, MetadataLoadContext context, string parentAssemblyName, string baseDirectory)
        {
            if (msAssembly != null && (assembly.IsLocalAssembly || Settings.GetSetting <bool>(SettingKeys.ScanGlobalManaged)))
            {
                assembly.Links.AddRange(msAssembly.GetReferencedAssemblies().Select(x => GetAssemblyLink(context, x, parentAssemblyName, baseDirectory)));

                if (Settings.GetSetting <bool>(SettingKeys.ScanDllImport))
                {
                    dllImportReferences[assembly.FullName] = msAssembly.GetDllImportReferences().ToList();
                }
            }
        }
Esempio n. 17
0
        public void CompareMemorySAsciiStringChunked()
        {
            List <string> originals = new();
            Dictionary <ulong, uint[]>      hashDictionary = new();
            Dictionary <SAsciiString, uint> helperDict     = new(new MyComparer());

            hashDictionary.EnsureCapacity(500_000);


            var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
            var paths             = new List <string>(runtimeAssemblies);
            var resolver          = new PathAssemblyResolver(paths);
            var mlc = new MetadataLoadContext(resolver);

            var before = GC.GetTotalMemory(true);

            Assembly assembly;

            using (mlc)
            {
                assembly         = mlc.LoadFromAssemblyPath("WolvenKit.Common.dll");
                using var stream = assembly.GetManifestResourceStream(s_used);

                // read KARK header
                var oodleCompression = stream.ReadStruct <uint>();
                if (oodleCompression != Oodle.KARK)
                {
                    throw new DecompressionException($"Incorrect hash file.");
                }

                var outputsize = stream.ReadStruct <uint>();

                // read the rest of the stream
                var outputbuffer = new byte[outputsize];
                var inbuffer     = stream.ToByteArray(true);
                Oodle.Decompress(inbuffer, outputbuffer);


                using (var ms = new MemoryStream(outputbuffer))
                    using (var sr = new StreamReader(ms))
                    {
                        string line;
                        while ((line = sr.ReadLine()) != null)
                        {
                            originals.Add(line);

                            var hash      = FNV1A64HashAlgorithm.HashString(line);
                            var pathParts = line.Split('\\');
                            hashDictionary.Add(hash, new uint[pathParts.Length]);


                            for (var i = 0; i < pathParts.Length; i++)
                            {
                                var  s = pathParts[i];
                                var  a = new SAsciiString(s);
                                uint idx;

                                if (helperDict.ContainsKey(a))
                                {
                                    idx = helperDict[a];
                                }
                                else
                                {
                                    //chunks.Add(a);
                                    var count = helperDict.Count;
                                    helperDict.Add(a, (uint)count);
                                    idx = (uint)count;
                                }

                                hashDictionary[hash][i] = idx;
                            }
                        }
                    }
            }

            var    after = GC.GetTotalMemory(true);
            double diff  = after - before;

            Console.WriteLine($"Memory: {diff.ToString()}");



            // compare
            var failed = 0;
            var keys   = helperDict.Keys.ToList();

            foreach (var s in originals)
            {
                var hash = FNV1A64HashAlgorithm.HashString(s);

                var gottenString = "";
                for (var i = 0; i < hashDictionary[hash].Length; i++)
                {
                    var idx = hashDictionary[hash][i];
                    gottenString += keys[(int)idx].ToString();
                    if (i < hashDictionary[hash].Length - 1)
                    {
                        gottenString += Path.DirectorySeparatorChar;
                    }
                }

                if (!gottenString.Equals(s))
                {
                    failed++;
                }
            }

            Assert.AreEqual(0, failed);
        }
        private static (AssemblyInformation assembly, Assembly?msAssembly) CreateManagedAssemblyInformation(MetadataLoadContext context, AssemblyName assemblyName, string baseDirectory, string extension = "dll")
        {
            var assemblyPath = FilePathProvider.GetAssemblyPath($"{assemblyName.Name}.{extension}", baseDirectory);

            Assembly?assembly = null;

            try
            {
                assembly = File.Exists(assemblyPath) ? context.LoadFromAssemblyPath(assemblyPath ?? string.Empty) : context.LoadFromAssemblyName(assemblyName);
            }
            catch
            {
                // In this case, assembly is not found
            }

            var assemblyShortName = assemblyName.Name ?? string.Empty;
            var assemblyVersion   = assemblyName.Version?.ToString() ?? string.Empty;

            var info = new AssemblyInformation(assemblyShortName, assembly?.GetName().Version?.ToString() ?? assemblyVersion, assemblyPath)
            {
                IsLocalAssembly = assemblyPath != null || assembly == null,
                AssemblyName    = assemblyName.FullName,
                IsResolved      = assembly != null
            };

            info.EnhancePropertiesWithFile();
            info.EnhanceProperties(assembly?.GetModules().First());

            return(info, assembly);
        }
Esempio n. 19
0
 public CodeGenerator(HttpModel model, MetadataLoadContext metadataLoadContext)
 {
     _model = model;
     _metadataLoadContext = metadataLoadContext;
 }
Esempio n. 20
0
 // Guards ToString() implementations. Sample usage:
 //
 //    public sealed override string ToString() => Loader.GetDisposedString() ?? <your real ToString() code>;"
 //
 public static string GetDisposedString(this MetadataLoadContext loader) => loader.IsDisposed ? SR.MetadataLoadContextDisposed : null;
        /// <summary>
        /// GetModules will create an ObservableCollection of type Module to organize
        /// the information from the dll file and its related .xml file.
        /// </summary>
        /// <param name="dllFiles">A string array containing the names of all dll files in the DllDirectory.</param>
        /// <returns>Returns an collection of Module objects.</returns>
        public ObservableCollection <DataObjects.Module> GetModules(string[] dllFiles)
        {
            if (string.IsNullOrEmpty(DllDirectory))
            {
                MessageBox.Show(@"The Directory Path Cannot Be Empty");
                return(null);
            }

            ObservableCollection <DataObjects.Module> modules =
                new ObservableCollection <DataObjects.Module>();
            Assembly assembly;

            // add all the possible referenced assemblies
            string[] runtimeEnvirnmentFiles = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), @"*.dll");

            var paths = new List <string>(runtimeEnvirnmentFiles);

            paths.AddRange(dllFiles);

            var resolver       = new PathAssemblyResolver(paths);
            var metaDataLoader = new MetadataLoadContext(resolver);

            foreach (var dllFile in dllFiles)
            {
                DllFilePath = dllFile;
                DescriptionRetriever.DllFilePath = dllFile;
                assembly = metaDataLoader.LoadFromAssemblyPath(dllFile);

                Type[] types = null;

                try
                {
                    types = assembly.GetTypes();
                }
                catch (ReflectionTypeLoadException ex)
                {
                    types = ex.Types.Where(t => t != null).ToArray();
                }

                int someNum = 0;
                foreach (var type in types)
                {
                    someNum++;

                    if (type != null)
                    {
                        CurrentTypeName         = type.Name;
                        PercentOfAssemblyLoaded = ((double)someNum / (double)types.Length) * 100;

                        Debug.WriteLine("Adding Module: " + type.Name + " From " + assembly.FullName);
                        DataObjects.Module tempModule = GetSingleModule(type);

                        // Add all non-null modules
                        if (tempModule != null)
                        {
                            modules.Add(tempModule);
                        }
                    }
                }
            }

            // Return an alphabetized collection of the found modules.
            return(new ObservableCollection <DataObjects.Module>(
                       modules.ToList().OrderBy(mod => mod.Name)));
        }
 public MetadataTypeFindingContext(MetadataLoadContext metadataLoadContext)
 {
     _metadataLoadContext = metadataLoadContext;
 }
Esempio n. 23
0
    int Main3(string [] args)
    {
        bool          show_help = false;
        bool          zero_copy = false;
        string        basedir = null;
        string        tmpdir = null;
        string        ns = null;
        bool          delete_temp = true, debug = false;
        bool          unsafef          = true;
        bool          external         = false;
        bool          public_mode      = true;
        bool          nostdlib         = false;
        bool?         inline_selectors = null;
        List <string> sources;
        var           resources          = new List <string> ();
        var           linkwith           = new List <string> ();
        var           api_sources        = new List <string> ();
        var           core_sources       = new List <string> ();
        var           extra_sources      = new List <string> ();
        var           defines            = new List <string> ();
        string        generate_file_list = null;
        bool          process_enums      = false;
        string        compiler           = "/Library/Frameworks/Mono.framework/Versions/Current/bin/csc";

        ErrorHelper.ClearWarningLevels();

        var os = new OptionSet()
        {
            { "h|?|help", "Displays the help", v => show_help = true },
            { "a", "Include alpha bindings (Obsolete).", v => {}, true },
            { "outdir=", "Sets the output directory for the temporary binding files", v => { basedir = v; } },
            { "o|out=", "Sets the name of the output library", v => outfile = v },
            { "tmpdir=", "Sets the working directory for temp files", v => { tmpdir = v; delete_temp = false; } },
            { "debug", "Generates a debugging build of the binding", v => debug = true },
            { "sourceonly=", "Only generates the source", v => generate_file_list = v },
            { "ns=", "Sets the namespace for storing helper classes", v => ns = v },
            { "unsafe", "Sets the unsafe flag for the build", v => unsafef = true },
            { "core", "Use this to build product assemblies", v => BindThirdPartyLibrary = false },
            { "r|reference=", "Adds a reference", v => references.Add(v) },
            { "lib=", "Adds the directory to the search path for the compiler", v => libs.Add(v) },
            { "compiler=", "Sets the compiler to use (Obsolete) ", v => compiler = v, true },
            { "sdk=", "Sets the .NET SDK to use (Obsolete)", v => {}, true },
            { "new-style", "Build for Unified (Obsolete).", v => { Console.WriteLine("The --new-style option is obsolete and ignored."); }, true },
            { "d=", "Defines a symbol", v => defines.Add(v) },
            { "api=", "Adds a API definition source file", v => api_sources.Add(v) },
            { "s=", "Adds a source file required to build the API", v => core_sources.Add(v) },
            { "q", "Quiet", v => ErrorHelper.Verbosity-- },
            { "v", "Sets verbose mode", v => ErrorHelper.Verbosity++ },
            { "x=", "Adds the specified file to the build, used after the core files are compiled", v => extra_sources.Add(v) },
            { "e", "Generates smaller classes that can not be subclassed (previously called 'external mode')", v => external = true },
            { "p", "Sets private mode", v => public_mode = false },
            { "baselib=", "Sets the base library", v => baselibdll = v },
            { "attributelib=", "Sets the attribute library", v => attributedll = v },
            { "use-zero-copy", v => zero_copy = true },
            { "nostdlib", "Does not reference mscorlib.dll library", l => nostdlib = true },
            { "no-mono-path", "Launches compiler with empty MONO_PATH", l => { }, true },
            { "native-exception-marshalling", "Enable the marshalling support for Objective-C exceptions", (v) => { /* no-op */ } },
            { "inline-selectors:", "If Selector.GetHandle is inlined and does not need to be cached (enabled by default in Xamarin.iOS, disabled in Xamarin.Mac)",
              v => inline_selectors = string.Equals("true", v, StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(v) },
            { "process-enums", "Process enums as bindings, not external, types.", v => process_enums = true },
            { "link-with=,", "Link with a native library {0:FILE} to the binding, embedded as a resource named {1:ID}",
              (path, id) => {
                  if (path == null || path.Length == 0)
                  {
                      throw new Exception("-link-with=FILE,ID requires a filename.");
                  }

                  if (id == null || id.Length == 0)
                  {
                      id = Path.GetFileName(path);
                  }

                  if (linkwith.Contains(id))
                  {
                      throw new Exception("-link-with=FILE,ID cannot assign the same resource id to multiple libraries.");
                  }

                  resources.Add(string.Format("-res:{0},{1}", path, id));
                  linkwith.Add(id);
              } },
            { "unified-full-profile", "Launches compiler pointing to XM Full Profile", l => { /* no-op*/ }, true },
            { "unified-mobile-profile", "Launches compiler pointing to XM Mobile Profile", l => { /* no-op*/ }, true },
            { "target-framework=", "Specify target framework to use. Always required, and the currently supported values are: 'Xamarin.iOS,v1.0', 'Xamarin.TVOS,v1.0', 'Xamarin.WatchOS,v1.0', 'XamMac,v1.0', 'Xamarin.Mac,Version=v2.0,Profile=Mobile', 'Xamarin.Mac,Version=v4.5,Profile=Full' and 'Xamarin.Mac,Version=v4.5,Profile=System')", v => SetTargetFramework(v) },
            { "warnaserror:", "An optional comma-separated list of warning codes that should be reported as errors (if no warnings are specified all warnings are reported as errors).", v => {
                  try {
                      if (!string.IsNullOrEmpty(v))
                      {
                          foreach (var code in v.Split(new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                          {
                              ErrorHelper.SetWarningLevel(ErrorHelper.WarningLevel.Error, int.Parse(code));
                          }
                      }
                      else
                      {
                          ErrorHelper.SetWarningLevel(ErrorHelper.WarningLevel.Error);
                      }
                  } catch (Exception ex) {
                      throw ErrorHelper.CreateError(26, ex.Message);
                  }
              } },
            { "nowarn:", "An optional comma-separated list of warning codes to ignore (if no warnings are specified all warnings are ignored).", v => {
                  try {
                      if (!string.IsNullOrEmpty(v))
                      {
                          foreach (var code in v.Split(new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                          {
                              ErrorHelper.SetWarningLevel(ErrorHelper.WarningLevel.Disable, int.Parse(code));
                          }
                      }
                      else
                      {
                          ErrorHelper.SetWarningLevel(ErrorHelper.WarningLevel.Disable);
                      }
                  } catch (Exception ex) {
                      throw ErrorHelper.CreateError(26, ex.Message);
                  }
              } },
            new Mono.Options.ResponseFileSource(),
        };

        try {
            sources = os.Parse(args);
        } catch (Exception e) {
            Console.Error.WriteLine("{0}: {1}", ToolName, e.Message);
            Console.Error.WriteLine("see {0} --help for more information", ToolName);
            return(1);
        }

        if (show_help)
        {
            ShowHelp(os);
            return(0);
        }

        if (!target_framework.HasValue)
        {
            throw ErrorHelper.CreateError(86);
        }

        switch (target_framework.Value.Platform)
        {
        case ApplePlatform.iOS:
            CurrentPlatform = PlatformName.iOS;
            nostdlib        = true;
            if (string.IsNullOrEmpty(baselibdll))
            {
                baselibdll = Path.Combine(GetSDKRoot(), "lib/mono/Xamarin.iOS/Xamarin.iOS.dll");
            }
            if (!IsDotNet)
            {
                references.Add("Facades/System.Drawing.Common");
                ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.iOS", references);
            }
            break;

        case ApplePlatform.TVOS:
            CurrentPlatform = PlatformName.TvOS;
            nostdlib        = true;
            if (string.IsNullOrEmpty(baselibdll))
            {
                baselibdll = Path.Combine(GetSDKRoot(), "lib/mono/Xamarin.TVOS/Xamarin.TVOS.dll");
            }
            if (!IsDotNet)
            {
                references.Add("Facades/System.Drawing.Common");
                ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.TVOS", references);
            }
            break;

        case ApplePlatform.WatchOS:
            CurrentPlatform = PlatformName.WatchOS;
            nostdlib        = true;
            if (string.IsNullOrEmpty(baselibdll))
            {
                baselibdll = Path.Combine(GetSDKRoot(), "lib/mono/Xamarin.WatchOS/Xamarin.WatchOS.dll");
            }
            if (!IsDotNet)
            {
                references.Add("Facades/System.Drawing.Common");
                ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.WatchOS", references);
            }
            break;

        case ApplePlatform.MacCatalyst:
            CurrentPlatform = PlatformName.MacCatalyst;
            nostdlib        = true;
            if (string.IsNullOrEmpty(baselibdll))
            {
                baselibdll = Path.Combine(GetSDKRoot(), "lib/mono/Xamarin.MacCatalyst/Xamarin.MacCatalyst.dll");
            }
            if (!IsDotNet)
            {
                // references.Add ("Facades/System.Drawing.Common");
                ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.MacCatalyst", references);
            }
            break;

        case ApplePlatform.MacOSX:
            CurrentPlatform = PlatformName.MacOSX;
            nostdlib        = true;
            if (string.IsNullOrEmpty(baselibdll))
            {
                if (target_framework == TargetFramework.Xamarin_Mac_2_0_Mobile)
                {
                    baselibdll = Path.Combine(GetSDKRoot(), "lib", "reference", "mobile", "Xamarin.Mac.dll");
                }
                else if (target_framework == TargetFramework.Xamarin_Mac_4_5_Full || target_framework == TargetFramework.Xamarin_Mac_4_5_System)
                {
                    baselibdll = Path.Combine(GetSDKRoot(), "lib", "reference", "full", "Xamarin.Mac.dll");
                }
                else
                {
                    throw ErrorHelper.CreateError(1053, target_framework);
                }
            }
            if (target_framework == TargetFramework.Xamarin_Mac_2_0_Mobile)
            {
                skipSystemDrawing = true;
                references.Add("Facades/System.Drawing.Common");
                ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.Mac", references);
            }
            else if (target_framework == TargetFramework.Xamarin_Mac_4_5_Full)
            {
                skipSystemDrawing = true;
                references.Add("Facades/System.Drawing.Common");
                ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/4.5", references);
            }
            else if (target_framework == TargetFramework.Xamarin_Mac_4_5_System)
            {
                skipSystemDrawing = false;
                ReferenceFixer.FixSDKReferences("/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5", references, forceSystemDrawing: true);
            }
            else if (target_framework == TargetFramework.DotNet_5_0_macOS)
            {
                skipSystemDrawing = false;
            }
            else
            {
                throw ErrorHelper.CreateError(1053, target_framework);
            }

            break;

        default:
            throw ErrorHelper.CreateError(1053, target_framework);
        }

        if (sources.Count > 0)
        {
            api_sources.Insert(0, sources [0]);
            for (int i = 1; i < sources.Count; i++)
            {
                core_sources.Insert(i - 1, sources [i]);
            }
        }

        if (api_sources.Count == 0)
        {
            Console.WriteLine("Error: no api file provided");
            ShowHelp(os);
            return(1);
        }

        if (tmpdir == null)
        {
            tmpdir = GetWorkDir();
        }

        string firstApiDefinitionName = Path.GetFileNameWithoutExtension(api_sources [0]);

        firstApiDefinitionName = firstApiDefinitionName.Replace('-', '_');          // This is not exhaustive, but common.
        if (outfile == null)
        {
            outfile = firstApiDefinitionName + ".dll";
        }

        var refs  = references.Select((v) => "-r:" + v);
        var paths = libs.Select((v) => "-lib:" + v);

        try {
            var tmpass = Path.Combine(tmpdir, "temp.dll");

            // -nowarn:436 is to avoid conflicts in definitions between core.dll and the sources
            // Keep source files at the end of the command line - csc will create TWO assemblies if any sources preceed the -out parameter
            var cargs = new List <string> ();

            cargs.Add("-debug");
            cargs.Add("-unsafe");
            cargs.Add("-target:library");
            cargs.Add("-nowarn:436");
            cargs.Add("-out:" + tmpass);
            cargs.Add("-r:" + GetAttributeLibraryPath());
            cargs.AddRange(refs);
            if (unsafef)
            {
                cargs.Add("-unsafe");
            }
            cargs.Add("-r:" + baselibdll);
            foreach (var def in defines)
            {
                cargs.Add("-define:" + def);
            }
            cargs.AddRange(paths);
            if (nostdlib)
            {
                cargs.Add("-nostdlib");
                cargs.Add("-noconfig");
            }
            cargs.AddRange(api_sources);
            cargs.AddRange(core_sources);
            if (!string.IsNullOrEmpty(Path.GetDirectoryName(baselibdll)))
            {
                cargs.Add("-lib:" + Path.GetDirectoryName(baselibdll));
            }

            if (Driver.RunCommand(compiler, cargs, null, out var compile_output, true, Driver.Verbosity) != 0)
            {
                throw ErrorHelper.CreateError(2, $"{compiler} {StringUtils.FormatArguments (cargs)}\n{compile_output}".Replace("\n", "\n\t"));
            }

            universe = new MetadataLoadContext(
                new SearchPathsAssemblyResolver(
                    GetLibraryDirectories().ToArray(),
                    references.ToArray()),
                "mscorlib"
                );

            Assembly api;
            try {
                api = universe.LoadFromAssemblyPath(tmpass);
            } catch (Exception e) {
                if (Driver.Verbosity > 0)
                {
                    Console.WriteLine(e);
                }

                Console.Error.WriteLine("Error loading API definition from {0}", tmpass);
                return(1);
            }

            Assembly baselib;
            try {
                baselib = universe.LoadFromAssemblyPath(baselibdll);
            } catch (Exception e) {
                if (Driver.Verbosity > 0)
                {
                    Console.WriteLine(e);
                }

                Console.Error.WriteLine("Error loading base library {0}", baselibdll);
                return(1);
            }

            AttributeManager = new AttributeManager(this);
            Frameworks       = new Frameworks(CurrentPlatform);

            // Explicitly load our attribute library so that IKVM doesn't try (and fail) to find it.
            universe.LoadFromAssemblyPath(GetAttributeLibraryPath());

            TypeManager.Initialize(this, api, universe.CoreAssembly, baselib);

            foreach (var linkWith in AttributeManager.GetCustomAttributes <LinkWithAttribute> (api))
            {
                if (!linkwith.Contains(linkWith.LibraryName))
                {
                    Console.Error.WriteLine("Missing native library {0}, please use `--link-with' to specify the path to this library.", linkWith.LibraryName);
                    return(1);
                }
            }

            foreach (var r in references)
            {
                // IKVM has a bug where it doesn't correctly compare assemblies, which means it
                // can end up loading the same assembly (in particular any System.Runtime whose
                // version > 4.0, but likely others as well) more than once. This is bad, because
                // we compare types based on reference equality, which breaks down when there are
                // multiple instances of the same type.
                //
                // So just don't ask IKVM to load assemblies that have already been loaded.
                var fn         = Path.GetFileNameWithoutExtension(r);
                var assemblies = universe.GetAssemblies();
                if (assemblies.Any((v) => v.GetName().Name == fn))
                {
                    continue;
                }

                if (File.Exists(r))
                {
                    try {
                        universe.LoadFromAssemblyPath(r);
                    } catch (Exception ex) {
                        ErrorHelper.Warning(1104, r, ex.Message);
                    }
                }
            }

            var types = new List <Type> ();
            var strong_dictionaries = new List <Type> ();
            foreach (var t in api.GetTypes())
            {
                if ((process_enums && t.IsEnum) ||
                    AttributeManager.HasAttribute <BaseTypeAttribute> (t) ||
                    AttributeManager.HasAttribute <ProtocolAttribute> (t) ||
                    AttributeManager.HasAttribute <StaticAttribute> (t) ||
                    AttributeManager.HasAttribute <PartialAttribute> (t))
                {
                    types.Add(t);
                }
                if (AttributeManager.HasAttribute <StrongDictionaryAttribute> (t))
                {
                    strong_dictionaries.Add(t);
                }
            }

            var nsManager = new NamespaceManager(
                this,
                ns == null ? firstApiDefinitionName : ns,
                skipSystemDrawing
                );

            var g = new Generator(this, nsManager, public_mode, external, debug, types.ToArray(), strong_dictionaries.ToArray())
            {
                BaseDir         = basedir != null ? basedir : tmpdir,
                ZeroCopyStrings = zero_copy,
                InlineSelectors = inline_selectors ?? (CurrentPlatform != PlatformName.MacOSX),
            };

            g.Go();

            if (generate_file_list != null)
            {
                using (var f = File.CreateText(generate_file_list)){
                    foreach (var x in g.GeneratedFiles.OrderBy((v) => v))
                    {
                        f.WriteLine(x);
                    }
                }
                return(0);
            }

            cargs.Clear();
            if (unsafef)
            {
                cargs.Add("-unsafe");
            }
            cargs.Add("-target:library");
            cargs.Add("-out:" + outfile);
            foreach (var def in defines)
            {
                cargs.Add("-define:" + def);
            }
            cargs.AddRange(g.GeneratedFiles);
            cargs.AddRange(core_sources);
            cargs.AddRange(extra_sources);
            cargs.AddRange(refs);
            cargs.Add("-r:" + baselibdll);
            cargs.AddRange(resources);
            if (nostdlib)
            {
                cargs.Add("-nostdlib");
                cargs.Add("-noconfig");
            }
            if (!string.IsNullOrEmpty(Path.GetDirectoryName(baselibdll)))
            {
                cargs.Add("-lib:" + Path.GetDirectoryName(baselibdll));
            }

            if (Driver.RunCommand(compiler, cargs, null, out var generated_compile_output, true, Driver.Verbosity) != 0)
            {
                throw ErrorHelper.CreateError(1000, $"{compiler} {StringUtils.FormatArguments (cargs)}\n{generated_compile_output}".Replace("\n", "\n\t"));
            }
        } finally {
            if (delete_temp)
            {
                Directory.Delete(tmpdir, true);
            }
        }
        return(0);
    }
Esempio n. 24
0
        public static PrimitiveTypeCode GetEnumUnderlyingPrimitiveTypeCode(this Type enumType, MetadataLoadContext loader)
        {
            Type      type      = enumType.GetEnumUnderlyingType();
            CoreTypes coreTypes = loader.GetAllFoundCoreTypes();

            // Be careful how you compare - one or more elements of "coreTypes" can be null!
            if (type == coreTypes[CoreType.Boolean])
            {
                return(PrimitiveTypeCode.Boolean);
            }
            if (type == coreTypes[CoreType.Char])
            {
                return(PrimitiveTypeCode.Char);
            }
            if (type == coreTypes[CoreType.Byte])
            {
                return(PrimitiveTypeCode.Byte);
            }
            if (type == coreTypes[CoreType.Int16])
            {
                return(PrimitiveTypeCode.Int16);
            }
            if (type == coreTypes[CoreType.Int32])
            {
                return(PrimitiveTypeCode.Int32);
            }
            if (type == coreTypes[CoreType.Int64])
            {
                return(PrimitiveTypeCode.Int64);
            }
            if (type == coreTypes[CoreType.IntPtr])
            {
                return(PrimitiveTypeCode.IntPtr);
            }
            if (type == coreTypes[CoreType.SByte])
            {
                return(PrimitiveTypeCode.SByte);
            }
            if (type == coreTypes[CoreType.UInt16])
            {
                return(PrimitiveTypeCode.UInt16);
            }
            if (type == coreTypes[CoreType.UInt32])
            {
                return(PrimitiveTypeCode.UInt32);
            }
            if (type == coreTypes[CoreType.UInt64])
            {
                return(PrimitiveTypeCode.UInt64);
            }
            if (type == coreTypes[CoreType.UIntPtr])
            {
                return(PrimitiveTypeCode.UIntPtr);
            }

            throw new BadImageFormatException(SR.Format(SR.UnexpectedUnderlyingEnumType, enumType, type));
        }
Esempio n. 25
0
 internal DefaultBinder(MetadataLoadContext loader)
 {
     _loader     = loader;
     _objectType = loader.TryGetCoreType(CoreType.Object);
 }
Esempio n. 26
0
        public static void TestMethodBody1()
        {
            using (MetadataLoadContext lc = new MetadataLoadContext(new CoreMetadataAssemblyResolver(), "mscorlib"))
            {
                Assembly coreAssembly = lc.LoadFromStream(TestUtils.CreateStreamForCoreAssembly());
                Assembly a            = lc.LoadFromByteArray(TestData.s_AssemblyWithMethodBodyImage);

                Type       nonsense = a.GetType("Nonsense`1", throwOnError: true);
                Type       theT     = nonsense.GetTypeInfo().GenericTypeParameters[0];
                MethodInfo m        = nonsense.GetMethod("Foo");
                Type       theM     = m.GetGenericArguments()[0];
                MethodBody mb       = m.GetMethodBody();
                byte[]     il       = mb.GetILAsByteArray();
                Assert.Equal <byte>(TestData.s_AssemblyWithMethodBodyILBytes, il);
                Assert.Equal(4, mb.MaxStackSize);
                Assert.True(mb.InitLocals);
                Assert.Equal(0x11000001, mb.LocalSignatureMetadataToken);

                IList <LocalVariableInfo> lvis = mb.LocalVariables;
                Assert.Equal(10, lvis.Count);

                Assert.Equal(0, lvis[0].LocalIndex);
                Assert.False(lvis[0].IsPinned);
                Assert.Equal(coreAssembly.GetType("System.Single", throwOnError: true), lvis[0].LocalType);

                Assert.Equal(1, lvis[1].LocalIndex);
                Assert.False(lvis[1].IsPinned);
                Assert.Equal(coreAssembly.GetType("System.Double", throwOnError: true), lvis[1].LocalType);

                Assert.Equal(2, lvis[2].LocalIndex);
                Assert.False(lvis[2].IsPinned);
                Assert.Equal(theT, lvis[2].LocalType);

                Assert.Equal(3, lvis[3].LocalIndex);
                Assert.False(lvis[3].IsPinned);
                Assert.Equal(theT.MakeArrayType(), lvis[3].LocalType);

                Assert.Equal(4, lvis[4].LocalIndex);
                Assert.False(lvis[4].IsPinned);
                Assert.Equal(coreAssembly.GetType("System.Collections.Generic.IList`1", throwOnError: true).MakeGenericType(theM), lvis[4].LocalType);

                Assert.Equal(5, lvis[5].LocalIndex);
                Assert.False(lvis[5].IsPinned);
                Assert.Equal(coreAssembly.GetType("System.String", throwOnError: true), lvis[5].LocalType);

                Assert.Equal(6, lvis[6].LocalIndex);
                Assert.False(lvis[6].IsPinned);
                Assert.Equal(coreAssembly.GetType("System.Int32", throwOnError: true).MakeArrayType(), lvis[6].LocalType);

                Assert.Equal(7, lvis[7].LocalIndex);
                Assert.True(lvis[7].IsPinned);
                Assert.Equal(coreAssembly.GetType("System.Int32", throwOnError: true).MakeByRefType(), lvis[7].LocalType);

                Assert.Equal(8, lvis[8].LocalIndex);
                Assert.False(lvis[8].IsPinned);
                Assert.Equal(coreAssembly.GetType("System.Int32", throwOnError: true).MakeArrayType(), lvis[8].LocalType);

                Assert.Equal(9, lvis[9].LocalIndex);
                Assert.False(lvis[9].IsPinned);
                Assert.Equal(coreAssembly.GetType("System.Boolean", throwOnError: true), lvis[9].LocalType);

                IList <ExceptionHandlingClause> ehcs = mb.ExceptionHandlingClauses;
                Assert.Equal(2, ehcs.Count);

                ExceptionHandlingClause ehc = ehcs[0];
                Assert.Equal(ExceptionHandlingClauseOptions.Finally, ehc.Flags);
                Assert.Equal(97, ehc.TryOffset);
                Assert.Equal(41, ehc.TryLength);
                Assert.Equal(138, ehc.HandlerOffset);
                Assert.Equal(5, ehc.HandlerLength);

                ehc = ehcs[1];
                Assert.Equal(ExceptionHandlingClauseOptions.Filter, ehc.Flags);
                Assert.Equal(88, ehc.TryOffset);
                Assert.Equal(58, ehc.TryLength);
                Assert.Equal(172, ehc.HandlerOffset);
                Assert.Equal(16, ehc.HandlerLength);
                Assert.Equal(146, ehc.FilterOffset);
            }
        }