diff --git a/src/mono/cmake/config.h.in b/src/mono/cmake/config.h.in index 3e42b7617cda8..bfbf8ddda4dd2 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -441,6 +441,9 @@ /* Some VES is available at runtime */ #cmakedefine ENABLE_ILGEN 1 +/* Disable non-blittable marshalling */ +#cmakedefine DISABLE_NONBLITTABLE + /* Disable SIMD intrinsics related optimizations. */ #cmakedefine DISABLE_SIMD 1 diff --git a/src/mono/mono/metadata/marshal-ilgen.c b/src/mono/mono/metadata/marshal-ilgen.c index 8146753741a70..b72a45c007cd4 100644 --- a/src/mono/mono/metadata/marshal-ilgen.c +++ b/src/mono/mono/metadata/marshal-ilgen.c @@ -2450,7 +2450,6 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, { MonoMethodBuilder *mb = m->mb; MonoClass *klass = mono_class_from_mono_type_internal (t); - gboolean need_convert, need_free; MonoMarshalNative encoding; encoding = mono_marshal_get_string_encoding (m->piinfo, spec); @@ -2471,6 +2470,10 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, mono_mb_emit_icall_id (mb, conv_to_icall (MONO_MARSHAL_CONV_ARRAY_LPARRAY, NULL)); mono_mb_emit_stloc (mb, conv_arg); } else { +#ifdef DISABLE_NONBLITTABLE + char *msg = g_strdup ("Non-blittable marshalling conversion is disabled"); + mono_mb_emit_exception_marshal_directive (mb, msg); +#else guint32 label1, label2, label3; int index_var, src_var, dest_ptr, esize; MonoMarshalConv conv; @@ -2582,11 +2585,14 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, } mono_mb_patch_branch (mb, label1); +#endif } break; - case MARSHAL_ACTION_CONV_OUT: + case MARSHAL_ACTION_CONV_OUT: { +#ifndef DISABLE_NONBLITTABLE + gboolean need_convert, need_free; /* Unicode character arrays are implicitly marshalled as [Out] under MS.NET */ need_convert = ((eklass == mono_defaults.char_class) && (encoding == MONO_NATIVE_LPWSTR)) || (eklass == mono_class_try_get_stringbuilder_class ()) || (t->attrs & PARAM_ATTRIBUTE_OUT); need_free = mono_marshal_need_free (m_class_get_byval_arg (eklass), m->piinfo, spec); @@ -2725,6 +2731,7 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, mono_mb_patch_branch (mb, label1); mono_mb_patch_branch (mb, label3); } +#endif if (m_class_is_blittable (eklass)) { /* free memory allocated (if any) by MONO_MARSHAL_CONV_ARRAY_LPARRAY */ @@ -2737,6 +2744,7 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, } break; + } case MARSHAL_ACTION_PUSH: if (t->byref) @@ -2810,16 +2818,20 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, /* FIXME: Optimize blittable case */ +#ifndef DISABLE_NONBLITTABLE if (eklass == mono_defaults.string_class) { is_string = TRUE; + gboolean need_free; conv = mono_marshal_get_ptr_to_string_conv (m->piinfo, spec, &need_free); } else if (eklass == mono_class_try_get_stringbuilder_class ()) { is_string = TRUE; + gboolean need_free; conv = mono_marshal_get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free); } else conv = MONO_MARSHAL_CONV_INVALID; +#endif mono_marshal_load_type_info (eklass); @@ -2902,7 +2914,12 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, mono_mb_patch_branch (mb, label1); break; } - +#ifdef DISABLE_NONBLITTABLE + else { + char *msg = g_strdup ("Non-blittable marshalling conversion is disabled"); + mono_mb_emit_exception_marshal_directive (mb, msg); + } +#else /* Emit marshalling loop */ index_var = mono_mb_add_local (mb, int_type); mono_mb_emit_byte (mb, CEE_LDC_I4_0); @@ -2939,6 +2956,7 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, mono_mb_patch_branch (mb, label1); mono_mb_patch_branch (mb, label3); +#endif break; } @@ -2972,6 +2990,7 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, /* FIXME: Optimize blittable case */ +#ifndef DISABLE_NONBLITTABLE if (eklass == mono_defaults.string_class) { is_string = TRUE; conv = mono_marshal_get_string_to_ptr_conv (m->piinfo, spec); @@ -2982,6 +3001,7 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, } else conv = MONO_MARSHAL_CONV_INVALID; +#endif mono_marshal_load_type_info (eklass); @@ -3018,6 +3038,7 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, break; } +#ifndef DISABLE_NONBLITTABLE /* Emit marshalling loop */ index_var = mono_mb_add_local (mb, int_type); mono_mb_emit_byte (mb, CEE_LDC_I4_0); @@ -3058,10 +3079,12 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, mono_mb_patch_branch (mb, label1); mono_mb_patch_branch (mb, label3); +#endif break; } case MARSHAL_ACTION_MANAGED_CONV_RESULT: { +#ifndef DISABLE_NONBLITTABLE guint32 label1, label2, label3; int index_var, src, dest, esize; MonoMarshalConv conv = MONO_MARSHAL_CONV_INVALID; @@ -3153,6 +3176,7 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, mono_mb_patch_branch (mb, label3); mono_mb_patch_branch (mb, label1); +#endif break; } default: @@ -3161,6 +3185,62 @@ emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, return conv_arg; } +static int +emit_marshal_ptr_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, int conv_arg, + MonoType **conv_arg_type, MarshalAction action) +{ + MonoMethodBuilder *mb = m->mb; + + switch (action) { + case MARSHAL_ACTION_CONV_IN: + /* MS seems to allow this in some cases, ie. bxc #158 */ + /* + if (MONO_TYPE_ISSTRUCT (t->data.type) && !mono_class_from_mono_type_internal (t->data.type)->blittable) { + char *msg = g_strdup_printf ("Can not marshal 'parameter #%d': Pointers can not reference marshaled structures. Use byref instead.", argnum + 1); + mono_mb_emit_exception_marshal_directive (m->mb, msg); + } + */ + break; + + case MARSHAL_ACTION_PUSH: + mono_mb_emit_ldarg (mb, argnum); + break; + + case MARSHAL_ACTION_CONV_RESULT: + /* no conversions necessary */ + mono_mb_emit_stloc (mb, 3); + break; + + default: + break; + } + return conv_arg; +} + +static int +emit_marshal_scalar_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, int conv_arg, + MonoType **conv_arg_type, MarshalAction action) +{ + MonoMethodBuilder *mb = m->mb; + + switch (action) { + case MARSHAL_ACTION_PUSH: + mono_mb_emit_ldarg (mb, argnum); + break; + + case MARSHAL_ACTION_CONV_RESULT: + /* no conversions necessary */ + mono_mb_emit_stloc (mb, 3); + break; + + default: + break; + } + return conv_arg; +} + static int emit_marshal_boolean_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, @@ -3312,39 +3392,6 @@ emit_marshal_boolean_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, return conv_arg; } -static int -emit_marshal_ptr_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, - MonoMarshalSpec *spec, int conv_arg, - MonoType **conv_arg_type, MarshalAction action) -{ - MonoMethodBuilder *mb = m->mb; - - switch (action) { - case MARSHAL_ACTION_CONV_IN: - /* MS seems to allow this in some cases, ie. bxc #158 */ - /* - if (MONO_TYPE_ISSTRUCT (t->data.type) && !mono_class_from_mono_type_internal (t->data.type)->blittable) { - char *msg = g_strdup_printf ("Can not marshal 'parameter #%d': Pointers can not reference marshaled structures. Use byref instead.", argnum + 1); - mono_mb_emit_exception_marshal_directive (m->mb, msg); - } - */ - break; - - case MARSHAL_ACTION_PUSH: - mono_mb_emit_ldarg (mb, argnum); - break; - - case MARSHAL_ACTION_CONV_RESULT: - /* no conversions necessary */ - mono_mb_emit_stloc (mb, 3); - break; - - default: - break; - } - return conv_arg; -} - static int emit_marshal_char_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, @@ -3371,29 +3418,6 @@ emit_marshal_char_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, return conv_arg; } -static int -emit_marshal_scalar_ilgen (EmitMarshalContext *m, int argnum, MonoType *t, - MonoMarshalSpec *spec, int conv_arg, - MonoType **conv_arg_type, MarshalAction action) -{ - MonoMethodBuilder *mb = m->mb; - - switch (action) { - case MARSHAL_ACTION_PUSH: - mono_mb_emit_ldarg (mb, argnum); - break; - - case MARSHAL_ACTION_CONV_RESULT: - /* no conversions necessary */ - mono_mb_emit_stloc (mb, 3); - break; - - default: - break; - } - return conv_arg; -} - static void emit_virtual_stelemref_ilgen (MonoMethodBuilder *mb, const char **param_names, MonoStelemrefKind kind) { @@ -6806,10 +6830,11 @@ mono_marshal_ilgen_init (void) MonoMarshalCallbacks cb; cb.version = MONO_MARSHAL_CALLBACKS_VERSION; cb.emit_marshal_array = emit_marshal_array_ilgen; - cb.emit_marshal_boolean = emit_marshal_boolean_ilgen; cb.emit_marshal_ptr = emit_marshal_ptr_ilgen; - cb.emit_marshal_char = emit_marshal_char_ilgen; cb.emit_marshal_scalar = emit_marshal_scalar_ilgen; +#ifndef DISABLE_NONBLITTABLE + cb.emit_marshal_boolean = emit_marshal_boolean_ilgen; + cb.emit_marshal_char = emit_marshal_char_ilgen; cb.emit_marshal_custom = emit_marshal_custom_ilgen; cb.emit_marshal_asany = emit_marshal_asany_ilgen; cb.emit_marshal_vtype = emit_marshal_vtype_ilgen; @@ -6818,6 +6843,7 @@ mono_marshal_ilgen_init (void) cb.emit_marshal_handleref = emit_marshal_handleref_ilgen; cb.emit_marshal_object = emit_marshal_object_ilgen; cb.emit_marshal_variant = emit_marshal_variant_ilgen; +#endif cb.emit_castclass = emit_castclass_ilgen; cb.emit_struct_to_ptr = emit_struct_to_ptr_ilgen; cb.emit_ptr_to_struct = emit_ptr_to_struct_ilgen; @@ -6847,5 +6873,8 @@ mono_marshal_ilgen_init (void) cb.mb_emit_exception = mb_emit_exception_ilgen; cb.mb_emit_exception_for_error = mb_emit_exception_for_error_ilgen; cb.mb_emit_byte = mb_emit_byte_ilgen; +#ifdef DISABLE_NONBLITTABLE + mono_marshal_noilgen_init_blittable (&cb); +#endif mono_install_marshal_callbacks (&cb); } diff --git a/src/mono/mono/metadata/marshal-internals.h b/src/mono/mono/metadata/marshal-internals.h index 17aced9723b0e..785f568edb703 100644 --- a/src/mono/mono/metadata/marshal-internals.h +++ b/src/mono/mono/metadata/marshal-internals.h @@ -9,6 +9,7 @@ #include #include #include +#include MonoObjectHandle mono_marshal_xdomain_copy_value_handle (MonoObjectHandle val, MonoError *error); @@ -43,4 +44,7 @@ typedef enum { void mono_marshal_noilgen_init (void); +void +mono_marshal_noilgen_init_blittable (MonoMarshalCallbacks *cb); + #endif /* __MONO_METADATA_MARSHAL_INTERNALS_H__ */ diff --git a/src/mono/mono/metadata/marshal-noilgen.c b/src/mono/mono/metadata/marshal-noilgen.c index cb79e2f504a73..ea0aa2c7e02f4 100644 --- a/src/mono/mono/metadata/marshal-noilgen.c +++ b/src/mono/mono/metadata/marshal-noilgen.c @@ -6,6 +6,79 @@ #include "utils/mono-compiler.h" #ifndef ENABLE_ILGEN +static int +emit_marshal_array_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, + int conv_arg, MonoType **conv_arg_type, + MarshalAction action) +{ + MonoType *int_type = mono_get_int_type (); + MonoType *object_type = mono_get_object_type (); + switch (action) { + case MARSHAL_ACTION_CONV_IN: + *conv_arg_type = object_type; + break; + case MARSHAL_ACTION_MANAGED_CONV_IN: + *conv_arg_type = int_type; + break; + } + return conv_arg; +} + +static int +emit_marshal_ptr_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, int conv_arg, + MonoType **conv_arg_type, MarshalAction action) +{ + return conv_arg; +} + +static int +emit_marshal_scalar_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, int conv_arg, + MonoType **conv_arg_type, MarshalAction action) +{ + return conv_arg; +} +#endif + +#if !defined(ENABLE_ILGEN) || defined(DISABLE_NONBLITTABLE) +static int +emit_marshal_boolean_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, + int conv_arg, MonoType **conv_arg_type, + MarshalAction action) +{ + MonoType *int_type = mono_get_int_type (); + switch (action) { + case MARSHAL_ACTION_CONV_IN: + if (t->byref) + *conv_arg_type = int_type; + else + *conv_arg_type = mono_marshal_boolean_conv_in_get_local_type (spec, NULL); + break; + + case MARSHAL_ACTION_MANAGED_CONV_IN: { + MonoClass* conv_arg_class = mono_marshal_boolean_managed_conv_in_get_conv_arg_class (spec, NULL); + if (t->byref) + *conv_arg_type = m_class_get_this_arg (conv_arg_class); + else + *conv_arg_type = m_class_get_byval_arg (conv_arg_class); + break; + } + + } + return conv_arg; +} + +static int +emit_marshal_char_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, int conv_arg, + MonoType **conv_arg_type, MarshalAction action) +{ + return conv_arg; +} + static int emit_marshal_custom_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, @@ -90,76 +163,16 @@ emit_marshal_object_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, } static int -emit_marshal_array_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, - MonoMarshalSpec *spec, - int conv_arg, MonoType **conv_arg_type, - MarshalAction action) -{ - MonoType *int_type = mono_get_int_type (); - MonoType *object_type = mono_get_object_type (); - switch (action) { - case MARSHAL_ACTION_CONV_IN: - *conv_arg_type = object_type; - break; - case MARSHAL_ACTION_MANAGED_CONV_IN: - *conv_arg_type = int_type; - break; - } - return conv_arg; -} - -static int -emit_marshal_boolean_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, - MonoMarshalSpec *spec, - int conv_arg, MonoType **conv_arg_type, - MarshalAction action) -{ - MonoType *int_type = mono_get_int_type (); - switch (action) { - case MARSHAL_ACTION_CONV_IN: - if (t->byref) - *conv_arg_type = int_type; - else - *conv_arg_type = mono_marshal_boolean_conv_in_get_local_type (spec, NULL); - break; - - case MARSHAL_ACTION_MANAGED_CONV_IN: { - MonoClass* conv_arg_class = mono_marshal_boolean_managed_conv_in_get_conv_arg_class (spec, NULL); - if (t->byref) - *conv_arg_type = m_class_get_this_arg (conv_arg_class); - else - *conv_arg_type = m_class_get_byval_arg (conv_arg_class); - break; - } - - } - return conv_arg; -} - -static int -emit_marshal_ptr_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, - MonoMarshalSpec *spec, int conv_arg, - MonoType **conv_arg_type, MarshalAction action) -{ - return conv_arg; -} - -static int -emit_marshal_char_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, - MonoMarshalSpec *spec, int conv_arg, - MonoType **conv_arg_type, MarshalAction action) -{ - return conv_arg; -} - -static int -emit_marshal_scalar_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, - MonoMarshalSpec *spec, int conv_arg, - MonoType **conv_arg_type, MarshalAction action) +emit_marshal_variant_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, + int conv_arg, MonoType **conv_arg_type, + MarshalAction action) { - return conv_arg; + g_assert_not_reached (); } +#endif +#ifndef ENABLE_ILGEN static void emit_managed_wrapper_noilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle) { @@ -208,15 +221,6 @@ emit_synchronized_wrapper_noilgen (MonoMethodBuilder *mb, MonoMethod *method, Mo } -static int -emit_marshal_variant_noilgen (EmitMarshalContext *m, int argnum, MonoType *t, - MonoMarshalSpec *spec, - int conv_arg, MonoType **conv_arg_type, - MarshalAction action) -{ - g_assert_not_reached (); -} - static void emit_delegate_begin_invoke_noilgen (MonoMethodBuilder *mb, MonoMethodSignature *sig) { @@ -360,10 +364,10 @@ mono_marshal_noilgen_init (void) MonoMarshalCallbacks cb; cb.version = MONO_MARSHAL_CALLBACKS_VERSION; cb.emit_marshal_array = emit_marshal_array_noilgen; - cb.emit_marshal_boolean = emit_marshal_boolean_noilgen; cb.emit_marshal_ptr = emit_marshal_ptr_noilgen; - cb.emit_marshal_char = emit_marshal_char_noilgen; cb.emit_marshal_scalar = emit_marshal_scalar_noilgen; + cb.emit_marshal_boolean = emit_marshal_boolean_noilgen; + cb.emit_marshal_char = emit_marshal_char_noilgen; cb.emit_marshal_custom = emit_marshal_custom_noilgen; cb.emit_marshal_asany = emit_marshal_asany_noilgen; cb.emit_marshal_vtype = emit_marshal_vtype_noilgen; @@ -409,3 +413,25 @@ mono_marshal_noilgen_init (void) { } #endif + +#ifdef DISABLE_NONBLITTABLE +void +mono_marshal_noilgen_init_blittable (MonoMarshalCallbacks *cb) +{ + cb->emit_marshal_boolean = emit_marshal_boolean_noilgen; + cb->emit_marshal_char = emit_marshal_char_noilgen; + cb->emit_marshal_custom = emit_marshal_custom_noilgen; + cb->emit_marshal_asany = emit_marshal_asany_noilgen; + cb->emit_marshal_vtype = emit_marshal_vtype_noilgen; + cb->emit_marshal_string = emit_marshal_string_noilgen; + cb->emit_marshal_safehandle = emit_marshal_safehandle_noilgen; + cb->emit_marshal_handleref = emit_marshal_handleref_noilgen; + cb->emit_marshal_object = emit_marshal_object_noilgen; + cb->emit_marshal_variant = emit_marshal_variant_noilgen; +} +#else +void +mono_marshal_noilgen_init_blittable (MonoMarshalCallbacks *cb) +{ +} +#endif