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
12 changes: 6 additions & 6 deletions src/CLR/Core/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2107,7 +2107,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
FETCH_ARG_COMPRESSED_METHODTOKEN(arg, ip);

CLR_RT_MethodDef_Instance calleeInst{};
if (calleeInst.ResolveToken(arg, assm) == false)
if (calleeInst.ResolveToken(arg, assm, stack->m_call.genericType) == false)
{
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
}
Expand Down Expand Up @@ -2345,7 +2345,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
FETCH_ARG_COMPRESSED_METHODTOKEN(arg, ip);

CLR_RT_MethodDef_Instance calleeInst{};
if (calleeInst.ResolveToken(arg, assm) == false)
if (calleeInst.ResolveToken(arg, assm, stack->m_call.genericType) == false)
{
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
}
Expand Down Expand Up @@ -3223,7 +3223,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
case TBL_MethodDef:
{
CLR_RT_MethodDef_Instance method{};
if (method.ResolveToken(arg, assm) == false)
if (method.ResolveToken(arg, assm, stack->m_call.genericType) == false)
{
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
}
Expand All @@ -3247,7 +3247,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
case TBL_MethodSpec:
{
CLR_RT_MethodDef_Instance method{};
if (!method.ResolveToken(arg, assm))
if (!method.ResolveToken(arg, assm, stack->m_call.genericType))
{
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
}
Expand Down Expand Up @@ -3403,7 +3403,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
CHECKSTACK(stack, evalPos);

CLR_RT_MethodDef_Instance method{};
if (method.ResolveToken(arg, assm) == false)
if (method.ResolveToken(arg, assm, stack->m_call.genericType) == false)
{
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
}
Expand All @@ -3421,7 +3421,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
FETCH_ARG_COMPRESSED_METHODTOKEN(arg, ip);

CLR_RT_MethodDef_Instance callee{};
if (callee.ResolveToken(arg, assm) == false)
if (callee.ResolveToken(arg, assm, stack->m_call.genericType) == false)
{
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
}
Expand Down
73 changes: 64 additions & 9 deletions src/CLR/Core/TypeSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,10 @@ void CLR_RT_MethodDef_Instance::ClearInstance()
genericType = nullptr;
}

bool CLR_RT_MethodDef_Instance::ResolveToken(CLR_UINT32 tk, CLR_RT_Assembly *assm)
bool CLR_RT_MethodDef_Instance::ResolveToken(
CLR_UINT32 tk,
CLR_RT_Assembly *assm,
const CLR_RT_TypeSpec_Index *callerGeneric)
{
NATIVE_PROFILE_CLR_CORE();
if (assm)
Expand All @@ -1285,21 +1288,73 @@ bool CLR_RT_MethodDef_Instance::ResolveToken(CLR_UINT32 tk, CLR_RT_Assembly *ass
{
// owner is TypeSpec

genericType = &assm->crossReferenceMethodRef[index].genericType;
// The raw MethodRef* says "Owner = a TypeSpec row".
// That TypeSpec row might be either the *open* generic or a purely nested flavor.
// Even if we know we are inside a closed instantiation of that same generic.
// We want to prefer the calling method's closed TypeSpec (callerGeneric) ONLY if they refer to the
// same TypeDef token.
//

const CLR_RECORD_TYPESPEC *ts = assm->GetTypeSpec(genericType->TypeSpec());
// grab the MethodRef *declared* owner:
const CLR_RT_TypeSpec_Index *methodOwnerTS = &assm->crossReferenceMethodRef[index].genericType;

CLR_RT_MethodDef_Index method;
// check if MethodRef TypeDef token is the same TypeDef as in that caller
bool useCaller = false;

if (!assm->FindMethodDef(ts, assm->GetString(mr->name), assm, mr->signature, method))
if (callerGeneric != nullptr && NANOCLR_INDEX_IS_VALID(*callerGeneric))
{
return false;
CLR_RT_TypeSpec_Instance callerInst{};
if (callerInst.InitializeFromIndex(*callerGeneric))
{
CLR_RT_SignatureParser parserCaller;
parserCaller.Initialize_TypeSpec(callerInst.assembly, callerInst.target);

CLR_RT_SignatureParser::Element elemCaller;

// advance to the generic instance which will point to the class
parserCaller.Advance(elemCaller);

CLR_UINT32 callerTypeDefToken = elemCaller.Class.data;

// parse the MethodRef declared TypeSpec
CLR_RT_TypeSpec_Instance ownerInst{};
if (ownerInst.InitializeFromIndex(*methodOwnerTS))
{
CLR_RT_SignatureParser parserOwner;
parserOwner.Initialize_TypeSpec(ownerInst.assembly, ownerInst.target);

CLR_RT_SignatureParser::Element elemOwner;

// advance to the generic instance which will point to the class
parserOwner.Advance(elemOwner);

CLR_UINT32 ownerTypeDefToken = elemOwner.Class.data;

if (callerTypeDefToken == ownerTypeDefToken)
{
// we have a match on the typeDef, so they refer to the same type
// lets bind using the closed generic
useCaller = true;
}
}
}
}

Set(assm->assemblyIndex, method.Method());
// Pick the “winner” between methodOwnerTS or callerGeneric:
const CLR_RT_TypeSpec_Index *definitiveTypeSpec = useCaller ? callerGeneric : methodOwnerTS;
genericType = (CLR_RT_TypeSpec_Index *)definitiveTypeSpec;

const CLR_RECORD_TYPESPEC *ts = assm->GetTypeSpec(definitiveTypeSpec->TypeSpec());
CLR_RT_MethodDef_Index methodIndex;

if (!assm->FindMethodDef(ts, assm->GetString(mr->name), assm, mr->signature, methodIndex))
{
return false;
}

Set(assm->assemblyIndex, methodIndex.Method());
assembly = assm;
target = assembly->GetMethodDef(method.Method());
target = assembly->GetMethodDef(methodIndex.Method());
}
else
{
Expand Down Expand Up @@ -6594,7 +6649,7 @@ bool CLR_RT_AttributeEnumerator::Advance()

// get the method definition, by resolving the token
CLR_RT_MethodDef_Instance method{};
if (method.ResolveToken(token, m_assm) == false)
if (method.ResolveToken(token, m_assm, nullptr) == false)
{
ASSERT(0);
}
Expand Down
37 changes: 26 additions & 11 deletions src/CLR/Diagnostics/Info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,26 +472,41 @@ void CLR_RT_Assembly::DumpToken(CLR_UINT32 token, const CLR_RT_TypeSpec_Index *g
CLR_UINT32 idx = CLR_DataFromTk(token);
auto &xref = crossReferenceMethodRef[idx];

// Build a MethodRef_Index so we can format the reference
// Build a MethodRef_Index so we can format the reference:
CLR_RT_MethodRef_Index mri;
mri.Set(assemblyIndex, idx);

// Pass the *target* method’s closed genericType, not "callGeneric"!
// Decide which TypeSpec to supply to BuildMethodRefName:
// 1) If the caller passed a non-null genericType (i.e. we’re inside SimpleList<I4>),
// use that, so ResizeArray prints as SimpleList<I4>::ResizeArray.
// 2) Otherwise, fall back to xref.genericType (the raw MethodRef own owner).
const CLR_RT_TypeSpec_Index *ownerTypeSpec;
if (genericType != nullptr && NANOCLR_INDEX_IS_VALID(*genericType))
{
ownerTypeSpec = genericType;
}
else
{
ownerTypeSpec = &xref.genericType;
}

char buf[256], *p = buf;
size_t cb = sizeof(buf);
g_CLR_RT_TypeSystem.BuildMethodRefName(
mri,
&xref.genericType, // THIS is the TypeSpec for SimpleList<I4>
p,
cb);
g_CLR_RT_TypeSystem.BuildMethodRefName(mri, ownerTypeSpec, p, cb);
CLR_Debug::Printf("%s", buf);
break;
}
case TBL_TypeDef:
{
// A genuine TypeDef token—print its (possibly non‐generic) name.
LOOKUP_ELEMENT_IDX(index, TypeDef, TYPEDEF);
CLR_RT_DUMP::TYPE(s);
CLR_UINT32 idx = CLR_DataFromTk(token);
CLR_RT_TypeDef_Index td;
td.Set(assemblyIndex, idx);

char buf[256], *p = buf;
size_t cb = sizeof(buf);

g_CLR_RT_TypeSystem.BuildTypeName(td, p, cb);
CLR_Debug::Printf("%s", buf);
break;
}
case TBL_TypeSpec:
Expand Down Expand Up @@ -857,7 +872,7 @@ void CLR_RT_Assembly::DumpOpcodeDirect(
if (op == CEE_CALL || op == CEE_CALLVIRT)
{
CLR_RT_MethodDef_Instance mdInst{};
if (mdInst.ResolveToken(token, call.assembly))
if (mdInst.ResolveToken(token, call.assembly, call.genericType))
{
// mdInst now holds the target MethodDef (or MethodSpec) plus any genericType.
CLR_RT_DUMP::METHOD(mdInst, mdInst.genericType);
Expand Down
2 changes: 1 addition & 1 deletion src/CLR/Include/nanoCLR_Runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -2172,7 +2172,7 @@ struct CLR_RT_MethodDef_Instance : public CLR_RT_MethodDef_Index
bool InitializeFromIndex(const CLR_RT_MethodDef_Index &index);
void ClearInstance();

bool ResolveToken(CLR_UINT32 tk, CLR_RT_Assembly *assm);
bool ResolveToken(CLR_UINT32 tk, CLR_RT_Assembly *assm, const CLR_RT_TypeSpec_Index *callerGeneric);

//--//

Expand Down