Skip to content

Commit

Permalink
[cdac] Fix getting array function type in RuntimeTypeSystem.IsArrayMe…
Browse files Browse the repository at this point in the history
…thod (dotnet#106512)

- Array method index should be the slot minus the number of virtuals, not the number of slots
- Constructor index should include 3, not just greater than
  • Loading branch information
elinor-fung committed Aug 20, 2024
1 parent 80f5d44 commit 7cd266e
Showing 1 changed file with 20 additions and 3 deletions.
23 changes: 20 additions & 3 deletions src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -678,14 +678,24 @@ public bool IsArrayMethod(MethodDescHandle methodDescHandle, out ArrayFunctionTy
return false;
}

int arrayMethodIndex = methodDesc.Slot - GetNumVtableSlots(GetTypeHandle(methodDesc.MethodTable));

// To get the array function index, subtract the number of virtuals from the method's slot
// The array vtable looks like:
// System.Object vtable
// System.Array vtable
// type[] vtable
// Get
// Set
// Address
// .ctor // possibly more
// See ArrayMethodDesc for details in coreclr
MethodTable methodTable = GetOrCreateMethodTable(methodDesc);
int arrayMethodIndex = methodDesc.Slot - methodTable.NumVirtuals;
functionType = arrayMethodIndex switch
{
0 => ArrayFunctionType.Get,
1 => ArrayFunctionType.Set,
2 => ArrayFunctionType.Address,
> 3 => ArrayFunctionType.Constructor,
>= 3 => ArrayFunctionType.Constructor,
_ => throw new InvalidOperationException()
};

Expand Down Expand Up @@ -749,4 +759,11 @@ public bool IsILStub(MethodDescHandle methodDescHandle)

return AsDynamicMethodDesc(methodDesc).IsILStub;
}

private MethodTable GetOrCreateMethodTable(MethodDesc methodDesc)
{
// Ensures that the method table is valid, created, and cached
_ = GetTypeHandle(methodDesc.MethodTable);
return _methodTables[methodDesc.MethodTable];
}
}

0 comments on commit 7cd266e

Please sign in to comment.