From 7cd266e3ad282d94e19664c6078ee699b9a5cc3e Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 20 Aug 2024 10:04:01 -0700 Subject: [PATCH] [cdac] Fix getting array function type in RuntimeTypeSystem.IsArrayMethod (#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 --- .../src/Contracts/RuntimeTypeSystem_1.cs | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.cs b/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.cs index e45b1fbfd2724..2584f2c8cc8ef 100644 --- a/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.cs +++ b/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.cs @@ -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() }; @@ -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]; + } }