Skip to content

Commit

Permalink
Switch AOT compilers to use AssemblyNameInfo (dotnet#102036)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotas authored and Ruihan-Yin committed May 30, 2024
1 parent 1d5c137 commit 3ab6767
Show file tree
Hide file tree
Showing 41 changed files with 207 additions and 221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,10 @@ private static RuntimeAssemblyName CreateRuntimeAssemblyNameFromMetadata(
ByteCollection publicKeyOrToken,
global::Internal.Metadata.NativeFormat.AssemblyFlags assemblyFlags)
{
AssemblyNameFlags assemblyNameFlags = AssemblyNameFlags.None;
if (0 != (assemblyFlags & global::Internal.Metadata.NativeFormat.AssemblyFlags.PublicKey))
assemblyNameFlags |= AssemblyNameFlags.PublicKey;
if (0 != (assemblyFlags & global::Internal.Metadata.NativeFormat.AssemblyFlags.Retargetable))
assemblyNameFlags |= AssemblyNameFlags.Retargetable;
int contentType = ((int)assemblyFlags) & 0x00000E00;
assemblyNameFlags |= (AssemblyNameFlags)contentType;
AssemblyNameFlags assemblyNameFlags = (AssemblyNameFlags)(assemblyFlags & (
global::Internal.Metadata.NativeFormat.AssemblyFlags.PublicKey |
global::Internal.Metadata.NativeFormat.AssemblyFlags.Retargetable |
global::Internal.Metadata.NativeFormat.AssemblyFlags.ContentTypeMask));

ArrayBuilder<byte> keyOrTokenArrayBuilder = default;
foreach (byte b in publicKeyOrToken)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Internal.TypeSystem
{
// Dummy implementation of AssemlyNameInfo for runtime type system
public abstract class AssemblyNameInfo
{
public abstract string FullName { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@
<Compile Include="Internal\Runtime\TypeLoader\TypeSystemContextFactory.cs" />
<Compile Include="Internal\Runtime\TypeLoader\TypeSystemExtensions.cs" />
<Compile Include="Internal\Runtime\TypeLoader\WellKnownTypeExtensions.cs" />
<Compile Include="Internal\TypeSystem\AssemblyNameInfo.Dummy.cs" />
<Compile Include="Internal\TypeSystem\ArrayMethod.Runtime.cs" />
<Compile Include="Internal\TypeSystem\CanonTypes.Runtime.cs" />
<Compile Include="Internal\TypeSystem\DefType.Runtime.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public IReadOnlyDictionary<string, string> ReferenceFilePaths
set;
}

public override ModuleDesc ResolveAssembly(System.Reflection.AssemblyName name, bool throwIfNotFound)
public override ModuleDesc ResolveAssembly(AssemblyNameInfo name, bool throwIfNotFound)
{
// TODO: catch typesystem BadImageFormatException and throw a new one that also captures the
// assembly name that caused the failure. (Along with the reason, which makes this rather annoying).
Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/tools/Common/Compiler/ProcessLinkerXmlBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ protected virtual void ProcessXml(bool ignoreResource)

protected virtual AllowedAssemblies AllowedAssemblySelector { get => _owningModule != null ? AllowedAssemblies.ContainingAssembly : AllowedAssemblies.AnyAssembly; }

private bool ShouldProcessAllAssemblies(XPathNavigator nav, [NotNullWhen(false)] out AssemblyName? assemblyName)
private bool ShouldProcessAllAssemblies(XPathNavigator nav, [NotNullWhen(false)] out AssemblyNameInfo? assemblyName)
{
assemblyName = null;
if (GetFullName(nav) == AllAssembliesFullName)
Expand All @@ -147,7 +147,7 @@ protected virtual void ProcessAssemblies(XPathNavigator nav)

// Errors for invalid assembly names should show up even if this element will be
// skipped due to feature conditions.
bool processAllAssemblies = ShouldProcessAllAssemblies(assemblyNav, out AssemblyName? name);
bool processAllAssemblies = ShouldProcessAllAssemblies(assemblyNav, out AssemblyNameInfo? name);
if (processAllAssemblies && !_globalAttributeRemoval)
{
#if !READYTORUN
Expand Down Expand Up @@ -175,7 +175,7 @@ protected virtual void ProcessAssemblies(XPathNavigator nav)
if (_owningModule.Assembly.GetName().Name != name!.Name)
{
#if !READYTORUN
LogWarning(assemblyNav, DiagnosticId.AssemblyWithEmbeddedXmlApplyToAnotherAssembly, _owningModule.Assembly.GetName().Name ?? "", name.ToString());
LogWarning(assemblyNav, DiagnosticId.AssemblyWithEmbeddedXmlApplyToAnotherAssembly, _owningModule.Assembly.GetName().Name, name.FullName);
#endif
continue;
}
Expand All @@ -188,7 +188,7 @@ protected virtual void ProcessAssemblies(XPathNavigator nav)
if (assembly == null)
{
#if !READYTORUN
LogWarning(assemblyNav, DiagnosticId.XmlCouldNotResolveAssembly, name!.Name ?? "");
LogWarning(assemblyNav, DiagnosticId.XmlCouldNotResolveAssembly, name!.Name);
#endif
continue;
}
Expand Down Expand Up @@ -499,9 +499,9 @@ protected virtual void ProcessProperty(TypeDesc type, XPathNavigator nav, object

protected virtual void ProcessProperty(TypeDesc type, PropertyPseudoDesc property, XPathNavigator nav, object? customData, bool fromSignature) { }

protected virtual AssemblyName GetAssemblyName(XPathNavigator nav)
protected virtual AssemblyNameInfo GetAssemblyName(XPathNavigator nav)
{
return new AssemblyName(GetFullName(nav));
return AssemblyNameInfo.Parse(GetFullName(nav));
}

protected static string GetFullName(XPathNavigator nav)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

namespace Internal.Metadata.NativeFormat
{
// Internal clone of System.Reflection.AssemblyFlags from System.Reflection.Metadata
[Flags]
#if SYSTEM_PRIVATE_CORELIB
[CLSCompliant(false)]
Expand All @@ -26,13 +27,12 @@ public enum AssemblyFlags : uint
/// The implementation of this assembly used at runtime is not expected to match the version seen at compile time.
Retargetable = 0x100,

/// Reserved.
DisableJITcompileOptimizer = 0x4000,
/// Content type mask. Masked bits correspond to values of System.Reflection.AssemblyContentType
ContentTypeMask = 0x00000e00,

/// Reserved.
EnableJITcompileTracking = 0x8000,
} // AssemblyFlags

// Internal clone of System.Reflection.AssemblyHashAlgorithm from System.Reflection.Metadata
#if SYSTEM_PRIVATE_CORELIB
[CLSCompliant(false)]
#endif
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/tools/Common/TypeSystem/Common/IAssemblyDesc.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Reflection;
using System.Reflection.Metadata;

namespace Internal.TypeSystem
{
Expand All @@ -13,6 +13,6 @@ public interface IAssemblyDesc
/// <summary>
/// Gets the assembly name.
/// </summary>
AssemblyName GetName();
AssemblyNameInfo GetName();
}
}
4 changes: 2 additions & 2 deletions src/coreclr/tools/Common/TypeSystem/Common/IModuleResolver.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Reflection;
using System.Reflection.Metadata;

namespace Internal.TypeSystem
{
public interface IModuleResolver
{
ModuleDesc ResolveAssembly(AssemblyName name, bool throwIfNotFound = true);
ModuleDesc ResolveAssembly(AssemblyNameInfo name, bool throwIfNotFound = true);
ModuleDesc ResolveModule(IAssemblyDesc referencingModule, string fileName, bool throwIfNotFound = true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Metadata;

using Internal.NativeFormat;

Expand All @@ -24,7 +24,7 @@ protected void InitializeSystemModule(ModuleDesc systemModule)
SystemModule = systemModule;
}

public virtual ModuleDesc ResolveAssembly(AssemblyName name, bool throwIfNotFound = true)
public virtual ModuleDesc ResolveAssembly(AssemblyNameInfo name, bool throwIfNotFound = true)
{
if (throwIfNotFound)
throw new NotSupportedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private TypeDesc GetSimpleType(TypeName typeName)
ModuleDesc module = _module;
if (topLevelTypeName.AssemblyName != null)
{
module = _context.ResolveAssembly(typeName.AssemblyName.ToAssemblyName(), throwIfNotFound: _throwIfNotFound);
module = _context.ResolveAssembly(typeName.AssemblyName, throwIfNotFound: _throwIfNotFound);
if (module == null)
return null;
}
Expand Down
21 changes: 11 additions & 10 deletions src/coreclr/tools/Common/TypeSystem/Ecma/EcmaAssembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Internal.TypeSystem.Ecma
{
public sealed partial class EcmaAssembly : EcmaModule, IAssemblyDesc
{
private AssemblyName _assemblyName;
private AssemblyNameInfo _assemblyName;
private AssemblyDefinition _assemblyDefinition;

public AssemblyDefinition AssemblyDefinition
Expand Down Expand Up @@ -39,20 +39,21 @@ public EcmaAssembly(TypeSystemContext context, PEReader peReader, MetadataReader
_assemblyDefinition = metadataReader.GetAssemblyDefinition();
}

// Returns cached copy of the name. Caller has to create a clone before mutating the name.
public AssemblyName GetName()
public AssemblyNameInfo GetName()
{
if (_assemblyName == null)
{
MetadataReader metadataReader = this.MetadataReader;

AssemblyName an = new AssemblyName();
an.Name = metadataReader.GetString(_assemblyDefinition.Name);
an.Version = _assemblyDefinition.Version;
an.SetPublicKey(metadataReader.GetBlobBytes(_assemblyDefinition.PublicKey));

an.CultureName = metadataReader.GetString(_assemblyDefinition.Culture);
an.ContentType = GetContentTypeFromAssemblyFlags(_assemblyDefinition.Flags);
AssemblyNameInfo an = new AssemblyNameInfo
(
name: metadataReader.GetString(_assemblyDefinition.Name),
version: _assemblyDefinition.Version,
cultureName: metadataReader.GetString(_assemblyDefinition.Culture),
flags: (AssemblyNameFlags)
((_assemblyDefinition.Flags & AssemblyFlags.ContentTypeMask) | AssemblyFlags.PublicKey),
publicKeyOrToken: metadataReader.GetBlobContent(_assemblyDefinition.PublicKey)
);

_assemblyName = an;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Reflection;
using System.Reflection.Metadata;

using Debug = System.Diagnostics.Debug;

Expand All @@ -20,8 +20,8 @@ public int CompareTo(EcmaModule other)
if (thisAssembly != otherAssembly)
{
// Each module comes from a different assembly: compare the assemblies
AssemblyName thisAssemblyName = thisAssembly.GetName();
AssemblyName otherAssemblyName = otherAssembly.GetName();
AssemblyNameInfo thisAssemblyName = thisAssembly.GetName();
AssemblyNameInfo otherAssemblyName = otherAssembly.GetName();

int compare = StringComparer.Ordinal.Compare(thisAssemblyName.Name, otherAssemblyName.Name);
if (compare != 0)
Expand Down
29 changes: 8 additions & 21 deletions src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -615,22 +615,14 @@ private object ResolveAssemblyReference(AssemblyReferenceHandle handle)
{
AssemblyReference assemblyReference = _metadataReader.GetAssemblyReference(handle);

AssemblyName an = new AssemblyName();
an.Name = _metadataReader.GetString(assemblyReference.Name);
an.Version = assemblyReference.Version;

var publicKeyOrToken = _metadataReader.GetBlobBytes(assemblyReference.PublicKeyOrToken);
if ((assemblyReference.Flags & AssemblyFlags.PublicKey) != 0)
{
an.SetPublicKey(publicKeyOrToken);
}
else
{
an.SetPublicKeyToken(publicKeyOrToken);
}

an.CultureName = _metadataReader.GetString(assemblyReference.Culture);
an.ContentType = GetContentTypeFromAssemblyFlags(assemblyReference.Flags);
AssemblyNameInfo an = new AssemblyNameInfo
(
name: _metadataReader.GetString(assemblyReference.Name),
version: assemblyReference.Version,
cultureName: _metadataReader.GetString(assemblyReference.Culture),
flags: (AssemblyNameFlags)assemblyReference.Flags,
publicKeyOrToken: _metadataReader.GetBlobContent(assemblyReference.PublicKeyOrToken)
);

var assembly = _moduleResolver.ResolveAssembly(an, throwIfNotFound: false);
if (assembly == null)
Expand Down Expand Up @@ -687,11 +679,6 @@ public sealed override MetadataType GetGlobalModuleType()
return (MetadataType)GetType(MetadataTokens.EntityHandle(0x02000001 /* COR_GLOBAL_PARENT_TOKEN */));
}

protected static AssemblyContentType GetContentTypeFromAssemblyFlags(AssemblyFlags flags)
{
return (AssemblyContentType)(((int)flags & 0x0E00) >> 9);
}

public string GetUserString(UserStringHandle userStringHandle)
{
// String literals are not cached
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Runtime.InteropServices;

namespace Internal.TypeSystem
{
Expand All @@ -28,7 +29,7 @@ internal class TypeSystemMetadataEmitter
private BlobHandle _noArgsVoidReturnStaticMethodSigHandle;
protected TypeSystemContext _typeSystemContext;

public TypeSystemMetadataEmitter(AssemblyName assemblyName, TypeSystemContext context, AssemblyFlags flags = default(AssemblyFlags), byte[] publicKeyArray = null)
public TypeSystemMetadataEmitter(AssemblyNameInfo assemblyName, TypeSystemContext context, AssemblyFlags flags = default(AssemblyFlags), byte[] publicKeyArray = null)
{
_typeSystemContext = context;
_metadataBuilder = new MetadataBuilder();
Expand Down Expand Up @@ -118,26 +119,27 @@ public byte[] EmitToMetadataBlob()
return metadataBlobBuilder.ToArray();
}

public AssemblyReferenceHandle GetAssemblyRef(AssemblyName name)
public AssemblyReferenceHandle GetAssemblyRef(AssemblyNameInfo name)
{
// References use a public key token instead of full public key.
if ((name.Flags & AssemblyNameFlags.PublicKey) != 0)
{
// Use AssemblyName to convert PublicKey to PublicKeyToken to avoid calling crypto APIs directly
AssemblyName an = new();
an.SetPublicKey(ImmutableCollectionsMarshal.AsArray<byte>(name.PublicKeyOrToken));
name = new AssemblyNameInfo(name.Name, name.Version, name.CultureName, name.Flags & ~AssemblyNameFlags.PublicKey, ImmutableCollectionsMarshal.AsImmutableArray<byte>(an.GetPublicKeyToken()));
}

if (!_assemblyRefNameHandles.TryGetValue(name.FullName, out var handle))
{
StringHandle assemblyName = _metadataBuilder.GetOrAddString(name.Name);
StringHandle cultureName = (name.CultureName != null) ? _metadataBuilder.GetOrAddString(name.CultureName) : default(StringHandle);
BlobHandle publicTokenBlob = name.GetPublicKeyToken() != null ? _metadataBuilder.GetOrAddBlob(name.GetPublicKeyToken()) : default(BlobHandle);
AssemblyFlags flags = default(AssemblyFlags);
if (name.Flags.HasFlag(AssemblyNameFlags.Retargetable))
{
flags |= AssemblyFlags.Retargetable;
}
if (name.ContentType == AssemblyContentType.WindowsRuntime)
{
flags |= AssemblyFlags.WindowsRuntime;
}

Version version = name.Version;
if (version == null)
version = new Version(0, 0);
BlobHandle publicTokenBlob = name.PublicKeyOrToken.IsDefault ? default : _metadataBuilder.GetOrAddBlob(name.PublicKeyOrToken);

AssemblyFlags flags = (AssemblyFlags)name.Flags & (AssemblyFlags.Retargetable | AssemblyFlags.ContentTypeMask);

Version version = name.Version ?? new Version(0, 0);

handle = _metadataBuilder.AddAssemblyReference(assemblyName, version, cultureName, publicTokenBlob, flags, default(BlobHandle));

Expand All @@ -152,7 +154,7 @@ public AssemblyReferenceHandle GetAssemblyRef(IAssemblyDesc assemblyDesc)
{
return handle;
}
AssemblyName name = assemblyDesc.GetName();
AssemblyNameInfo name = assemblyDesc.GetName();
var referenceHandle = GetAssemblyRef(name);
_assemblyRefs.Add(assemblyDesc, referenceHandle);
return referenceHandle;
Expand Down
Loading

0 comments on commit 3ab6767

Please sign in to comment.