-
-
Notifications
You must be signed in to change notification settings - Fork 186
Fix rebinding logic in MethodDef_Instance::InitializeFromIndex() #3221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1641,7 +1641,7 @@ bool CLR_RT_MethodDef_Instance::InitializeFromIndex( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLR_RT_TypeDef_Index ownerTypeIdx; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLR_RT_MethodDef_Index mdRebound; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLR_RT_MethodDef_Index mdResolved; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (elem.DataType == DATATYPE_VAR) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1661,10 +1661,52 @@ bool CLR_RT_MethodDef_Instance::InitializeFromIndex( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ownerTypeIdx.data = elem.Class.data; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // rebind the method onto the *declaring* assembly of the generic | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mdRebound.data = (ownerTypeIdx.Assembly() << 24) | md.Method(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // try to find the correct method reference | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (ownerTypeIdx.Assembly() != md.Assembly()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Cross-assembly case: need to find the corresponding MethodRef/MethodDef | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLR_RT_Assembly *originalAssm = g_CLR_RT_TypeSystem.m_assemblies[md.Assembly() - 1]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLR_RT_Assembly *targetAssm = g_CLR_RT_TypeSystem.m_assemblies[ownerTypeIdx.Assembly() - 1]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Get the original method information | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const CLR_RECORD_METHODDEF *originalMD = originalAssm->GetMethodDef(md.Method()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const char *methodName = originalAssm->GetString(originalMD->name); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Try to find the method in the target assembly by looking through MethodRefs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool found = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (int i = 0; i < targetAssm->tablesSize[TBL_MethodRef]; i++) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const CLR_RECORD_METHODREF *mr = targetAssm->GetMethodRef(i); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const char *refName = targetAssm->GetString(mr->name); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!strcmp(methodName, refName)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Found a potential match, now check if it resolves to our original method | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLR_RT_MethodRef_CrossReference &crossRef = targetAssm->crossReferenceMethodRef[i]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (crossRef.target.data == md.data) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // This MethodRef points to our original method! | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mdResolved.data = md.data; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| found = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1684
to
+1692
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Found a potential match, now check if it resolves to our original method | |
| CLR_RT_MethodRef_CrossReference &crossRef = targetAssm->crossReferenceMethodRef[i]; | |
| if (crossRef.target.data == md.data) | |
| { | |
| // This MethodRef points to our original method! | |
| mdResolved.data = md.data; | |
| found = true; | |
| break; | |
| // Compare signatures to ensure correct method match | |
| CLR_RT_SignatureParser sigParserOriginal; | |
| CLR_RT_SignatureParser sigParserCandidate; | |
| // Parse the signature of the original method | |
| sigParserOriginal.Initialize_Method(originalAssm, originalMD); | |
| // Parse the signature of the candidate method reference | |
| sigParserCandidate.Initialize_MethodRef(targetAssm, mr); | |
| if (CLR_RT_TypeSystem::MatchSignature(sigParserOriginal, sigParserCandidate)) | |
| { | |
| // Found a potential match, now check if it resolves to our original method | |
| CLR_RT_MethodRef_CrossReference &crossRef = targetAssm->crossReferenceMethodRef[i]; | |
| if (crossRef.target.data == md.data) | |
| { | |
| // This MethodRef points to our original method! | |
| mdResolved.data = md.data; | |
| found = true; | |
| break; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot Method signatures will be different depending on a type being a closed or open generic... signatures can't be compared on an exact match.
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method resolution logic is incorrect. When a matching MethodRef is found (line 1687), the code sets mdResolved.data to md.data (the original method), but it should construct a new method index using the target assembly and the MethodRef index. The resolved method should be: mdResolved.data = (ownerTypeIdx.Assembly() << 24) | i; This defeats the purpose of the cross-assembly resolution.
Uh oh!
There was an error while loading. Please reload this page.