Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/coreclr/vm/appdomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3138,7 +3138,6 @@ PEAssembly * AppDomain::BindAssemblySpec(
STATIC_CONTRACT_THROWS;
STATIC_CONTRACT_GC_TRIGGERS;
PRECONDITION(CheckPointer(pSpec));
PRECONDITION(pSpec->GetAppDomain() == this);
PRECONDITION(this==::GetAppDomain());

GCX_PREEMP();
Expand All @@ -3161,7 +3160,7 @@ PEAssembly * AppDomain::BindAssemblySpec(
PEAssembly* result = NULL;
{
ReleaseHolder<BINDER_SPACE::Assembly> boundAssembly;
hrBindResult = pSpec->Bind(this, &boundAssembly, &bindDiagnosticInfo);
hrBindResult = pSpec->Bind(&boundAssembly, &bindDiagnosticInfo);

if (boundAssembly)
{
Expand Down Expand Up @@ -3196,7 +3195,7 @@ PEAssembly * AppDomain::BindAssemblySpec(
if (!pSpec->IsCoreLibSatellite())
{
// Trigger the resolve event also for non-throw situation.
AssemblySpec NewSpec(this);
AssemblySpec NewSpec;
AssemblySpec *pFailedSpec = NULL;

fForceReThrow = TRUE; // Managed resolve event handler can throw
Expand All @@ -3216,7 +3215,7 @@ PEAssembly * AppDomain::BindAssemblySpec(
{
Exception *ex = GET_EXCEPTION();

AssemblySpec NewSpec(this);
AssemblySpec NewSpec;
AssemblySpec *pFailedSpec = NULL;

// Let transient exceptions or managed resolve event handler exceptions propagate
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/vm/assemblybinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,9 @@ void AssemblyBinder::GetNameForDiagnosticsFromSpec(AssemblySpec* spec, /*out*/ S
{
_ASSERTE(spec != nullptr);

AppDomain* domain = spec->GetAppDomain();
AssemblyBinder* binder = spec->GetBinder();
if (binder == nullptr)
binder = spec->GetBinderFromParentAssembly(domain);
binder = spec->GetInitialBinder();

binder->GetNameForDiagnostics(alcName);
}
Expand Down
12 changes: 2 additions & 10 deletions src/coreclr/vm/assemblynative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,10 @@ extern "C" void QCALLTYPE AssemblyNative_InternalLoad(NativeAssemblyNameParts* p
spec.SetParentAssembly(pRefAssembly);

// Have we been passed the reference to the binder against which this load should be triggered?
// If so, then use it to set the fallback load context binder.
// If so, then bind against it instead of the requesting assembly's load context.
if (pBinder != NULL)
{
spec.SetFallbackBinderForRequestingAssembly(pBinder);
spec.SetPreferFallbackBinder();
}
else if (pRefAssembly != NULL)
{
// If the requesting assembly has Fallback LoadContext binder available,
// then set it up in the AssemblySpec.
PEAssembly *pRefAssemblyManifestFile = pRefAssembly->GetPEAssembly();
spec.SetFallbackBinderForRequestingAssembly(pRefAssemblyManifestFile->GetFallbackBinder());
spec.SetExplicitBinder(pBinder);
}

Assembly *pAssembly = spec.LoadAssembly(FILE_LOADED, fThrowOnFileNotFound);
Expand Down
68 changes: 22 additions & 46 deletions src/coreclr/vm/assemblyspec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,58 +263,39 @@ void AssemblySpec::InitializeAssemblyNameRef(_In_ BINDER_SPACE::AssemblyName* as
spec.AssemblyNameInit(assemblyNameRef);
}

AssemblyBinder* AssemblySpec::GetBinderFromParentAssembly(AppDomain *pDomain)
AssemblyBinder* AssemblySpec::GetInitialBinder()
{
CONTRACTL
{
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
PRECONDITION(pDomain != NULL);
}
CONTRACTL_END;

// If the caller explicitly named the load context to bind against, it wins over the parent's context.
if (GetExplicitBinder() != NULL)
return GetExplicitBinder();

AssemblyBinder *pParentAssemblyBinder = NULL;
Assembly *pParentAssembly = GetParentAssembly();

if(pParentAssembly != NULL)
if (pParentAssembly != NULL)
{
// Get the PEAssembly associated with the parent's assembly
// Get the PEAssembly associated with the parent's assembly. For a dynamic parent this is the
// binder of the assembly that created it, which was captured at Assembly::CreateDynamic time.
PEAssembly *pParentPEAssembly = pParentAssembly->GetPEAssembly();
pParentAssemblyBinder = pParentPEAssembly->GetAssemblyBinder();
}

if (GetPreferFallbackBinder())
{
// If we have been asked to use the fallback load context binder (currently only supported for AssemblyLoadContext.LoadFromAssemblyName),
// then pretend we do not have any binder yet available.
_ASSERTE(GetFallbackBinderForRequestingAssembly() != NULL);
pParentAssemblyBinder = NULL;
}

if (pParentAssemblyBinder == NULL)
{
// If the parent assembly binder is not available, then we maybe dealing with one of the following
// assembly scenarios:
//
// 1) Entrypoint assembly
// 2) AssemblyLoadContext.LoadFromAssemblyName
//
// For (2), we will need to bind against the DefaultContext binder (aka TPA Binder). This happens
// below if we do not find the parent assembly binder.
//
// For (3), fetch the fallback load context binder reference.

pParentAssemblyBinder = GetFallbackBinderForRequestingAssembly();
}

if (!pParentAssemblyBinder)
{
// We can be here when loading assemblies via the host (e.g. ICLRRuntimeHost2::ExecuteAssembly) (see comment above for details).
// We can be here when there is no parent assembly, i.e. the entrypoint assembly, or when loading
// assemblies via the host (e.g. ICLRRuntimeHost2::ExecuteAssembly).
//
// In such a case, the parent assembly (semantically) is CoreLibrary and thus, the default binding context should be
// used as the parent assembly binder.
pParentAssemblyBinder = static_cast<AssemblyBinder*>(pDomain->GetDefaultBinder());
// In such a case, the parent assembly (semantically) is CoreLibrary and thus, the default binding
// context should be used as the parent assembly binder.
pParentAssemblyBinder = AppDomain::GetCurrentDomain()->GetDefaultBinder();
}

return pParentAssemblyBinder;
Expand All @@ -334,7 +315,7 @@ Assembly *AssemblySpec::LoadAssembly(FileLoadLevel targetLevel,
CONTRACTL_END;

ETWOnStartup (LoaderCatchCall_V1, LoaderCatchCallEnd_V1);
AppDomain* pDomain = GetAppDomain();
AppDomain* pDomain = AppDomain::GetCurrentDomain();

Assembly* assembly = pDomain->FindCachedAssembly(this);
if (assembly)
Expand Down Expand Up @@ -581,23 +562,18 @@ AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::LookupInter
UPTR key = (UPTR)pSpec->Hash();

AssemblyBinder *pBinderForLookup = NULL;
bool fGetBindingContextFromParent = true;
bool fUsedInitialBinder = false;

// 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.
pBinderForLookup = pSpec->GetBinder();

if (pBinderForLookup != NULL)
{
// We are working with the actual binding context in which the assembly was expected to be loaded.
// Thus, we don't need to get it from the parent assembly.
fGetBindingContextFromParent = false;
}

if (fGetBindingContextFromParent)
if (pBinderForLookup == NULL)
{
pBinderForLookup = pSpec->GetBinderFromParentAssembly(pSpec->GetAppDomain());
// No binder is associated with the spec yet, so use the one the bind would start against.
pBinderForLookup = pSpec->GetInitialBinder();
pSpec->SetBinder(pBinderForLookup);
fUsedInitialBinder = true;
}

if (pBinderForLookup)
Expand All @@ -607,9 +583,9 @@ AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::LookupInter

AssemblyBinding* pEntry = (AssemblyBinding *)m_map.LookupValue(key, pSpec);

// Reset the binding context if one was originally never present in the AssemblySpec and we didnt find any entry
// Reset the binder if one was originally never present in the AssemblySpec and we didn't find any entry
// in the cache.
if (fGetBindingContextFromParent)
if (fUsedInitialBinder)
{
if (pEntry == (AssemblyBinding *) INVALIDENTRY)
{
Expand Down Expand Up @@ -1009,7 +985,7 @@ BOOL AssemblySpecBindingCache::StoreException(AssemblySpec *pSpec, Exception* pE
pBinderToSaveException = pSpec->GetBinder();
if (pBinderToSaveException == NULL)
{
pBinderToSaveException = pSpec->GetBinderFromParentAssembly(pSpec->GetAppDomain());
pBinderToSaveException = pSpec->GetInitialBinder();
key = key ^ (UPTR)pBinderToSaveException;
}
}
Expand Down
67 changes: 11 additions & 56 deletions src/coreclr/vm/assemblyspec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,11 @@ enum NotificationStatus
class AssemblySpec : public BaseAssemblySpec
{
private:
AppDomain *m_pAppDomain;
Assembly *m_pParentAssembly;

// Contains the reference to the fallback load context associated with RefEmitted assembly requesting the load of another assembly (static or dynamic)
AssemblyBinder *m_pFallbackBinder;

// Flag to indicate if we should prefer the fallback load context binder for binding or not.
bool m_fPreferFallbackBinder;
// 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;

HRESULT InitializeSpecInternal(mdToken kAssemblyRefOrDef,
IMDInternalImport *pImport,
Expand All @@ -73,32 +70,16 @@ class AssemblySpec : public BaseAssemblySpec

public:

#ifndef DACCESS_COMPILE
AssemblySpec() : m_pAppDomain(::GetAppDomain())
AssemblySpec()
{
LIMITED_METHOD_CONTRACT;
m_pParentAssembly = NULL;

m_pFallbackBinder = NULL;
m_fPreferFallbackBinder = false;

m_pExplicitBinder = NULL;
}
#endif //!DACCESS_COMPILE

AssemblySpec(AppDomain *pAppDomain) : m_pAppDomain(pAppDomain)
{
LIMITED_METHOD_CONTRACT
m_pParentAssembly = NULL;

m_pFallbackBinder = NULL;
m_fPreferFallbackBinder = false;

}


Assembly* GetParentAssembly();

AssemblyBinder* GetBinderFromParentAssembly(AppDomain *pDomain);
AssemblyBinder* GetInitialBinder();

bool HasParentAssembly()
{ WRAPPER_NO_CONTRACT; return GetParentAssembly() != NULL; }
Expand Down Expand Up @@ -139,32 +120,18 @@ class AssemblySpec : public BaseAssemblySpec
m_pParentAssembly = pAssembly;
}

void SetFallbackBinderForRequestingAssembly(AssemblyBinder *pFallbackBinder)
{
LIMITED_METHOD_CONTRACT;

m_pFallbackBinder = pFallbackBinder;
}

AssemblyBinder* GetFallbackBinderForRequestingAssembly()
void SetExplicitBinder(AssemblyBinder *pBinder)
{
LIMITED_METHOD_CONTRACT;

return m_pFallbackBinder;
m_pExplicitBinder = pBinder;
}

void SetPreferFallbackBinder()
AssemblyBinder* GetExplicitBinder()
{
LIMITED_METHOD_CONTRACT;

m_fPreferFallbackBinder = true;
}

bool GetPreferFallbackBinder()
{
LIMITED_METHOD_CONTRACT;

return m_fPreferFallbackBinder;
return m_pExplicitBinder;
}

// Note that this method does not clone the fields!
Expand All @@ -181,10 +148,7 @@ class AssemblySpec : public BaseAssemblySpec
BaseAssemblySpec::CopyFrom(pSource);

SetParentAssembly(pSource->GetParentAssembly());

// Copy the details of the fallback load context binder
SetFallbackBinderForRequestingAssembly(pSource->GetFallbackBinderForRequestingAssembly());
m_fPreferFallbackBinder = pSource->GetPreferFallbackBinder();
SetExplicitBinder(pSource->GetExplicitBinder());
}

HRESULT CheckFriendAssemblyName();
Expand All @@ -193,7 +157,6 @@ class AssemblySpec : public BaseAssemblySpec
mdAssemblyRef *pToken);

HRESULT Bind(
AppDomain* pAppDomain,
BINDER_SPACE::Assembly** ppAssembly,
SString* pDiagnosticInfo = NULL);

Expand All @@ -213,14 +176,6 @@ class AssemblySpec : public BaseAssemblySpec

// Initialize an AssemblyName managed object based on the specified assemblyName
static void InitializeAssemblyNameRef(_In_ BINDER_SPACE::AssemblyName* assemblyName, _Out_ ASSEMBLYNAMEREF* assemblyNameRef);

public:
AppDomain *GetAppDomain()
{
LIMITED_METHOD_CONTRACT;
return m_pAppDomain;
}

};

#define INITIAL_ASM_SPEC_HASH_SIZE 7
Expand Down
6 changes: 2 additions & 4 deletions src/coreclr/vm/coreassemblyspec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,20 @@
#include "../binder/inc/assemblybindercommon.hpp"
#include "../binder/inc/applicationcontext.hpp"

HRESULT AssemblySpec::Bind(AppDomain *pAppDomain, BINDER_SPACE::Assembly** ppAssembly, SString* pDiagnosticInfo)
HRESULT AssemblySpec::Bind(BINDER_SPACE::Assembly** ppAssembly, SString* pDiagnosticInfo)
{
CONTRACTL
{
INSTANCE_CHECK;
STANDARD_VM_CHECK;
PRECONDITION(CheckPointer(ppAssembly));
PRECONDITION(CheckPointer(pAppDomain));
PRECONDITION(IsCoreLib() == FALSE); // This should never be called for CoreLib (explicit loading)
}
CONTRACTL_END;

HRESULT hr=S_OK;

// Have a default binding context setup
AssemblyBinder *pBinder = GetBinderFromParentAssembly(pAppDomain);
AssemblyBinder *pBinder = GetInitialBinder();

ReleaseHolder<BINDER_SPACE::Assembly> pPrivAsm;
_ASSERTE(pBinder != NULL);
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/vm/peassembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ PEAssembly::PEAssembly(
BINDER_SPACE::Assembly* pBindResultInfo,
IMetaDataEmit* pEmit,
BOOL isSystem,
AssemblyBinder* pFallbackBinder /*= NULL*/,
AssemblyBinder* pDynamicAssemblyBinder /*= NULL*/,
PEImage * pPEImage /*= NULL*/,
BINDER_SPACE::Assembly * pHostAssembly /*= NULL*/)
{
Expand Down Expand Up @@ -723,7 +723,7 @@ PEAssembly::PEAssembly(
}
else
{
m_pAssemblyBinder = pFallbackBinder;
m_pAssemblyBinder = pDynamicAssemblyBinder;
}

#ifdef LOGGING
Expand All @@ -744,7 +744,7 @@ PEAssembly *PEAssembly::Open(
nullptr, // BindResult
nullptr, // IMetaDataEmit
FALSE, // isSystem
nullptr, // FallbackBinder
nullptr, // DynamicAssemblyBinder
pPEImageIL,
pHostAssembly);

Expand Down Expand Up @@ -837,7 +837,7 @@ PEAssembly* PEAssembly::Open(BINDER_SPACE::Assembly* pBindResult)
};

/* static */
PEAssembly *PEAssembly::Create(IMetaDataAssemblyEmit *pAssemblyEmit, AssemblyBinder *pFallbackBinder)
PEAssembly *PEAssembly::Create(IMetaDataAssemblyEmit *pAssemblyEmit, AssemblyBinder *pDynamicAssemblyBinder)
{
CONTRACTL
{
Expand All @@ -850,7 +850,7 @@ PEAssembly *PEAssembly::Create(IMetaDataAssemblyEmit *pAssemblyEmit, AssemblyBin
// we have.)
ReleaseHolder<IMetaDataEmit> pEmit;
pAssemblyEmit->QueryInterface(IID_IMetaDataEmit, (void **)&pEmit);
return new PEAssembly(NULL, pEmit, FALSE, pFallbackBinder);
return new PEAssembly(NULL, pEmit, FALSE, pDynamicAssemblyBinder);
}

#endif // #ifndef DACCESS_COMPILE
Expand Down
Loading
Loading