From baf25ac0e3881e31698f0367a8ea03ce4fc0e652 Mon Sep 17 00:00:00 2001 From: Washi Date: Sun, 27 Nov 2022 14:23:03 +0100 Subject: [PATCH] Add IsTypeOfUtf8 as well as Utf8String versions of Name properties to avoid unnecessary string allocations during member resolution. --- .../DefaultMetadataResolver.cs | 30 +++++++++++-------- src/AsmResolver.DotNet/IFieldDescriptor.cs | 8 +++++ src/AsmResolver.DotNet/IMethodDescriptor.cs | 8 +++++ .../TypeDescriptorExtensions.cs | 22 ++++++++++++++ 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/AsmResolver.DotNet/DefaultMetadataResolver.cs b/src/AsmResolver.DotNet/DefaultMetadataResolver.cs index fcfc69b8b..bd3030090 100644 --- a/src/AsmResolver.DotNet/DefaultMetadataResolver.cs +++ b/src/AsmResolver.DotNet/DefaultMetadataResolver.cs @@ -81,12 +81,12 @@ public IAssemblyResolver AssemblyResolver return null; var resolvedType = LookupInCache(exportedType); - if (resolvedType != null) + if (resolvedType is not null) return resolvedType; var resolution = new TypeResolution(AssemblyResolver); resolvedType = resolution.ResolveExportedType(exportedType); - if (resolvedType != null) + if (resolvedType is not null) _typeCache[exportedType] = resolvedType; return resolvedType; @@ -137,6 +137,10 @@ public IAssemblyResolver AssemblyResolver if (declaringType is null) return null; + var name = field is MemberReference member + ? member.Name + : (Utf8String?) field.Name; + for (int i = 0; i < declaringType.Fields.Count; i++) { var candidate = declaringType.Fields[i]; @@ -171,7 +175,7 @@ public TypeResolution(IAssemblyResolver resolver) { case TableIndex.AssemblyRef: var assemblyDefScope = _assemblyResolver.Resolve((AssemblyReference) scope); - return assemblyDefScope != null + return assemblyDefScope is not null ? FindTypeInAssembly(assemblyDefScope, reference.Namespace, reference.Name) : null; @@ -180,7 +184,7 @@ public TypeResolution(IAssemblyResolver resolver) case TableIndex.TypeRef: var typeDefScope = ResolveTypeReference((TypeReference) scope); - return typeDefScope != null + return typeDefScope is not null ? FindTypeInType(typeDefScope, reference.Name) : null; @@ -200,20 +204,20 @@ public TypeResolution(IAssemblyResolver resolver) { case TableIndex.AssemblyRef: var assembly = _assemblyResolver.Resolve((AssemblyReference) implementation); - return assembly is {} + return assembly is not null ? FindTypeInAssembly(assembly, exportedType.Namespace, exportedType.Name) : null; case TableIndex.File when !string.IsNullOrEmpty(implementation.Name): var module = FindModuleInAssembly(exportedType.Module!.Assembly!, implementation.Name!); - return module is {} + return module is not null ? FindTypeInModule(module, exportedType.Namespace, exportedType.Name) : null; case TableIndex.ExportedType: var exportedDeclaringType = (ExportedType) implementation; var declaringType = ResolveExportedType(exportedDeclaringType); - return declaringType is {} + return declaringType is not null ? FindTypeInType(declaringType, exportedType.Name) : null; @@ -228,33 +232,33 @@ public TypeResolution(IAssemblyResolver resolver) { var module = assembly.Modules[i]; var type = FindTypeInModule(module, ns, name); - if (type != null) + if (type is not null) return type; } return null; } - private TypeDefinition? FindTypeInModule(ModuleDefinition module, string? ns, string name) + private TypeDefinition? FindTypeInModule(ModuleDefinition module, Utf8String? ns, Utf8String name) { for (int i = 0; i < module.ExportedTypes.Count; i++) { var exportedType = module.ExportedTypes[i]; - if (exportedType.IsTypeOf(ns, name)) + if (exportedType.IsTypeOfUtf8(ns, name)) return ResolveExportedType(exportedType); } for (int i = 0; i < module.TopLevelTypes.Count; i++) { var type = module.TopLevelTypes[i]; - if (type.IsTypeOf(ns, name)) + if (type.IsTypeOfUtf8(ns, name)) return type; } return null; } - private static TypeDefinition? FindTypeInType(TypeDefinition enclosingType, string name) + private static TypeDefinition? FindTypeInType(TypeDefinition enclosingType, Utf8String name) { for (int i = 0; i < enclosingType.NestedTypes.Count; i++) { @@ -266,7 +270,7 @@ public TypeResolution(IAssemblyResolver resolver) return null; } - private static ModuleDefinition? FindModuleInAssembly(AssemblyDefinition assembly, string name) + private static ModuleDefinition? FindModuleInAssembly(AssemblyDefinition assembly, Utf8String name) { for (int i = 0; i < assembly.Modules.Count; i++) { diff --git a/src/AsmResolver.DotNet/IFieldDescriptor.cs b/src/AsmResolver.DotNet/IFieldDescriptor.cs index 18143ac19..8ed9a5ebf 100644 --- a/src/AsmResolver.DotNet/IFieldDescriptor.cs +++ b/src/AsmResolver.DotNet/IFieldDescriptor.cs @@ -7,6 +7,14 @@ namespace AsmResolver.DotNet /// public interface IFieldDescriptor : IMemberDescriptor, IMetadataMember { + /// + /// Gets the name of the field. + /// + new Utf8String Name + { + get; + } + /// /// Gets the signature of the field. /// diff --git a/src/AsmResolver.DotNet/IMethodDescriptor.cs b/src/AsmResolver.DotNet/IMethodDescriptor.cs index 4f695c8f9..d9cf2085c 100644 --- a/src/AsmResolver.DotNet/IMethodDescriptor.cs +++ b/src/AsmResolver.DotNet/IMethodDescriptor.cs @@ -7,6 +7,14 @@ namespace AsmResolver.DotNet /// public interface IMethodDescriptor : IMemberDescriptor, IMetadataMember { + /// + /// Gets the name of the method. + /// + new Utf8String Name + { + get; + } + /// /// Gets the signature of the method. /// diff --git a/src/AsmResolver.DotNet/TypeDescriptorExtensions.cs b/src/AsmResolver.DotNet/TypeDescriptorExtensions.cs index 360ad9f54..5b586f18d 100644 --- a/src/AsmResolver.DotNet/TypeDescriptorExtensions.cs +++ b/src/AsmResolver.DotNet/TypeDescriptorExtensions.cs @@ -20,6 +20,28 @@ public static class TypeDescriptorExtensions public static bool IsTypeOf(this ITypeDescriptor type, string? ns, string? name) => type.Name == name && type.Namespace == ns; + /// + /// Determines whether a type matches a namespace and name pair. + /// + /// The type. + /// The namespace. + /// The name. + /// true if the name and the namespace of the type matches the provided values, + /// false otherwise. + public static bool IsTypeOfUtf8(this ITypeDefOrRef type, Utf8String? ns, Utf8String? name) => + type.Name == name && type.Namespace == ns; + + /// + /// Determines whether a type matches a namespace and name pair. + /// + /// The type. + /// The namespace. + /// The name. + /// true if the name and the namespace of the type matches the provided values, + /// false otherwise. + public static bool IsTypeOfUtf8(this ExportedType type, Utf8String? ns, Utf8String? name) => + type.Name == name && type.Namespace == ns; + /// /// Constructs a new single-dimension, zero based array signature with the provided type descriptor /// as element type.