diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 953c0230a9a728..a6b32288f2818b 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -2158,6 +2158,7 @@ ves_icall_RuntimeFieldInfo_SetValueInternal (MonoReflectionFieldHandle field, Mo case MONO_TYPE_R8: case MONO_TYPE_VALUETYPE: case MONO_TYPE_PTR: + case MONO_TYPE_FNPTR: isref = FALSE; if (!MONO_HANDLE_IS_NULL (value)) { if (m_class_is_valuetype (mono_handle_class (value))) diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index e39bece1f9e508..c1dbc302cb47bd 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -2989,7 +2989,7 @@ mono_field_set_value_internal (MonoObject *obj, MonoClassField *field, void *val } else dest = (char*)obj + m_field_get_offset (field); - mono_copy_value (field->type, dest, value, value && field->type->type == MONO_TYPE_PTR); + mono_copy_value (field->type, dest, value, value && (field->type->type == MONO_TYPE_PTR || field->type->type == MONO_TYPE_FNPTR)); } /** @@ -3022,7 +3022,7 @@ mono_field_static_set_value_internal (MonoVTable *vt, MonoClassField *field, voi return; dest = mono_static_field_get_addr (vt, field); - mono_copy_value (field->type, dest, value, value && field->type->type == MONO_TYPE_PTR); + mono_copy_value (field->type, dest, value, value && (field->type->type == MONO_TYPE_PTR || field->type->type == MONO_TYPE_FNPTR)); } gpointer @@ -3234,6 +3234,7 @@ mono_field_get_value_object_checked (MonoClassField *field, MonoObject *obj, Mon gboolean is_ref = FALSE; gboolean is_literal = FALSE; gboolean is_ptr = FALSE; + gboolean is_fnptr = FALSE; MonoStringHandle string_handle = MONO_HANDLE_NEW (MonoString, NULL); @@ -3272,6 +3273,9 @@ mono_field_get_value_object_checked (MonoClassField *field, MonoObject *obj, Mon case MONO_TYPE_PTR: is_ptr = TRUE; break; + case MONO_TYPE_FNPTR: + is_fnptr = TRUE; + break; default: g_error ("type 0x%x not handled in " "mono_field_get_value_object", type->type); @@ -3344,6 +3348,12 @@ mono_field_get_value_object_checked (MonoClassField *field, MonoObject *obj, Mon goto exit; } + if (G_UNLIKELY (is_fnptr)) { + // CoreCLR behavior: returns an IntPtr value if we're getting a function pointer field. + // Does not return a System.Reflection.Pointer value in this case + type = mono_get_int_type (); + } + /* boxed value type */ klass = mono_class_from_mono_type_internal (type);