Skip to content

Conversation

josesimoes
Copy link
Member

@josesimoes josesimoes commented Oct 17, 2025

Description

  • 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.

Motivation and Context

How Has This Been Tested?

Screenshots

Types of changes

  • Improvement (non-breaking change that improves a feature, code or algorithm)
  • Bug fix (non-breaking change which fixes an issue with code or algorithm)
  • New feature (non-breaking change which adds functionality to code)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Config and build (change in the configuration and build system, has no impact on code or features)
  • Dev Containers (changes related with Dev Containers, has no impact on code or features)
  • Dependencies/declarations (update dependencies or assembly declarations and changes associated, has no impact on code or features)
  • Documentation (changes or updates in the documentation, has no impact on code or features)

Checklist

  • My code follows the code style of this project (only if there are changes in source code).
  • My changes require an update to the documentation (there are changes that require the docs website to be updated).
  • I have updated the documentation accordingly (the changes require an update on the docs in this repo).
  • I have read the CONTRIBUTING document.
  • I have tested everything locally and all new and existing tests passed (only if there are changes in source code).

Summary by CodeRabbit

  • Bug Fixes
    • Improved robustness of method resolution in cross-assembly scenarios involving generic types. The system now more reliably resolves method references when the generic type owner assembly differs from the method's assembly, reducing potential resolution failures.

- 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.
@josesimoes josesimoes added the Area: Common libs Everything related with common libraries label Oct 17, 2025
Copy link
Contributor

coderabbitai bot commented Oct 17, 2025

Walkthrough

Refactored cross-assembly method resolution in CLR's type system. Renamed variable mdRebound to mdResolved and replaced simple rebinding logic with robust MethodRef lookups across assemblies when generic type owner assembly differs from method assembly. Adds fallback to original method reference if no matching MethodRef found.

Changes

Cohort / File(s) Summary
Type system cross-assembly resolution
src/CLR/Core/TypeSystem.cpp
Refactored CLR_RT_MethodDef_Instance::InitializeFromIndex() to implement cross-assembly method resolution: renamed mdRebound to mdResolved; added logic to detect assembly mismatch, locate original MethodDef, search target assembly's MethodRef table for matching reference by name, validate cross-reference target; maintains fallback to original method reference when no match found

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant InitializeFromIndex as CLR_RT_MethodDef_Instance<br/>InitializeFromIndex()
    participant OwnerAssembly as Owner Assembly
    participant MethodDefTable as Original Assembly<br/>MethodDef Table
    participant MethodRefTable as Target Assembly<br/>MethodRef Table
    participant CrossRef as MethodRef<br/>Cross-Reference

    Caller->>InitializeFromIndex: md, typeSpec
    alt ownerAssembly != md.Assembly()
        Note over InitializeFromIndex: Cross-assembly case
        InitializeFromIndex->>OwnerAssembly: Locate original MethodDef
        InitializeFromIndex->>MethodRefTable: Search by method name
        alt MethodRef found
            InitializeFromIndex->>CrossRef: Validate cross-ref target<br/>matches original
            alt Cross-ref valid
                InitializeFromIndex->>InitializeFromIndex: mdResolved = original method
            else Cross-ref invalid
                InitializeFromIndex->>InitializeFromIndex: mdResolved = md (fallback)
            end
        else MethodRef not found
            InitializeFromIndex->>InitializeFromIndex: mdResolved = md (fallback)
        end
    else Same assembly
        Note over InitializeFromIndex: Same-assembly case
        InitializeFromIndex->>InitializeFromIndex: mdResolved = md
    end
    InitializeFromIndex->>InitializeFromIndex: InitializeFromIndex(mdResolved)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

The change involves logic modifications to a core type system function with cross-assembly resolution semantics. Review requires understanding MethodRef lookup mechanics, assembly cross-references, and validating the fallback behavior for edge cases, but the change is localized to a single method.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Fix rebinding logic in MethodDef_Instance::InitializeFromIndex()" is fully aligned with the main change in this PR. The core modification centers on replacing the previous blind rebinding approach with robust cross-assembly resolution logic in the specified method, and the title accurately captures this. The title is concise, specific enough for scanning history, mentions the exact function being modified, and uses "fix" appropriately since this is a bug fix. It does not include extraneous details like file lists or vague terminology, and a teammate would understand the primary change from the title alone.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@josesimoes
Copy link
Member Author

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Oct 17, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/CLR/Core/TypeSystem.cpp (2)

1644-1644: Initialize mdResolved with md upfront.

Avoid partial field assignment and make intent explicit.

-    CLR_RT_MethodDef_Index mdResolved;
+    CLR_RT_MethodDef_Index mdResolved = md;

1664-1707: Cross-assembly scan is a no-op; remove or make it actually resolve.

The loop only compares names and in all paths sets mdResolved.data = md.data, so behavior never changes while adding O(n) cost and confusion. Either delete the block and keep the original md, or implement signature-based resolution.

Minimal cleanup (recommended):

-    // 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;
-                }
-            }
-        }
-
-        if (!found)
-        {
-            // Fallback: keep the original method reference
-            mdResolved.data = md.data;
-        }
-    }
-    else
-    {
-        // Same assembly case: no rebinding needed
-        mdResolved.data = md.data;
-    }
+    // No rebinding needed; keep original method index (rebinding caused issues previously).

If you intended a real resolution, prefer matching by signature (name+signature) as done in ResolveMethodRef/FindMethodDef rather than name-only, and only rebind when a definitive match is found.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13fefc5 and 5651eb1.

📒 Files selected for processing (1)
  • src/CLR/Core/TypeSystem.cpp (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: nf-interpreter (Build_Azure_RTOS_targets SL_STK3701A)
  • GitHub Check: nf-interpreter (Build_WIN32_nanoCLR)
  • GitHub Check: nf-interpreter (Build_ESP32_targets ESP32_P4_UART)
  • GitHub Check: nf-interpreter (Build_ESP32_targets ESP32_ETHERNET_KIT_1.2)
  • GitHub Check: nf-interpreter (Build_ESP32_targets ESP32_S3_ALL)
  • GitHub Check: nf-interpreter (Build_ESP32_targets ESP32_H2_THREAD)
  • GitHub Check: nf-interpreter (Build_ESP32_targets ESP32_C6_THREAD)
  • GitHub Check: nf-interpreter (Build_ESP32_targets ESP32_C3)
  • GitHub Check: nf-interpreter (Build_ESP32_targets ESP32_BLE_REV0)
  • GitHub Check: nf-interpreter (Build_STM32_targets ST_STM32F769I_DISCOVERY)
  • GitHub Check: nf-interpreter (Build_STM32_targets ST_STM32F429I_DISCOVERY)
  • GitHub Check: nf-interpreter (Build_NXP_targets NXP_MIMXRT1060_EVK)
  • GitHub Check: nf-interpreter (Build_ESP32_targets ESP32_PSRAM_REV0)
  • GitHub Check: nf-interpreter (Build_TI_SimpleLink_targets TI_CC1352R1_LAUNCHXL_915)
  • GitHub Check: nf-interpreter (Nightly build) (Build_STM32_targets ORGPAL_PALX)
  • GitHub Check: nf-interpreter (Nightly build) (Build_STM32_targets ORGPAL_PALTHREE)
  • GitHub Check: nf-interpreter (Check_Code_Style)
  • GitHub Check: nf-interpreter (Nightly build) (Check_Build_Options)
  • GitHub Check: nf-interpreter (Check_Build_Options)

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

Labels

Area: Common libs Everything related with common libraries Type: bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants