From d575f10471929f2e2b547fb75f1080a608daa067 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Fri, 7 Aug 2020 09:30:15 -0400 Subject: [PATCH] [Wasm] Ensure monovm_initialize is called on startup and address other startup items (#39446) This PR addresses: - Calling monovm_initialize matches how other mono platforms init themselves (Fixes https://github.com/dotnet/runtime/issues/39074) - Set the entry assembly (Fixes https://github.com/dotnet/runtime/issues/38994) - Make sure the assembly location is set to empty for assemblies that are loaded from memory (Fixes https://github.com/dotnet/runtime/issues/39650) --- .../TestUtilities/System/AssemblyPathHelper.cs | 21 ++++++++++++++ .../tests/TestUtilities/TestUtilities.csproj | 1 + .../CodeDom/Compiler/CompilerResultsTests.cs | 2 +- .../src/System/Configuration/ClientConfigPaths.cs | 28 ++++++++++++++---- .../tests/StackTraceSymbolsTests.cs | 3 +- .../System.Diagnostics.StackTrace.Tests.csproj | 4 +++ .../Decoding/CustomAttributeDecoderTests.cs | 2 +- .../Metadata/Decoding/SignatureDecoderTests.cs | 8 +++--- .../src/TestUtils/CoreMetadataAssemblyResolver.cs | 3 ++ .../src/TestUtils/TestUtils.JittedRuntimes.cs | 23 +++++++++------ .../tests/src/TestUtils/TestUtils.cs | 7 ++++- .../MetadataLoadContext/PathAssemblyResolver.cs | 9 +----- .../src/Tests/MetadataLoadContext/Scenarios.cs | 10 +++---- .../src/Tests/RestrictedApis/RestrictedApis.cs | 2 +- .../tests/src/Tests/Type/TypeTests.cs | 4 +-- .../System.Reflection/tests/AssemblyNameTests.cs | 2 +- .../System.Reflection/tests/AssemblyTests.cs | 20 +++++++------ .../tests/RuntimeIdentifierTests.cs | 1 - .../tests/SatelliteAssemblies.cs | 6 ++-- .../tests/System/Reflection/ModuleTests.cs | 10 ++++++- src/mono/mono/metadata/appdomain.h | 3 ++ src/mono/mono/metadata/assembly.c | 10 +++++++ src/mono/mono/metadata/domain-internals.h | 3 -- .../src/System/Reflection/RuntimeAssembly.cs | 33 ++++++++-------------- src/mono/wasm/runtime/driver.c | 12 ++++++++ 25 files changed, 148 insertions(+), 79 deletions(-) create mode 100644 src/libraries/Common/tests/TestUtilities/System/AssemblyPathHelper.cs diff --git a/src/libraries/Common/tests/TestUtilities/System/AssemblyPathHelper.cs b/src/libraries/Common/tests/TestUtilities/System/AssemblyPathHelper.cs new file mode 100644 index 0000000..10b3ee0 --- /dev/null +++ b/src/libraries/Common/tests/TestUtilities/System/AssemblyPathHelper.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Reflection; + +namespace System +{ + public static class AssemblyPathHelper + { + public static string GetAssemblyLocation(Assembly a) + { + // Note, in Browser, assemblies are loaded from memory and in that case, Assembly.Location will return an empty + // string. For these tests, the assemblies will also be available in the VFS, so just specify the assembly name + // plus extension. + return (PlatformDetection.IsNotBrowser) ? + a.Location + : "/" + a.GetName().Name + ".dll"; + } + } +} \ No newline at end of file diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj index 5646078..978aff5 100644 --- a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj @@ -22,6 +22,7 @@ + diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs index 71158fa..aa791ba 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs @@ -31,7 +31,7 @@ namespace System.CodeDom.Compiler.Tests [Fact] public void CompiledAssembly_GetWithPathToAssemblySet_ReturnsExpectedAssembly() { - var results = new CompilerResults(null) { PathToAssembly = (PlatformDetection.IsBrowser ? "/" : string.Empty) + typeof(CompilerResultsTests).Assembly.Location }; + var results = new CompilerResults(null) { PathToAssembly = AssemblyPathHelper.GetAssemblyLocation(typeof(CompilerResultsTests).Assembly) }; Assert.NotNull(results.CompiledAssembly); Assert.Equal(typeof(CompilerResultsTests).Assembly.FullName, results.CompiledAssembly.FullName); diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs index abb9737..087cb3e 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs @@ -215,22 +215,38 @@ namespace System.Configuration AssemblyName assemblyName = assembly.GetName(); Uri codeBase = new Uri(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assembly.ManifestModule.Name)); - hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName); + try + { + // Certain platforms may not have support for crypto + hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName); + } + catch (PlatformNotSupportedException) { } + if (hash != null) { typeName = StrongNameDesc; } else { - hash = IdentityHelper.GetNormalizedUriHash(codeBase); - typeName = UrlDesc; + try + { + // Certain platforms may not have support for crypto + hash = IdentityHelper.GetNormalizedUriHash(codeBase); + typeName = UrlDesc; + } + catch (PlatformNotSupportedException) { } } } else if (!string.IsNullOrEmpty(exePath)) { - // Fall back on the exe name - hash = IdentityHelper.GetStrongHashSuitableForObjectName(exePath); - typeName = PathDesc; + try + { + // Fall back on the exe name + // Certain platforms may not have support for crypto + hash = IdentityHelper.GetStrongHashSuitableForObjectName(exePath); + typeName = PathDesc; + } + catch (PlatformNotSupportedException) { } } if (!string.IsNullOrEmpty(hash)) suffix = "_" + typeName + "_" + hash; diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs index 8026935..47eb6f0 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs @@ -7,13 +7,12 @@ using Xunit; namespace System.Diagnostics.SymbolStore.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/39650", TestPlatforms.Browser)] public class StackTraceSymbolsTests { [Fact] public void StackTraceSymbolsDoNotLockFile() { - var asmPath = typeof(StackTraceSymbolsTests).Assembly.Location; + var asmPath = AssemblyPathHelper.GetAssemblyLocation(typeof(StackTraceSymbolsTests).Assembly); var pdbPath = Path.ChangeExtension(asmPath, ".pdb"); Assert.True(File.Exists(pdbPath)); diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj b/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj index 0290d84..b112648 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj +++ b/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj @@ -13,4 +13,8 @@ + + + + \ No newline at end of file diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs index 9899c09..6a14d35 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs @@ -15,7 +15,7 @@ namespace System.Reflection.Metadata.Decoding.Tests [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Type assembly name is different on .NET Framework.")] public void TestCustomAttributeDecoder() { - using (FileStream stream = File.OpenRead(typeof(HasAttributes).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(HasAttributes).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/SignatureDecoderTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/SignatureDecoderTests.cs index 9a83882..7669fbc 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/SignatureDecoderTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/SignatureDecoderTests.cs @@ -83,7 +83,7 @@ namespace System.Reflection.Metadata.Decoding.Tests [Fact] public void DecodeVarArgsDefAndRef() { - using (FileStream stream = File.OpenRead(typeof(VarArgsToDecode).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(VarArgsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader metadataReader = peReader.GetMetadataReader(); @@ -135,7 +135,7 @@ namespace System.Reflection.Metadata.Decoding.Tests [Fact] public void SimpleSignatureProviderCoverage() { - using (FileStream stream = File.OpenRead(typeof(SignaturesToDecode<>).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(SignaturesToDecode<>).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); @@ -246,7 +246,7 @@ namespace System.Reflection.Metadata.Decoding.Tests [Fact] public void PinnedAndUnpinnedLocals() { - using (FileStream stream = File.OpenRead(typeof(PinnedAndUnpinnedLocalsToDecode).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(PinnedAndUnpinnedLocalsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); @@ -285,7 +285,7 @@ namespace System.Reflection.Metadata.Decoding.Tests [Fact] public void WrongSignatureType() { - using (FileStream stream = File.OpenRead(typeof(VarArgsToDecode).GetTypeInfo().Assembly.Location)) + using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(VarArgsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/CoreMetadataAssemblyResolver.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/CoreMetadataAssemblyResolver.cs index f5a81d7..70c9806 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/CoreMetadataAssemblyResolver.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/CoreMetadataAssemblyResolver.cs @@ -1,5 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; namespace System.Reflection.Tests { @@ -22,7 +23,9 @@ namespace System.Reflection.Tests name.Equals("System.Runtime.InteropServices", StringComparison.OrdinalIgnoreCase)) { if (_coreAssembly == null) + { _coreAssembly = context.LoadFromStream(TestUtils.CreateStreamForCoreAssembly()); + } return _coreAssembly; } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs index aa98d6e..cdbd7d4 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs @@ -18,7 +18,7 @@ namespace System.Reflection.Tests Assembly assembly = type.Assembly; string location = assembly.Location; - if (location == null || location == string.Empty) + if (PlatformDetection.IsNotBrowser && (location == null || location == string.Empty)) { throw new Exception("Could not find the IL for assembly " + type.Assembly + " on disk. The most likely cause " + "is that you built the tests for a Jitted runtime but are running them on an AoT runtime."); @@ -30,9 +30,11 @@ namespace System.Reflection.Tests // The core assembly we're using might not be the one powering the runtime. Make sure we project to the core assembly the MetataLoadContext // is using. if (a == typeof(object).Assembly) - return TestMetadataLoadContext.LoadFromStream(CreateStreamForCoreAssembly()); + { + TestMetadataLoadContext.LoadFromStream(CreateStreamForCoreAssembly()); + } - return TestMetadataLoadContext.LoadFromAssemblyPath(a.Location); + return TestMetadataLoadContext.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(a)); }); Type projectedType = s_typeDict.GetOrAdd(type, (t) => projectedAssembly.GetType(t.FullName, throwOnError: true, ignoreCase: false)); @@ -50,12 +52,15 @@ namespace System.Reflection.Tests { // We need a core assembly in IL form. Since this version of this code is for Jitted platforms, the System.Private.Corelib // of the underlying runtime will do just fine. - string assumedLocationOfCoreLibrary = typeof(object).Assembly.Location; - if (assumedLocationOfCoreLibrary == null || assumedLocationOfCoreLibrary == string.Empty) + if (PlatformDetection.IsNotBrowser) { - throw new Exception("Could not find a core assembly to use for tests as 'typeof(object).Assembly.Location` returned " + - "a null or empty value. The most likely cause is that you built the tests for a Jitted runtime but are running them " + - "on an AoT runtime."); + string assumedLocationOfCoreLibrary = typeof(object).Assembly.Location; + if (assumedLocationOfCoreLibrary == null || assumedLocationOfCoreLibrary == string.Empty) + { + throw new Exception("Could not find a core assembly to use for tests as 'typeof(object).Assembly.Location` returned " + + "a null or empty value. The most likely cause is that you built the tests for a Jitted runtime but are running them " + + "on an AoT runtime."); + } } return File.OpenRead(GetPathToCoreAssembly()); @@ -63,7 +68,7 @@ namespace System.Reflection.Tests public static string GetPathToCoreAssembly() { - return typeof(object).Assembly.Location; + return AssemblyPathHelper.GetAssemblyLocation(typeof(object).Assembly); } public static string GetNameOfCoreAssembly() diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.cs index c0a4192..ac71edd 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.cs @@ -253,7 +253,12 @@ namespace System.Reflection.Tests private static readonly Lazy s_useRuntimeTypesForTests = new Lazy(() => { - if (File.Exists(Path.Combine(Path.GetDirectoryName(typeof(TestUtils).Assembly.Location), "UseRuntimeTypes.txt"))) + if (PlatformDetection.IsBrowser) + return false; + + var loc = AssemblyPathHelper.GetAssemblyLocation(typeof(TestUtils).Assembly); + + if (File.Exists(Path.Combine(loc, "UseRuntimeTypes.txt"))) { // Disable projection so that are Reflection tests run against the runtime types. This is used primarily to verify // the *test* code for correctness. diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/PathAssemblyResolver.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/PathAssemblyResolver.cs index 501e40c..464a925 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/PathAssemblyResolver.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/PathAssemblyResolver.cs @@ -60,14 +60,7 @@ namespace System.Reflection.Tests string coreAssemblyPath = TestUtils.GetPathToCoreAssembly(); // Obtain this test class - string thisAssemblyPath = typeof(MetadataLoadContextTests).Assembly.Location; - - if (PlatformDetection.IsBrowser) - { - // prepends slash as Assembly.Location only contains the file name on browser (https://github.com/dotnet/runtime/issues/39650) - thisAssemblyPath = "/" + thisAssemblyPath; - } - + string thisAssemblyPath = AssemblyPathHelper.GetAssemblyLocation(typeof(MetadataLoadContextTests).Assembly); var resolver = new PathAssemblyResolver(new string[] { coreAssemblyPath, thisAssemblyPath }); using (MetadataLoadContext lc = new MetadataLoadContext(resolver, TestUtils.GetNameOfCoreAssembly())) { diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/Scenarios.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/Scenarios.cs index b51651c..86561cc 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/Scenarios.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/MetadataLoadContext/Scenarios.cs @@ -16,7 +16,7 @@ namespace System.Reflection.Tests // Ensure you can do all this without resolving dependencies. using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(GenericClass1<>).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(GenericClass1<>).Assembly)); AssemblyName assemblyName = a.GetName(); Console.WriteLine(assemblyName.FullName); } @@ -28,7 +28,7 @@ namespace System.Reflection.Tests // Ensure you can do all this without resolving dependencies. using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(GenericClass1<>).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(GenericClass1<>).Assembly)); foreach (AssemblyName name in a.GetReferencedAssemblies()) { Console.WriteLine(name.FullName); @@ -44,8 +44,8 @@ namespace System.Reflection.Tests { Assembly[] candidates = { - lc.LoadFromAssemblyPath(typeof(GenericClass1<>).Assembly.Location), - lc.LoadFromAssemblyPath(typeof(object).Assembly.Location), + lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(GenericClass1<>).Assembly)), + lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(object).Assembly)), }; foreach (Assembly candidate in candidates) @@ -68,7 +68,7 @@ namespace System.Reflection.Tests // Ensure you can do all this without resolving dependencies. using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(GenericClass1<>).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(GenericClass1<>).Assembly)); foreach (TypeInfo t in a.DefinedTypes) { Console.WriteLine(t.FullName); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs index f154f09..28aea79 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs @@ -12,7 +12,7 @@ namespace System.Reflection.Tests { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(TopLevelType).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(TopLevelType).Assembly)); #pragma warning disable SYSLIB0012 Assert.Throws(() => a.CodeBase); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs index 60617d2..d14c4b8 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs @@ -523,7 +523,7 @@ namespace System.Reflection.Tests { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { - Assembly a = lc.LoadFromAssemblyPath(typeof(SampleMetadata.NS0.SameNamedType).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(SampleMetadata.NS0.SameNamedType).Assembly)); // Create big hash collisions in GetTypeCoreCache. for (int i = 0; i < 16; i++) { @@ -542,7 +542,7 @@ namespace System.Reflection.Tests using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { // Make sure the tricky corner case of a null/empty namespace is covered. - Assembly a = lc.LoadFromAssemblyPath(typeof(TopLevelType).Assembly.Location); + Assembly a = lc.LoadFromAssemblyPath(AssemblyPathHelper.GetAssemblyLocation(typeof(TopLevelType).Assembly)); Type t = a.GetType("TopLevelType", throwOnError: true, ignoreCase: false); Assert.Null(t.Namespace); Assert.Equal("TopLevelType", t.Name); diff --git a/src/libraries/System.Reflection/tests/AssemblyNameTests.cs b/src/libraries/System.Reflection/tests/AssemblyNameTests.cs index d33e010..e64b887 100644 --- a/src/libraries/System.Reflection/tests/AssemblyNameTests.cs +++ b/src/libraries/System.Reflection/tests/AssemblyNameTests.cs @@ -240,7 +240,7 @@ namespace System.Reflection.Tests } Assembly a = typeof(AssemblyNameTests).Assembly; - Assert.Equal(new AssemblyName(a.FullName).ToString(), AssemblyName.GetAssemblyName(a.Location).ToString()); + Assert.Equal(new AssemblyName(a.FullName).ToString(), AssemblyName.GetAssemblyName(AssemblyPathHelper.GetAssemblyLocation(a)).ToString()); } [Fact] diff --git a/src/libraries/System.Reflection/tests/AssemblyTests.cs b/src/libraries/System.Reflection/tests/AssemblyTests.cs index 8f7384f..e1b60d5 100644 --- a/src/libraries/System.Reflection/tests/AssemblyTests.cs +++ b/src/libraries/System.Reflection/tests/AssemblyTests.cs @@ -158,8 +158,9 @@ namespace System.Reflection.Tests AssertExtensions.Throws(null, () => typeof(AssemblyTests).Assembly.GetFile("")); Assert.Null(typeof(AssemblyTests).Assembly.GetFile("NonExistentfile.dll")); Assert.NotNull(typeof(AssemblyTests).Assembly.GetFile("System.Reflection.Tests.dll")); - if (PlatformDetection.IsNotBrowser) // see https://github.com/dotnet/runtime/issues/39650 - Assert.Equal(typeof(AssemblyTests).Assembly.GetFile("System.Reflection.Tests.dll").Name, typeof(AssemblyTests).Assembly.Location); + + string name = AssemblyPathHelper.GetAssemblyLocation(typeof(AssemblyTests).Assembly); + Assert.Equal(typeof(AssemblyTests).Assembly.GetFile("System.Reflection.Tests.dll").Name, name); } [Fact] @@ -167,8 +168,9 @@ namespace System.Reflection.Tests { Assert.NotNull(typeof(AssemblyTests).Assembly.GetFiles()); Assert.Equal(1, typeof(AssemblyTests).Assembly.GetFiles().Length); - if (PlatformDetection.IsNotBrowser) // see https://github.com/dotnet/runtime/issues/39650 - Assert.Equal(typeof(AssemblyTests).Assembly.GetFiles()[0].Name, typeof(AssemblyTests).Assembly.Location); + + string name = AssemblyPathHelper.GetAssemblyLocation(typeof(AssemblyTests).Assembly); + Assert.Equal(typeof(AssemblyTests).Assembly.GetFiles()[0].Name, name); } public static IEnumerable GetHashCode_TestData() @@ -387,7 +389,7 @@ namespace System.Reflection.Tests [Fact] public void LoadFrom_SameIdentityAsAssemblyWithDifferentPath_ReturnsEqualAssemblies() { - Assembly assembly1 = Assembly.LoadFrom(typeof(AssemblyTests).Assembly.Location); + Assembly assembly1 = Assembly.LoadFrom(AssemblyPathHelper.GetAssemblyLocation(typeof(AssemblyTests).Assembly)); Assert.Equal(assembly1, typeof(AssemblyTests).Assembly); Assembly assembly2 = Assembly.LoadFrom(LoadFromTestPath); @@ -659,7 +661,7 @@ namespace System.Reflection.Tests public void AssemblyLoadFromBytes() { Assembly assembly = typeof(AssemblyTests).Assembly; - byte[] aBytes = System.IO.File.ReadAllBytes(assembly.Location); + byte[] aBytes = System.IO.File.ReadAllBytes(AssemblyPathHelper.GetAssemblyLocation(assembly)); Assembly loadedAssembly = Assembly.Load(aBytes); Assert.NotNull(loadedAssembly); @@ -677,8 +679,8 @@ namespace System.Reflection.Tests public void AssemblyLoadFromBytesWithSymbols() { Assembly assembly = typeof(AssemblyTests).Assembly; - byte[] aBytes = System.IO.File.ReadAllBytes(assembly.Location); - byte[] symbols = System.IO.File.ReadAllBytes((System.IO.Path.ChangeExtension(assembly.Location, ".pdb"))); + byte[] aBytes = System.IO.File.ReadAllBytes(AssemblyPathHelper.GetAssemblyLocation(assembly)); + byte[] symbols = System.IO.File.ReadAllBytes((System.IO.Path.ChangeExtension(AssemblyPathHelper.GetAssemblyLocation(assembly), ".pdb"))); Assembly loadedAssembly = Assembly.Load(aBytes, symbols); Assert.NotNull(loadedAssembly); @@ -696,7 +698,7 @@ namespace System.Reflection.Tests public void AssemblyReflectionOnlyLoadFromBytes() { Assembly assembly = typeof(AssemblyTests).Assembly; - byte[] aBytes = System.IO.File.ReadAllBytes(assembly.Location); + byte[] aBytes = System.IO.File.ReadAllBytes(AssemblyPathHelper.GetAssemblyLocation(assembly)); Assert.Throws(() => Assembly.ReflectionOnlyLoad(aBytes)); } diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs index 6747714..d25b747 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs @@ -11,7 +11,6 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests public class RuntimeIdentifierTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39074", TestPlatforms.Browser)] public void VerifyOSRid() { Assert.NotNull(RuntimeInformation.RuntimeIdentifier); diff --git a/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs b/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs index 658d1f4..7851469 100644 --- a/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs +++ b/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs @@ -18,15 +18,15 @@ namespace System.Runtime.Loader.Tests public SatelliteAssembliesTestsFixture() { AssemblyLoadContext satelliteAssembliesTests = new AssemblyLoadContext("SatelliteAssembliesTests"); - var satelliteAssembliesTestsPath = (PlatformDetection.IsBrowser ? "/" : "") + typeof(SatelliteAssembliesTests).Assembly.Location; + var satelliteAssembliesTestsPath = AssemblyPathHelper.GetAssemblyLocation(typeof(SatelliteAssembliesTests).Assembly); satelliteAssembliesTests.LoadFromAssemblyPath(satelliteAssembliesTestsPath); AssemblyLoadContext referencedClassLib = new AssemblyLoadContext("ReferencedClassLib"); - var referencedClassLibPath = (PlatformDetection.IsBrowser ? "/" : "") + typeof(ReferencedClassLib.Program).Assembly.Location; + var referencedClassLibPath = AssemblyPathHelper.GetAssemblyLocation(typeof(ReferencedClassLib.Program).Assembly); referencedClassLib.LoadFromAssemblyPath(referencedClassLibPath); AssemblyLoadContext referencedClassLibNeutralIsSatellite = new AssemblyLoadContext("ReferencedClassLibNeutralIsSatellite"); - var referencedClassLibNeutralIsSatellitePath = (PlatformDetection.IsBrowser ? "/" : "") + typeof(ReferencedClassLibNeutralIsSatellite.Program).Assembly.Location; + var referencedClassLibNeutralIsSatellitePath = AssemblyPathHelper.GetAssemblyLocation(typeof(ReferencedClassLibNeutralIsSatellite.Program).Assembly); referencedClassLibNeutralIsSatellite.LoadFromAssemblyPath(referencedClassLibNeutralIsSatellitePath); new AssemblyLoadContext("Empty"); diff --git a/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs b/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs index 8f16d1d..b549471 100644 --- a/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs +++ b/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs @@ -81,7 +81,15 @@ namespace System.Reflection.Tests [Fact] public void FullyQualifiedName() { - Assert.Equal(Assembly.GetExecutingAssembly().Location, Module.FullyQualifiedName); + var loc = AssemblyPathHelper.GetAssemblyLocation(Assembly.GetExecutingAssembly()); + + // Browser will include the path (/), so strip it + if (PlatformDetection.IsBrowser && loc.Length > 1) + { + loc = loc.Substring(1); + } + + Assert.Equal(loc, Module.FullyQualifiedName); } [Fact] diff --git a/src/mono/mono/metadata/appdomain.h b/src/mono/mono/metadata/appdomain.h index ab26064..bc8a1f2 100644 --- a/src/mono/mono/metadata/appdomain.h +++ b/src/mono/mono/metadata/appdomain.h @@ -106,6 +106,9 @@ mono_domain_foreach (MonoDomainFunc func, void* user_data); MONO_API MONO_RT_EXTERNAL_ONLY MonoAssembly * mono_domain_assembly_open (MonoDomain *domain, const char *name); +MONO_API void +mono_domain_ensure_entry_assembly (MonoDomain *domain, MonoAssembly *assembly); + MONO_API mono_bool mono_domain_finalize (MonoDomain *domain, uint32_t timeout); diff --git a/src/mono/mono/metadata/assembly.c b/src/mono/mono/metadata/assembly.c index d4ea7f7..d9a9e7f 100644 --- a/src/mono/mono/metadata/assembly.c +++ b/src/mono/mono/metadata/assembly.c @@ -2501,6 +2501,16 @@ mono_assembly_open_from_bundle (MonoAssemblyLoadContext *alc, const char *filena for (i = 0; !image && bundles [i]; ++i) { if (strcmp (bundles [i]->name, is_satellite ? filename : name) == 0) { image = mono_image_open_from_data_internal (alc, (char*)bundles [i]->data, bundles [i]->size, FALSE, status, refonly, FALSE, name); +#if defined(TARGET_WASM) && defined(ENABLE_NETCORE) + /* + * Since bundled images do not exist on disk, don't give them a legit file name. + * This is the expected behavior for single file exe's. + */ + if (image->filename) + g_free (image->filename); + + image->filename = NULL; +#endif break; } } diff --git a/src/mono/mono/metadata/domain-internals.h b/src/mono/mono/metadata/domain-internals.h index 2acdd85..0985b67 100644 --- a/src/mono/mono/metadata/domain-internals.h +++ b/src/mono/mono/metadata/domain-internals.h @@ -692,9 +692,6 @@ mono_runtime_install_appctx_properties (void); gboolean mono_domain_set_fast (MonoDomain *domain, gboolean force); -void -mono_domain_ensure_entry_assembly (MonoDomain *domain, MonoAssembly *assembly); - MonoAssemblyLoadContext * mono_domain_default_alc (MonoDomain *domain); diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index 7154236..2c7616b 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -415,38 +415,29 @@ namespace System.Reflection if (name.Length == 0) throw new ArgumentException(SR.Argument_EmptyFileName); - string location = Location; - if (location != null && Path.GetFileName(location) == name) - return new FileStream(location, FileMode.Open, FileAccess.Read); - string filename = (string)GetFilesInternal(name, true); - if (filename != null) - return new FileStream(filename, FileMode.Open, FileAccess.Read); + RuntimeModule? m = (RuntimeModule?)GetModule(name); + + if (m != null) + return new FileStream(m.FullyQualifiedName, FileMode.Open, FileAccess.Read); else return null; } public override FileStream[] GetFiles(bool getResourceModules) { - string[] names = (string[])GetFilesInternal(null, getResourceModules); - if (names == null) + Module[] modules = GetModules(getResourceModules); + + if (modules.Length == 0) return Array.Empty(); - string location = Location; + FileStream[] res = new FileStream[modules.Length]; - FileStream[] res; - if (location != string.Empty) - { - res = new FileStream[names.Length + 1]; - res[0] = new FileStream(location, FileMode.Open, FileAccess.Read); - for (int i = 0; i < names.Length; ++i) - res[i + 1] = new FileStream(names[i], FileMode.Open, FileAccess.Read); - } - else + for (int i = 0; i < modules.Length; i++) { - res = new FileStream[names.Length]; - for (int i = 0; i < names.Length; ++i) - res[i] = new FileStream(names[i], FileMode.Open, FileAccess.Read); + RuntimeModule m = (RuntimeModule)modules[i]; + res[i] = new FileStream(m.FullyQualifiedName, FileMode.Open, FileAccess.Read); } + return res; } diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 8e68329..2d4498c 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -375,6 +375,16 @@ mono_wasm_load_runtime (const char *unused, int debug_level) monoeg_g_setenv ("COMPlus_DebugWriteToStdErr", "1", 0); #endif + const char *appctx_keys[2]; + appctx_keys [0] = "APP_CONTEXT_BASE_DIRECTORY"; + appctx_keys [1] = "RUNTIME_IDENTIFIER"; + + const char *appctx_values[2]; + appctx_values [0] = "/"; + appctx_values [1] = "browser-wasm"; + + monovm_initialize (2, appctx_keys, appctx_values); + mini_parse_debug_option ("top-runtime-invoke-unhandled"); mono_dl_fallback_register (wasm_dl_load, wasm_dl_symbol, NULL, NULL); @@ -514,6 +524,8 @@ mono_wasm_assembly_get_entry_point (MonoAssembly *assembly) uint32_t entry = mono_image_get_entry_point (image); if (!entry) return NULL; + + mono_domain_ensure_entry_assembly (root_domain, assembly); return mono_get_method (image, entry, NULL); } -- 2.7.4