Skip to content

Commit

Permalink
Remove built-in COM interop support from Mono runtime (#97789)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkoritzinsky authored Feb 8, 2024
1 parent ac14935 commit 7f4702a
Show file tree
Hide file tree
Showing 32 changed files with 171 additions and 5,190 deletions.
2 changes: 0 additions & 2 deletions src/mono/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ if(ENABLE_MINIMAL)
process_enable_minimal()
endif()

set(DISABLE_COM 1)

# Dependencies between options
if(ENABLE_INTERP_LIB)
set(DISABLE_INTERPRETER 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,6 @@ internal static bool HasElementType(RuntimeType type)
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool HasInstantiation(QCallTypeHandle type);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool IsComObject(QCallTypeHandle type);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool IsInstanceOfType(QCallTypeHandle type, [NotNullWhen(true)] object? o);

Expand All @@ -234,10 +231,13 @@ internal static bool HasInstantiation(RuntimeType type)
return HasInstantiation(new QCallTypeHandle(ref type));
}

#pragma warning disable IDE0060
internal static bool IsComObject(RuntimeType type, bool isGenericCOM)
{
return isGenericCOM ? false : IsComObject(new QCallTypeHandle(ref type));
// Mono runtime doesn't support built-in COM.
return false;
}
#pragma warning restore IDE0060

#pragma warning disable IDE0060
internal static bool IsEquivalentTo(RuntimeType rtType1, RuntimeType rtType2)
Expand Down
3 changes: 0 additions & 3 deletions src/mono/cmake/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,6 @@
/* Disable support debug logging */
#cmakedefine DISABLE_LOGGING 1

/* Disable COM support */
#cmakedefine DISABLE_COM 1

/* Disable advanced SSA JIT optimizations */
#cmakedefine DISABLE_SSA 1

Expand Down
1 change: 0 additions & 1 deletion src/mono/cmake/options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ option (DISABLE_AOT "Disable AOT Compiler")
option (DISABLE_DEBUG "Disable runtime debugging support")
option (DISABLE_REFLECTION_EMIT "Disable reflection emit support")
option (DISABLE_LOGGING "Disable support debug logging")
option (DISABLE_COM "Disable COM support")
option (DISABLE_SSA "Disable advanced SSA JIT optimizations")
option (DISABLE_JIT "Disable the JIT, only full-aot mode or interpreter will be supported by the runtime.")
option (DISABLE_INTERPRETER "Disable the interpreter.")
Expand Down
128 changes: 0 additions & 128 deletions src/mono/mono/component/marshal-ilgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,15 +414,6 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
switch (spec->native) {
case MONO_NATIVE_LPARRAY:
break;
case MONO_NATIVE_SAFEARRAY:
#ifndef DISABLE_COM
if (spec->data.safearray_data.elem_type != MONO_VARIANT_VARIANT) {
char *msg = g_strdup ("Only SAFEARRAY(VARIANT) marshalling to managed code is implemented.");
cb_to_mono->methodBuilder.emit_exception_marshal_directive (mb, msg);
return conv_arg;
}
return mono_cominterop_emit_marshal_safearray (m, argnum, t, spec, conv_arg, conv_arg_type, action);
#endif
default: {
char *msg = g_strdup ("Unsupported array type marshalling to managed code.");
cb_to_mono->methodBuilder.emit_exception_marshal_directive (mb, msg);
Expand Down Expand Up @@ -2618,108 +2609,6 @@ emit_marshal_object_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
return conv_arg;
}

static int
emit_marshal_variant_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
MonoMarshalSpec *spec,
int conv_arg, MonoType **conv_arg_type,
MarshalAction action)
{
#ifndef DISABLE_COM
MonoMethodBuilder *mb = m->mb;
MonoType *variant_type = m_class_get_byval_arg (mono_class_get_variant_class ());
MonoType *variant_type_byref = mono_class_get_byref_type (mono_class_get_variant_class ());
MonoType *object_type = cb_to_mono->get_object_type ();

switch (action) {
case MARSHAL_ACTION_CONV_IN: {
conv_arg = cb_to_mono->methodBuilder.add_local (mb, variant_type);

if (m_type_is_byref (t))
*conv_arg_type = variant_type_byref;
else
*conv_arg_type = variant_type;

if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && t->attrs & PARAM_ATTRIBUTE_OUT)
break;

cb_to_mono->methodBuilder.emit_ldarg (mb, argnum);
if (m_type_is_byref (t))
cb_to_mono->methodBuilder.emit_byte(mb, CEE_LDIND_REF);
cb_to_mono->methodBuilder.emit_ldloc_addr (mb, conv_arg);
cb_to_mono->methodBuilder.emit_managed_call (mb, mono_get_Marshal_GetNativeVariantForObject (), NULL);
break;
}

case MARSHAL_ACTION_CONV_OUT: {
if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN))) {
cb_to_mono->methodBuilder.emit_ldarg (mb, argnum);
cb_to_mono->methodBuilder.emit_ldloc_addr (mb, conv_arg);
cb_to_mono->methodBuilder.emit_managed_call (mb, mono_get_Marshal_GetObjectForNativeVariant (), NULL);
cb_to_mono->methodBuilder.emit_byte (mb, CEE_STIND_REF);
}

cb_to_mono->methodBuilder.emit_ldloc_addr (mb, conv_arg);
cb_to_mono->methodBuilder.emit_managed_call (mb, mono_get_Variant_Clear (), NULL);
break;
}

case MARSHAL_ACTION_PUSH:
if (m_type_is_byref (t))
cb_to_mono->methodBuilder.emit_ldloc_addr (mb, conv_arg);
else
cb_to_mono->methodBuilder.emit_ldloc (mb, conv_arg);
break;

case MARSHAL_ACTION_CONV_RESULT: {
char *msg = g_strdup ("Marshalling of VARIANT not supported as a return type.");
cb_to_mono->methodBuilder.emit_exception_marshal_directive (mb, msg);
break;
}

case MARSHAL_ACTION_MANAGED_CONV_IN: {
conv_arg = cb_to_mono->methodBuilder.add_local (mb, object_type);

if (m_type_is_byref (t))
*conv_arg_type = variant_type_byref;
else
*conv_arg_type = variant_type;

if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && t->attrs & PARAM_ATTRIBUTE_OUT)
break;

if (m_type_is_byref (t))
cb_to_mono->methodBuilder.emit_ldarg (mb, argnum);
else
cb_to_mono->methodBuilder.emit_ldarg_addr (mb, argnum);
cb_to_mono->methodBuilder.emit_managed_call (mb, mono_get_Marshal_GetObjectForNativeVariant (), NULL);
cb_to_mono->methodBuilder.emit_stloc (mb, conv_arg);
break;
}

case MARSHAL_ACTION_MANAGED_CONV_OUT: {
if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN))) {
cb_to_mono->methodBuilder.emit_ldloc (mb, conv_arg);
cb_to_mono->methodBuilder.emit_ldarg (mb, argnum);
cb_to_mono->methodBuilder.emit_managed_call (mb, mono_get_Marshal_GetNativeVariantForObject (), NULL);
}
break;
}

case MARSHAL_ACTION_MANAGED_CONV_RESULT: {
char *msg = g_strdup ("Marshalling of VARIANT not supported as a return type.");
cb_to_mono->methodBuilder.emit_exception_marshal_directive (mb, msg);
break;
}

default:
g_assert_not_reached ();
}
#endif /* DISABLE_COM */

return conv_arg;
}


static int
emit_marshal_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
MonoMarshalSpec *spec, int conv_arg,
Expand All @@ -2741,23 +2630,6 @@ emit_marshal_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
return emit_marshal_string_ilgen (m, argnum, t, spec, conv_arg, conv_arg_type, action);
case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
#if !defined(DISABLE_COM)
if (spec && spec->native == MONO_NATIVE_STRUCT)
return emit_marshal_variant_ilgen (m, argnum, t, spec, conv_arg, conv_arg_type, action);
#endif

#if !defined(DISABLE_COM)
if ((spec && (spec->native == MONO_NATIVE_IUNKNOWN ||
spec->native == MONO_NATIVE_IDISPATCH ||
spec->native == MONO_NATIVE_INTERFACE)) ||
(t->type == MONO_TYPE_CLASS && mono_cominterop_is_interface(t->data.klass)))
return mono_cominterop_emit_marshal_com_interface (m, argnum, t, spec, conv_arg, conv_arg_type, action);
if (spec && (spec->native == MONO_NATIVE_SAFEARRAY) &&
(spec->data.safearray_data.elem_type == MONO_VARIANT_VARIANT) &&
((action == MARSHAL_ACTION_CONV_OUT) || (action == MARSHAL_ACTION_CONV_IN) || (action == MARSHAL_ACTION_PUSH)))
return mono_cominterop_emit_marshal_safearray (m, argnum, t, spec, conv_arg, conv_arg_type, action);
#endif

if (cb_to_mono->try_get_safehandle_class () != NULL && t->data.klass &&
cb_to_mono->is_subclass_of_internal (t->data.klass, cb_to_mono->try_get_safehandle_class (), FALSE))
return emit_marshal_safehandle_ilgen (m, argnum, t, spec, conv_arg, conv_arg_type, action);
Expand Down
4 changes: 1 addition & 3 deletions src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ typedef struct _AssemblyEventData AssemblyEventData;
typedef enum {
TYPE_FLAGS_DELEGATE = 0x1,
TYPE_FLAGS_FINALIZABLE = 0x2,
TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT = 0x4,
// unused = 0x4,
TYPE_FLAGS_ARRAY = 0x8,

TYPE_FLAGS_ARRAY_RANK_MASK = 0x3F00,
Expand Down Expand Up @@ -1547,8 +1547,6 @@ bulk_type_log_single_type (
val->fixed_sized_data.flags |= TYPE_FLAGS_FINALIZABLE;
if (m_class_is_delegate (klass))
val->fixed_sized_data.flags |= TYPE_FLAGS_DELEGATE;
if (mono_class_is_com_object (klass))
val->fixed_sized_data.flags |= TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT;
val->fixed_sized_data.cor_element_type = (uint8_t)mono_underlying_type->type;

// Sets val variable sized parameter type data, type_parameters_count, and mono_type_parameters associated
Expand Down
2 changes: 0 additions & 2 deletions src/mono/mono/metadata/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ set(metadata_common_sources
class-private-definition.h
class-accessors.c
class-setup-vtable.c
cominterop.c
cominterop.h
components.h
components.c
debug-helpers.c
Expand Down
10 changes: 0 additions & 10 deletions src/mono/mono/metadata/class-accessors.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,16 +437,6 @@ mono_class_set_declsec_flags (MonoClass *klass, guint32 value)
mono_property_bag_add (m_class_get_infrequent_data (klass), prop);
}

void
mono_class_set_is_com_object (MonoClass *klass)
{
#ifndef DISABLE_COM
mono_loader_lock ();
klass->is_com_object = 1;
mono_loader_unlock ();
#endif
}

void
mono_class_set_is_simd_type (MonoClass *klass, gboolean is_simd)
{
Expand Down
1 change: 0 additions & 1 deletion src/mono/mono/metadata/class-getters.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ MONO_CLASS_GETTER(m_class_has_cctor, gboolean, , MonoClass, has_cctor)
MONO_CLASS_GETTER(m_class_has_references, gboolean, , MonoClass, has_references)
MONO_CLASS_GETTER(m_class_has_static_refs, gboolean, , MonoClass, has_static_refs)
MONO_CLASS_GETTER(m_class_has_no_special_static_fields, gboolean, , MonoClass, no_special_static_fields)
MONO_CLASS_GETTER(m_class_is_com_object, gboolean, , MonoClass, is_com_object)
MONO_CLASS_GETTER(m_class_is_nested_classes_inited, gboolean, , MonoClass, nested_classes_inited)
MONO_CLASS_GETTER(m_class_get_class_kind, guint8, , MonoClass, class_kind)
MONO_CLASS_GETTER(m_class_is_interfaces_inited, gboolean, , MonoClass, interfaces_inited)
Expand Down
30 changes: 0 additions & 30 deletions src/mono/mono/metadata/class-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -3188,20 +3188,6 @@ mono_class_init_checked (MonoClass *klass, MonoError *error)
return success;
}

#ifndef DISABLE_COM
/*
* COM initialization is delayed until needed.
* However when a [ComImport] attribute is present on a type it will trigger
* the initialization. This is not a problem unless the BCL being executed
* lacks the types that COM depends on (e.g. Variant on Silverlight).
*/
static void
init_com_from_comimport (MonoClass *klass)
{
/* FIXME : we should add an extra checks to ensure COM can be initialized properly before continuing */
}
#endif /*DISABLE_COM*/

/*
* LOCKING: this assumes the loader lock is held
*/
Expand All @@ -3226,14 +3212,6 @@ mono_class_setup_parent (MonoClass *klass, MonoClass *parent)
}

if (!MONO_CLASS_IS_INTERFACE_INTERNAL (klass)) {
/* Imported COM Objects always derive from __ComObject. */
#ifndef DISABLE_COM
if (MONO_CLASS_IS_IMPORT (klass)) {
init_com_from_comimport (klass);
if (parent == mono_defaults.object_class)
parent = mono_class_get_com_object_class ();
}
#endif
if (!parent) {
/* set the parent to something useful and safe, but mark the type as broken */
parent = mono_defaults.object_class;
Expand All @@ -3254,9 +3232,6 @@ mono_class_setup_parent (MonoClass *klass, MonoClass *parent)

klass->delegate = parent->delegate;

if (MONO_CLASS_IS_IMPORT (klass) || mono_class_is_com_object (parent))
mono_class_set_is_com_object (klass);

if (system_namespace) {
if (klass->name [0] == 'D' && !strcmp (klass->name, "Delegate"))
klass->delegate = 1;
Expand All @@ -3270,11 +3245,6 @@ mono_class_setup_parent (MonoClass *klass, MonoClass *parent)
}
/*klass->enumtype = klass->parent->enumtype; */
} else {
/* initialize com types if COM interfaces are present */
#ifndef DISABLE_COM
if (MONO_CLASS_IS_IMPORT (klass))
init_com_from_comimport (klass);
#endif
klass->parent = NULL;
}

Expand Down
20 changes: 0 additions & 20 deletions src/mono/mono/metadata/class-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,13 +331,6 @@ int mono_class_interface_match (const uint8_t *bitmap, int id);

#define MONO_VTABLE_AVAILABLE_GC_BITS 4

#ifdef DISABLE_COM
#define mono_class_is_com_object(klass) (FALSE)
#else
#define mono_class_is_com_object(klass) (m_class_is_com_object (klass))
#endif


MONO_API int mono_class_interface_offset (MonoClass *klass, MonoClass *itf);
MONO_COMPONENT_API int mono_class_interface_offset_with_variance (MonoClass *klass, MonoClass *itf, gboolean *non_exact_match);

Expand Down Expand Up @@ -979,16 +972,6 @@ mono_class_try_get_##shortname##_class (void) \

GENERATE_TRY_GET_CLASS_WITH_CACHE_DECL (safehandle)

#ifndef DISABLE_COM

GENERATE_GET_CLASS_WITH_CACHE_DECL (interop_proxy)
GENERATE_GET_CLASS_WITH_CACHE_DECL (idispatch)
GENERATE_GET_CLASS_WITH_CACHE_DECL (iunknown)
GENERATE_GET_CLASS_WITH_CACHE_DECL (com_object)
GENERATE_GET_CLASS_WITH_CACHE_DECL (variant)

#endif

MonoClass* mono_class_get_appdomain_class (void);

GENERATE_GET_CLASS_WITH_CACHE_DECL (appdomain_unloaded_exception)
Expand Down Expand Up @@ -1370,9 +1353,6 @@ mono_class_get_declsec_flags (MonoClass *klass);
void
mono_class_set_declsec_flags (MonoClass *klass, guint32 value);

void
mono_class_set_is_com_object (MonoClass *klass);

void
mono_class_set_weak_bitmap (MonoClass *klass, int nbits, gsize *bits);

Expand Down
7 changes: 1 addition & 6 deletions src/mono/mono/metadata/class-private-definition.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,7 @@ struct _MonoClass {
guint has_ref_fields : 1; /* it has byref fields */
guint has_static_refs : 1; /* it has static fields that are GC-tracked */
guint no_special_static_fields : 1; /* has no thread/context static fields */
/* directly or indirectly derives from ComImport attributed class.
* this means we need to create a proxy for instances of this class
* for COM Interop. set this flag on loading so all we need is a quick check
* during object creation rather than having to traverse supertypes
*/
guint is_com_object : 1;

guint nested_classes_inited : 1; /* Whenever nested_class is initialized */

/* next byte*/
Expand Down
Loading

0 comments on commit 7f4702a

Please sign in to comment.