Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove built-in COM interop support from Mono runtime #97789

Merged
merged 13 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
2 changes: 0 additions & 2 deletions src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c
Original file line number Diff line number Diff line change
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
35 changes: 5 additions & 30 deletions src/mono/mono/metadata/class-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,11 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
}
}

if (MONO_CLASS_IS_IMPORT (klass)) {
mono_class_set_failure_and_error (klass, error, "Built-in COM interop is not supported on the Mono runtime.");
goto parent_failure;
}
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved

mono_class_setup_parent (klass, parent);

/* uses ->valuetype, which is initialized by mono_class_setup_parent above */
Expand Down Expand Up @@ -3196,20 +3201,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 @@ -3234,14 +3225,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 @@ -3262,9 +3245,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 @@ -3278,11 +3258,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 @@ -332,13 +332,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 @@ -980,16 +973,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 @@ -1371,9 +1354,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
Loading