Open
Conversation
This comment has been minimized.
This comment has been minimized.
Sergio0694
reviewed
Jan 23, 2026
Sergio0694
reviewed
Jan 23, 2026
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Test Results
Failing runs |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is a PR that improves
RuntimeContextto make it more similar to anAssemblyLoadContext(as seen in the BCL, but for static binaries), and will further pave the way towards a full robust implementation of AsmResolver.Workspaces (#298). It aims to giveRuntimeContexta lot more responsibility, including assembly and metadata resolution. This is to make things more predictable, robust, and more diagnoseable when loading and constructing new metadata references across multiple assemblies.This is a breaking but important change: Ideally we want to get this in before we fully release 6.0.
Overview Changes
Revamp of
RuntimeContext:IAssemblyResolveris drastically simplified and does not do caching anymore.IMetadataResolverand friends are removed.RuntimeContextconstruction is drastically simplified.RuntimeContextis now responsible for resolving and maintaining assembly and metadata caches.RuntimeContext::LoadAssemblymethods to load assemblies into the context (similar toAssemblyDefinition::FromX, but using the context for reader parameters, cache and automatic wiring of dependencies).Revamp of Metadata Resolution System:
Resolvemethods are removed.T? Resolve(ModuleDefinition)methods are replaced with a throwingT Resolve(RuntimeContext), a non-throwingbool TryResolve(RuntimeContext, out T?)and a more generalResolutionStatus Resolve(RuntimeContext, out T?).RuntimeContextparameter as well. This was done to avoid implicit (failing) resolutions.bool ITypeDescriptor::IsValueTypeproperty in favor of a methodbool GetIsValueType(RuntimeContext)andbool? TryGetIsValueType(RuntimeContext). Note thatTypeSignatureandTypeDefinitionstill define the property, as these are defined by metadata itself.Other changes:
TargetRuntimeProberto detect the target runtime of a PE image without loading it as a fullModuleDefinition.MetadataDirectory::GetImpliedStreamSelection()Examples
Creating new contexts
Loading assemblies into RuntimeContexts
Resolving metadata
IsValueType, GetIsValueType and TryGetIsValueType
For references or generic descriptors, use
GetIsValueTypeorTryGetIsValueType:For definitions and signatures,
IsValueTypeproperty remains:Rationale
IMemberDefinition::Resolve()
The main reason for this big change is that many users have experienced seemingly random output corruptions or type resolution failures when constructing new binaries, in particular when adding metadata to an
AssemblyDefinitionusing the various helper methods (e.g.,CreateTypeReference,ToTypeSignature,MakeGenericInstanceTypeSignature). Currently, these helper methods often rely on the value ofITypeDescriptor::IsValueTypeto encode blob signatures properly. This property may implicitly trigger a resolution if the type needs to be resolved to aTypeDefinitionto check its base type.Experience by users has shown that the method
TypeDeifnition? ITypeDescriptor::Resolve(), while convenient for many use-cases, has a pretty brittle design:nullon failure, and leaves out the reason for why it failed. This makes it hard to diagnose where in the resolution process it failed (e.g., wrong type name, could not find containing assembly file...)ContextModule's metadata resolver. This is inaccurate when new type references are created on-the-fly. In such a case, aTypeReferencedoesn't always have a context module set yet, causing its resolution to fail despite it being a valid reference. It is also inaccurate whenTypeReferenceinstances are reused in other assemblies, which happens a lot after auto-import was introduced (Automatically import Type/Field/MethodDefintions when building #689). Some low-hanging fruits were fixed (e.g., in Address Auto Import Regressions #697), but the core problem remains.Resolve()returnsnullbut methods likeToTypeSignature()still need a proper value forTypeDefinition::IsValueType, usually a default value is set (i.e.,false). While this is in most cases correct, it is not sound for all types.This PR aims to make things more predictable, robust, and more diagnoseable when things go wrong. All methods that may require type resolutions now are explicitly marked as such.
Processing multiple assemblies at once
Additionally, users have reported that it is sometimes difficult to process a collection of assembly definitions, especially when a binary has many dependencies which in turn have dependencies etc. Currently, assemblies kind of live in their own bubble, with their own metadata and asembly resolvers attached. This works if assemblies are processed in isolation, but falls apart when processing assemblies with complex dependency graphs. The isolated resolvers would maintain own cachecs of resolved assemblies and types, resulting in multiple instances of the same assembly or type being loaded.
The first version of
RuntimeContextaimed to fix this by providing a sharedIAssemblyResolvers toModuleDefinitions. However, this had bugs (#580) and the manual wiring of assembly objects in user code is very unintuitive.This PR extracts most of the resolution and caching mechanism out of
ModuleDefinition,IMetadataResolverandIAssemblyResolver, and moves it into the sharedRuntimeContext. All resolutions now always go through the runtime context, ensuring consistency and more efficient lookups.Related Issues
Closes #580, #703