Skip to content

Remove the fallback binder from PEAssembly and AssemblySpec - #131894

Open
elinor-fung wants to merge 5 commits into
dotnet:mainfrom
elinor-fung:clarify-fallback-binder
Open

Remove the fallback binder from PEAssembly and AssemblySpec#131894
elinor-fung wants to merge 5 commits into
dotnet:mainfrom
elinor-fung:clarify-fallback-binder

Conversation

@elinor-fung

@elinor-fung elinor-fung commented Aug 5, 2026

Copy link
Copy Markdown
Member

A fallback binder was an overloaded (and confusing-to-me) concept with three possible meanings:

  • PEAssembly: the binder for assemblies without a 'host' assembly (that is, ref-emit assemblies), null for non-ref-emit assemblies
  • AssemblySpec: the binder for specs where the parent assembly's binder could not be determined
  • AssemblySpec: the explicitly specified binder for that assembly load operation

This change removes / clarifies those meanings:

  • Remove PEAssembly::GetFallbackAssembly
    • For ref-emit on PEAssembly, it really isn't a fallback - it is the binder and we already store it as such.
  • Replace AssemblySpec:: m_pFallbackBinder and m_fPreferFallbackBinder with m_pExplicitBinder
    • This represents the binder explicitly specified for a load operation
    • The case of the fallback for specs without the parent assembly binder was effectively dead - the only place where the fallback binder was set for a spec for this case was using on an assembly that was already set to the spec's parent assembly.
  • Rename AssemblySpec:: GetBinderFromParentAssembly to GetInitialBinder
    • It wasn't just for the parent assembly - it represents the binder with which to kick off the bind request (as opposed to the GetBinder which is the binder with which the assembly was actually bound)

Also removes the AssemblySpec::m_pAppDomain.

cc @dotnet/appmodel @AaronRobinsonMSFT

elinor-fung and others added 3 commits August 3, 2026 14:25
PEAssembly::GetFallbackBinder() existed to answer "which binder should a
Ref.Emit assembly's dependencies bind against?", back when the creator's
binder was held in a dedicated m_pFallbackBinder field separate from
m_pHostAssembly.

Since dotnet#117939 merged those into a single eagerly-computed m_pAssemblyBinder,
GetFallbackBinder() has just been GetAssemblyBinder() with a
"m_pHostAssembly == NULL" filter, and its only caller stashed the result in
AssemblySpec under a condition that also guarantees SetParentAssembly() ran.
GetBinderFromParentAssembly() therefore always resolved the same value from
the parent binder tier first, and the stashed copy was never read.

Drop GetFallbackBinder() and the dead branch, and collapse
m_pFallbackBinder/m_fPreferFallbackBinder into a single m_pExplicitBinder,
which is what that pair actually encoded: the binder named explicitly by
AssemblyLoadContext.LoadFromAssemblyName, which takes precedence over the
parent's context. Binder resolution goes from three tiers to two.

Also rename the PEAssembly ctor/factory parameter from pFallbackBinder to
pDynamicAssemblyBinder. It is not a fallback: for a dynamic assembly it is
the binder.

No functional change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a96004b3-2cbc-46c1-8313-299ca97ec301
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors CoreCLR assembly binding to remove the overloaded “fallback binder” concept, clarifying binder ownership for dynamic (ref-emit) assemblies and making AssemblySpec’s binder intent explicit (initial vs actually-bound binder).

Changes:

  • Removes PEAssembly::GetFallbackBinder and renames related parameters to reflect that dynamic assemblies carry their creator/load-context binder directly.
  • Replaces AssemblySpec’s fallback/prefer-fallback fields with m_pExplicitBinder, and renames GetBinderFromParentAssembly to GetInitialBinder to represent the binder used to start binding.
  • Removes AssemblySpec::m_pAppDomain and updates call sites to use the current domain where needed.
