Skip to content

Commit f513349

Browse files
monojenkinsrbernon
andauthored
[metadata] Generate type-3 GUIDs for interfaces. (dotnet#43677)
I'm opening this although it's still WIP, for discussion, as I'm not sure what else I should be adding. Tests probably, of course, but also I was wondering if it should be plugged to RuntimeType.GUID / Marshal.GenerateGuidForType. I'm not entirely sure if that's desired as I've seen clues in the reference source that the GUID generation has issues. I've left class GUID generation aside, as it doesn't seem so useful for COM interop, and the algorithm uses some Assembly properties to seed the GUID, and retrieving that is currently beyond my understanding of the code. Also I'm a bit lost regarding which RuntimeType.GUID it should be added to: there's at least two places that looked appropriate : in `mono/netcore/System.Private.CoreLib/src/RuntimeType.Mono.cs` and in `mono/mcs/class/corlib/ReferenceSources/RuntimeType.cs`. Co-authored-by: rbernon <[email protected]>
1 parent 6553a49 commit f513349

File tree

10 files changed

+409
-41
lines changed

10 files changed

+409
-41
lines changed

src/mono/mono/metadata/cominterop.c

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ GENERATE_GET_CLASS_WITH_CACHE (com_object, "System", "__ComObject")
150150
GENERATE_GET_CLASS_WITH_CACHE (variant, "System", "Variant")
151151

152152
static GENERATE_GET_CLASS_WITH_CACHE (interface_type_attribute, "System.Runtime.InteropServices", "InterfaceTypeAttribute")
153-
static GENERATE_GET_CLASS_WITH_CACHE (guid_attribute, "System.Runtime.InteropServices", "GuidAttribute")
154153
static GENERATE_GET_CLASS_WITH_CACHE (com_visible_attribute, "System.Runtime.InteropServices", "ComVisibleAttribute")
155154
static GENERATE_GET_CLASS_WITH_CACHE (com_default_interface_attribute, "System.Runtime.InteropServices", "ComDefaultInterfaceAttribute")
156155
static GENERATE_GET_CLASS_WITH_CACHE (class_interface_attribute, "System.Runtime.InteropServices", "ClassInterfaceAttribute")
@@ -487,30 +486,13 @@ cominterop_get_com_slot_for_method (MonoMethod* method, MonoError* error)
487486
return slot + cominterop_get_com_slot_begin (ic);
488487
}
489488

490-
static void
491-
cominterop_mono_string_to_guid (MonoString* string, guint8 *guid);
492-
493489
static gboolean
494490
cominterop_class_guid (MonoClass* klass, guint8* guid)
495491
{
496492
ERROR_DECL (error);
497-
MonoCustomAttrInfo *cinfo;
498-
499-
cinfo = mono_custom_attrs_from_class_checked (klass, error);
500-
mono_error_assert_ok (error);
501-
if (cinfo) {
502-
MonoReflectionGuidAttribute *attr = (MonoReflectionGuidAttribute*)mono_custom_attrs_get_attr_checked (cinfo, mono_class_get_guid_attribute_class (), error);
503-
mono_error_assert_ok (error); /*FIXME proper error handling*/
504-
505-
if (!attr)
506-
return FALSE;
507-
if (!cinfo->cached)
508-
mono_custom_attrs_free (cinfo);
509-
510-
cominterop_mono_string_to_guid (attr->guid, guid);
511-
return TRUE;
512-
}
513-
return FALSE;
493+
mono_metadata_get_class_guid (klass, guid, error);
494+
mono_error_assert_ok (error); /*FIXME proper error handling*/
495+
return TRUE;
514496
}
515497

516498
static gboolean
@@ -552,8 +534,8 @@ cominterop_com_visible (MonoClass* klass)
552534

553535
}
554536

555-
static gboolean
556-
cominterop_method_com_visible (MonoMethod *method)
537+
gboolean
538+
mono_cominterop_method_com_visible (MonoMethod *method)
557539
{
558540
ERROR_DECL (error);
559541
MonoCustomAttrInfo *cinfo;
@@ -2157,7 +2139,7 @@ cominterop_class_method_is_visible (MonoMethod *method)
21572139
if (flags & METHOD_ATTRIBUTE_RT_SPECIAL_NAME)
21582140
return FALSE;
21592141

2160-
if (!cominterop_method_com_visible (method))
2142+
if (!mono_cominterop_method_com_visible (method))
21612143
return FALSE;
21622144

21632145
/* if the method is an override, ignore it and use the original definition */
@@ -2713,22 +2695,6 @@ cominterop_get_managed_wrapper_adjusted (MonoMethod *method)
27132695
return res;
27142696
}
27152697

