Skip to content

Commit 5651eb1

Browse files
committed
Fix rebinding logic in MethodDef_Instance::InitializeFromIndex()
- Instead of blindly rebing methodDef it now checks if that is required and goes through it's paces on finding the correct method in the correct assembly.
1 parent 13fefc5 commit 5651eb1

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

src/CLR/Core/TypeSystem.cpp

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,7 +1641,7 @@ bool CLR_RT_MethodDef_Instance::InitializeFromIndex(
16411641
}
16421642

16431643
CLR_RT_TypeDef_Index ownerTypeIdx;
1644-
CLR_RT_MethodDef_Index mdRebound;
1644+
CLR_RT_MethodDef_Index mdResolved;
16451645

16461646
if (elem.DataType == DATATYPE_VAR)
16471647
{
@@ -1661,10 +1661,52 @@ bool CLR_RT_MethodDef_Instance::InitializeFromIndex(
16611661
ownerTypeIdx.data = elem.Class.data;
16621662
}
16631663

1664-
// rebind the method onto the *declaring* assembly of the generic
1665-
mdRebound.data = (ownerTypeIdx.Assembly() << 24) | md.Method();
1664+
// try to find the correct method reference
1665+
if (ownerTypeIdx.Assembly() != md.Assembly())
1666+
{
1667+
// Cross-assembly case: need to find the corresponding MethodRef/MethodDef
1668+
CLR_RT_Assembly *originalAssm = g_CLR_RT_TypeSystem.m_assemblies[md.Assembly() - 1];
1669+
CLR_RT_Assembly *targetAssm = g_CLR_RT_TypeSystem.m_assemblies[ownerTypeIdx.Assembly() - 1];
1670+
1671+
// Get the original method information
1672+
const CLR_RECORD_METHODDEF *originalMD = originalAssm->GetMethodDef(md.Method());
1673+
const char *methodName = originalAssm->GetString(originalMD->name);
1674+
1675+
// Try to find the method in the target assembly by looking through MethodRefs
1676+
bool found = false;
1677+
for (int i = 0; i < targetAssm->tablesSize[TBL_MethodRef]; i++)
1678+
{
1679+
const CLR_RECORD_METHODREF *mr = targetAssm->GetMethodRef(i);
1680+
const char *refName = targetAssm->GetString(mr->name);
1681+
1682+
if (!strcmp(methodName, refName))
1683+
{
1684+
// Found a potential match, now check if it resolves to our original method
1685+
CLR_RT_MethodRef_CrossReference &crossRef = targetAssm->crossReferenceMethodRef[i];
1686+
1687+
if (crossRef.target.data == md.data)
1688+
{
1689+
// This MethodRef points to our original method!
1690+
mdResolved.data = md.data;
1691+
found = true;
1692+
break;
1693+
}
1694+
}
1695+
}
1696+
1697+
if (!found)
1698+
{
1699+
// Fallback: keep the original method reference
1700+
mdResolved.data = md.data;
1701+
}
1702+
}
1703+
else
1704+
{
1705+
// Same assembly case: no rebinding needed
1706+
mdResolved.data = md.data;
1707+
}
16661708

1667-
if (!InitializeFromIndex(mdRebound))
1709+
if (!InitializeFromIndex(mdResolved))
16681710
{
16691711
return false;
16701712
}

0 commit comments

Comments
 (0)