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); } }
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); } } }
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); } }
/// <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)) };
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); }
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++; } } }
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);
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); }
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); }
void Add(MetadataLoadContext mlc, Assembly assembly) { Assemblies ![assembly.GetName().Name !] = assembly;
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); } }
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); }
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(); } } }
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); }
public CodeGenerator(HttpModel model, MetadataLoadContext metadataLoadContext) { _model = model; _metadataLoadContext = metadataLoadContext; }
// 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; }
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); }
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)); }
internal DefaultBinder(MetadataLoadContext loader) { _loader = loader; _objectType = loader.TryGetCoreType(CoreType.Object); }
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); } }