2716-
/**
2717-
* cominterop_mono_string_to_guid:
2718-
*
2719-
* Converts the standard string representation of a GUID
2720-
* to a 16 byte Microsoft GUID.
2721-
*/
2722-
static void
2723-
cominterop_mono_string_to_guid (MonoString* string, guint8 *guid) {
2724-
gunichar2 * chars = mono_string_chars_internal (string);
2725-
int i = 0;
2726-
static const guint8 indexes[16] = {7, 5, 3, 1, 12, 10, 17, 15, 20, 22, 25, 27, 29, 31, 33, 35};
2727-
2728-
for (i = 0; i < sizeof(indexes); i++)
2729-
guid [i] = g_unichar_xdigit_value (chars [indexes [i]]) + (g_unichar_xdigit_value (chars [indexes [i] - 1]) << 4);
2730-
}
2731-
27322698
static gboolean
27332699
cominterop_class_guid_equal (const guint8* guid, MonoClass* klass)
27342700
{

src/mono/mono/metadata/cominterop.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,7 @@ mono_cominterop_get_com_interface (MonoObject* object, MonoClass* ic, MonoError
7373
gboolean
7474
mono_cominterop_is_interface (MonoClass* klass);
7575

76+
gboolean
77+
mono_cominterop_method_com_visible (MonoMethod *method);
78+
7679
#endif /* __MONO_COMINTEROP_H__ */

src/mono/mono/metadata/icall-def.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,7 @@ HANDLES(RT_30, "GetCorrespondingInflatedConstructor", ves_icall_RuntimeType_GetC
872872
HANDLES_REUSE_WRAPPER(RT_31, "GetCorrespondingInflatedMethod", ves_icall_RuntimeType_GetCorrespondingInflatedMethod)
873873
HANDLES(RT_3, "GetEvents_native", ves_icall_RuntimeType_GetEvents_native, GPtrArray_ptr, 3, (MonoReflectionType, char_ptr, guint32))
874874
HANDLES(RT_5, "GetFields_native", ves_icall_RuntimeType_GetFields_native, GPtrArray_ptr, 4, (MonoReflectionType, char_ptr, guint32, guint32))
875+
HANDLES(RT_32, "GetGUID", ves_icall_RuntimeType_GetGUID, void, 2, (MonoReflectionType, MonoArray))
875876
HANDLES(RT_6, "GetGenericArgumentsInternal", ves_icall_RuntimeType_GetGenericArguments, MonoArray, 2, (MonoReflectionType, MonoBoolean))
876877
HANDLES(RT_9, "GetGenericParameterPosition", ves_icall_RuntimeType_GetGenericParameterPosition, gint32, 1, (MonoReflectionType))
877878
HANDLES(RT_10, "GetInterfaceMapData", ves_icall_RuntimeType_GetInterfaceMapData, void, 4, (MonoReflectionType, MonoReflectionType, MonoArrayOut, MonoArrayOut))

src/mono/mono/metadata/icall.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3294,6 +3294,28 @@ set_type_object_in_array (MonoDomain *domain, MonoType *type, MonoArrayHandle de
32943294
HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
32953295
}
32963296

3297+
#ifndef ENABLE_NETCORE
3298+
void
3299+
ves_icall_RuntimeType_GetGUID (MonoReflectionTypeHandle type_handle, MonoArrayHandle guid_handle, MonoError *error)
3300+
{
3301+
error_init (error);
3302+
3303+
g_assert (mono_array_handle_length (guid_handle) == 16);
3304+
if (MONO_HANDLE_IS_NULL (type_handle)) {
3305+
mono_error_set_argument_null (error, "type", "");
3306+
return;
3307+
}
3308+
3309+
MonoType *type = MONO_HANDLE_GETVAL (type_handle, type);
3310+
MonoClass *klass = mono_class_from_mono_type_internal (type);
3311+
if (!mono_class_init_checked (klass, error))
3312+
return;
3313+
3314+
guint8 *data = (guint8*) mono_array_addr_with_size_internal (MONO_HANDLE_RAW (guid_handle), 1, 0);
3315+
mono_metadata_get_class_guid (klass, data, error);
3316+
}
3317+
#endif
3318+
32973319
MonoArrayHandle
32983320
ves_icall_RuntimeType_GetGenericArguments (MonoReflectionTypeHandle ref_type, MonoBoolean runtimeTypeArray, MonoError *error)
32993321
{

src/mono/mono/metadata/metadata-internals.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,9 @@ mono_type_is_valid_generic_argument (MonoType *type);
11821182
MonoAssemblyContextKind
11831183
mono_asmctx_get_kind (const MonoAssemblyContext *ctx);
11841184

1185+
void
1186+
mono_metadata_get_class_guid (MonoClass* klass, uint8_t* guid, MonoError *error);
1187+
11851188
#define MONO_CLASS_IS_INTERFACE_INTERNAL(c) ((mono_class_get_flags (c) & TYPE_ATTRIBUTE_INTERFACE) || mono_type_is_generic_parameter (m_class_get_byval_arg (c)))
11861189

11871190
static inline gboolean

0 commit comments

Comments
 (0)