Show a summary per file
File Description
src/coreclr/vm/peassembly.h Removes fallback-binder API and clarifies dynamic assembly binder semantics in the interface.
src/coreclr/vm/peassembly.cpp Plumbs the renamed dynamic-assembly binder parameter through PEAssembly construction/creation.
src/coreclr/vm/coreassemblyspec.cpp Updates AssemblySpec::Bind to use GetInitialBinder() and drops the AppDomain* parameter.
src/coreclr/vm/assemblyspec.hpp Replaces fallback-binder fields with m_pExplicitBinder and renames binder selection API.
src/coreclr/vm/assemblyspec.cpp Implements GetInitialBinder() and updates cache/exception paths to use it; switches to current domain access.
src/coreclr/vm/assemblynative.cpp Uses SetExplicitBinder when an explicit binder is provided for InternalLoad.
src/coreclr/vm/assemblybinder.cpp Uses GetInitialBinder() for diagnostics when no binder is yet associated with the spec.
src/coreclr/vm/appdomain.cpp Updates binding flow for new Bind signature and removes AppDomain affinity checks tied to AssemblySpec.

Copilot's findings

  • Files reviewed: 8/8 changed files
  • Comments generated: 2

Comment thread src/coreclr/vm/assemblyspec.hpp Outdated
Comment thread src/coreclr/vm/assemblyspec.cpp Outdated
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @elinor-fung
See info in area-owners.md if you want to be subscribed.

Co-authored-by: Elinor Fung <elfung@microsoft.com>
Copilot AI review requested due to automatic review settings August 5, 2026 18:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Suppressed comments (4)

src/coreclr/vm/assemblyspec.hpp:58

  • The two newly added comment lines appear to have stray CR (\r) characters at the end, introducing mixed line endings in this file. Please normalize these lines to use the repo’s standard LF endings (remove the CR characters).
    // The initial binder to use when the caller explicitly provided a load context for this load.
    // When set, it takes precedence over the binder of the parent assembly as the initial binder.
    AssemblyBinder *m_pExplicitBinder;

src/coreclr/vm/assemblyspec.cpp:278

  • The comment and following if line have stray CR (\r) characters at the end (mixed line endings). Please rewrite these lines with normal LF endings to avoid churn and potential formatting enforcement issues.
    // If the caller explicitly named the load context to bind against, it wins over the parent's context.
    if (GetExplicitBinder() != NULL)
        return GetExplicitBinder();

src/coreclr/vm/assemblyspec.cpp:568

  • This comment still claims AssemblySpec::GetBinder() will be set for AssemblyLoadContext LoadFrom* scenarios, but after this change those paths set m_pExplicitBinder (not GetBinder()) and GetBinder() remains null until later. Updating the comment will prevent readers from assuming GetBinder() reflects LoadFrom* loads.
    // Check if the AssemblySpec already has specified its binding context. This will be set for assemblies that are
    // attempted to be explicitly bound using AssemblyLoadContext LoadFrom* methods.

src/coreclr/vm/assemblyspec.cpp:988

  • The nearby comment says failures are saved in the “DefaultBinder context”, but this block actually keys the cached failure by GetBinder() (if already known) or otherwise by GetInitialBinder(). Please update the comment to match the logic to avoid confusing future readers.
            pBinderToSaveException = pSpec->GetInitialBinder();
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new

Comment thread src/coreclr/vm/assemblyspec.cpp Outdated
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
Copilot AI review requested due to automatic review settings August 5, 2026 18:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Suppressed comments (1)

src/coreclr/vm/assemblyspec.hpp:58

  • The comment lines here appear to contain literal carriage-return characters (shown as "\r" in the file view), which can lead to mixed line endings / stray control characters in the source. Please normalize these lines to use the file’s standard LF line endings (i.e., remove the embedded CR characters).
    // The initial binder to use when the caller explicitly provided a load context for this load.
    // When set, it takes precedence over the binder of the parent assembly as the initial binder.
    AssemblyBinder *m_pExplicitBinder;
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants