Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b79c57e

Browse files
authored
Fix field accessor for RVA field (#103705)
* Revert "Separate RVA reflection change out" This reverts commit 089ae12. * Fix FieldAccessor getting RVA field * Disable test on NativeAot
1 parent 71ab8f1 commit b79c57e

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

src/coreclr/vm/reflectioninvocation.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,14 +1246,16 @@ FCIMPL1(void*, RuntimeFieldHandle::GetStaticFieldAddress, ReflectFieldObject *pF
12461246
// IsFastPathSupported needs to checked before calling this method.
12471247
_ASSERTE(IsFastPathSupportedHelper(pFieldDesc));
12481248

1249-
PTR_BYTE base = 0;
1250-
if (!pFieldDesc->IsRVA())
1249+
if (pFieldDesc->IsRVA())
12511250
{
1252-
// For RVA the base is ignored and offset is used.
1253-
base = pFieldDesc->GetBase();
1251+
Module* pModule = pFieldDesc->GetModule();
1252+
return pModule->GetRvaField(pFieldDesc->GetOffset());
1253+
}
1254+
else
1255+
{
1256+
PTR_BYTE base = pFieldDesc->GetBase();
1257+
return PTR_VOID(base + pFieldDesc->GetOffset());
12541258
}
1255-
1256-
return PTR_VOID(base + pFieldDesc->GetOffset());
12571259
}
12581260
FCIMPLEND
12591261

src/libraries/System.Private.CoreLib/src/System/Reflection/FieldAccessor.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ private void Initialize()
4848
{
4949
_addressOrOffset = RuntimeFieldHandle.GetStaticFieldAddress(_fieldInfo);
5050

51-
if (fieldType.IsValueType)
51+
if ((_fieldInfo.Attributes & FieldAttributes.HasFieldRVA) != 0)
52+
{
53+
_methodTable = (MethodTable*)fieldType.TypeHandle.Value;
54+
_fieldAccessType = FieldAccessorType.StaticValueType;
55+
}
56+
else if (fieldType.IsValueType)
5257
{
5358
if (fieldType.IsEnum)
5459
{

src/libraries/System.Runtime/tests/System.Reflection.Tests/FieldInfoTests.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System.Diagnostics;
66
using System.Diagnostics.CodeAnalysis;
77
using System.Linq;
8+
using System.Runtime.CompilerServices;
9+
using System.Runtime.InteropServices;
810
using Xunit;
911

1012
#pragma warning disable 0414
@@ -121,6 +123,30 @@ public void GetValueWithFunctionPointers(Type type, string name, object obj, obj
121123
Assert.Equal(expected, fieldInfo.GetValue(obj));
122124
}
123125

126+
// RVA field reflection is not supported in NativeAot
127+
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNativeAot))]
128+
public void GetValueFromRvaField()
129+
{
130+
byte[] valueArray = new byte[] { 1, 2, 3, 4, 5 };
131+
132+
// Roslyn uses SHA256 of raw data as data field name
133+
FieldInfo fieldInfo = GetField(
134+
typeof(FieldInfoTests).Assembly.GetType("<PrivateImplementationDetails>"),
135+
"74F81FE167D99B4CB41D6D0CCDA82278CAEE9F3E2F25D5E5A3936FF3DCEC60D0");
136+
Assert.NotNull(fieldInfo);
137+
Assert.True(fieldInfo.IsStatic);
138+
Assert.True((fieldInfo.Attributes & FieldAttributes.HasFieldRVA) != 0);
139+
140+
for (int i = 0; i < 5; i++)
141+
{
142+
// FieldAccessor uses slow path until the class is initialized.
143+
// Make sure subsequent invocations also succeed.
144+
145+
object value = fieldInfo.GetValue(null);
146+
Assert.Equal(valueArray, MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<object, RawData>(ref value).Data, valueArray.Length));
147+
}
148+
}
149+
124150
[Fact]
125151
public void GetAndSetValueTypeFromStatic()
126152
{
@@ -839,5 +865,10 @@ public static class SettingsForMyTypeThatThrowsInClassInitializer
839865
{
840866
public static bool s_shouldThrow = true;
841867
}
868+
869+
private class RawData
870+
{
871+
public byte Data;
872+
}
842873
}
843874
}

0 commit comments

Comments
 (0)