X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmarshal.c;h=ae4355b04c513b79a36cd765f4362a27fa1e8894;hb=4a5d0b18890aa9344b129bda425af5798bd4ce3d;hp=910b1d3ae6174fe10f76078a95d4d2dd6969cb1a;hpb=434e59e4bc6cda7d62ad6725a8b5a590ff9c9d1f;p=mono.git diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index 910b1d3ae61..ae4355b04c5 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -539,7 +539,7 @@ mono_delegate_to_ftnptr (MonoDelegate *delegate) // Add the delegate to the delegate hash table delegate_hash_table_add (delegate); - /* when the object is collected, collect the dunamic method, too */ + /* when the object is collected, collect the dynamic method, too */ mono_object_register_finalizer ((MonoObject*)delegate); return delegate->delegate_trampoline; @@ -966,16 +966,15 @@ mono_string_to_byvalstr (gpointer dst, MonoString *src, int size) g_assert (size > 0); memset (dst, 0, size); - if (!src) return; s = mono_string_to_utf8 (src); len = MIN (size, strlen (s)); + if (len >= size) + len--; memcpy (dst, s, len); g_free (s); - - *((char *)dst + size - 1) = 0; } /** @@ -984,8 +983,9 @@ mono_string_to_byvalstr (gpointer dst, MonoString *src, int size) * @src: the MonoString to copy. * @size: the maximum number of bytes to copy. * - * Copies the MonoString pointed to by @src as a utf16 string - * into @dst, it copies at most @size bytes into the destination. + * Copies the MonoString pointed to by @src as a utf16 string into + * @dst, it copies at most @size bytes into the destination (including + * a terminating 16-bit zero terminator). */ void mono_string_to_byvalwstr (gpointer dst, MonoString *src, int size) @@ -1001,9 +1001,10 @@ mono_string_to_byvalwstr (gpointer dst, MonoString *src, int size) } len = MIN (size, (mono_string_length (src))); - memcpy (dst, mono_string_chars (src), len * 2); - - *((gunichar2 *)dst + len - 1) = 0; + memcpy (dst, mono_string_chars (src), size * 2); + if (size <= mono_string_length (src)) + len--; + *((gunichar2 *) dst + len) = 0; } void @@ -2956,6 +2957,12 @@ mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params) ares = mono_array_get (msg->args, gpointer, sig->param_count - 1); g_assert (ares); + if (ares->async_delegate != (MonoObject*)delegate && mono_get_runtime_info ()->framework_version [0] >= '2') { + mono_raise_exception (mono_get_exception_invalid_operation ( + "The IAsyncResult object provided does not match this delegate.")); + return NULL; + } + if (delegate->target && mono_object_class (delegate->target) == mono_defaults.transparent_proxy_class) { MonoTransparentProxy* tp = (MonoTransparentProxy *)delegate->target; msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class); @@ -3465,9 +3472,6 @@ mono_get_xdomain_marshal_type (MonoType *t) } } - if (mono_class_from_mono_type (t) == mono_defaults.stringbuilder_class) - return MONO_MARSHAL_COPY; - return MONO_MARSHAL_SERIALIZE; } @@ -4274,14 +4278,14 @@ mono_marshal_get_remoting_invoke_with_check (MonoMethod *method) if (method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK) return method; - sig = signature_no_pinvoke (method); - /* we cant remote methods without this pointer */ - g_assert (sig->hasthis); + g_assert (mono_method_signature (method)->hasthis); if ((res = mono_marshal_remoting_find_in_cache (method, MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK))) return res; + sig = signature_no_pinvoke (method); + mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK); for (i = 0; i <= sig->param_count; i++) @@ -4481,8 +4485,6 @@ mono_marshal_get_runtime_invoke (MonoMethod *method) g_assert (method); - target_klass = method->klass; - mono_marshal_lock (); if (method->string_ctor) { @@ -4517,7 +4519,22 @@ mono_marshal_get_runtime_invoke (MonoMethod *method) } } - cache = method->klass->image->runtime_invoke_cache; + target_klass = mono_defaults.object_class; + /* + * if types in the signature belong to non-mscorlib, we cache only + * in the method image + */ + if (mono_class_from_mono_type (callsig->ret)->image != mono_defaults.corlib) { + target_klass = method->klass; + } else { + for (i = 0; i < callsig->param_count; i++) { + if (mono_class_from_mono_type (callsig->params [i])->image != mono_defaults.corlib) { + target_klass = method->klass; + break; + } + } + } + cache = target_klass->image->runtime_invoke_cache; /* from mono_marshal_find_in_cache */ res = g_hash_table_lookup (cache, callsig); @@ -4533,8 +4550,6 @@ mono_marshal_get_runtime_invoke (MonoMethod *method) dealy_abort_sig->pinvoke = 0; } - target_klass = mono_defaults.object_class; - /* to make it work with our special string constructors */ if (!string_dummy) { MONO_GC_REGISTER_ROOT (string_dummy); @@ -4543,7 +4558,7 @@ mono_marshal_get_runtime_invoke (MonoMethod *method) sig = mono_method_signature (method); - csig = mono_metadata_signature_alloc (method->klass->image, 4); + csig = mono_metadata_signature_alloc (target_klass->image, 4); csig->ret = &mono_defaults.object_class->byval_arg; if (method->klass->valuetype && mono_method_signature (method)->hasthis) @@ -4630,7 +4645,7 @@ handle_enum: /* fall through */ case MONO_TYPE_VALUETYPE: - if (t->data.klass->enumtype) { + if (type == MONO_TYPE_VALUETYPE && t->data.klass->enumtype) { type = t->data.klass->enum_basetype->type; goto handle_enum; } @@ -6192,11 +6207,7 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, MonoClass *klass = t->data.klass; int pos, pos2, loc; - if (mono_class_from_mono_type (t) == mono_defaults.object_class && - (!spec || (spec && spec->native != MONO_NATIVE_STRUCT)) && - (!spec || (spec && (spec->native != MONO_NATIVE_IUNKNOWN && - spec->native != MONO_NATIVE_IDISPATCH && - spec->native != MONO_NATIVE_INTERFACE)))) { + if (mono_class_from_mono_type (t) == mono_defaults.object_class) { mono_raise_exception (mono_get_exception_not_implemented ("Marshalling of type object is not implemented")); } @@ -6206,98 +6217,8 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, conv_arg = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); m->orig_conv_args [argnum] = 0; - - if (spec && spec->native == MONO_NATIVE_STRUCT) - { - static MonoMethod *get_native_variant_for_object = NULL; - int local_variant; - if (!get_native_variant_for_object) - get_native_variant_for_object = mono_class_get_method_from_name (mono_defaults.marshal_class, "GetNativeVariantForObject", 2); - - *conv_arg_type = &mono_defaults.variant_class->byval_arg; - - local_variant = mono_mb_add_local (mb, &mono_defaults.variant_class->byval_arg); - conv_arg = local_variant; - mono_mb_emit_ldarg (mb, argnum); - if (t->byref) - mono_mb_emit_byte(mb, CEE_LDIND_REF); - mono_mb_emit_ldloc_addr (mb, local_variant); - mono_mb_emit_managed_call (mb, get_native_variant_for_object, NULL); - } - else if (spec && (spec->native == MONO_NATIVE_IUNKNOWN || - spec->native == MONO_NATIVE_IDISPATCH || - spec->native == MONO_NATIVE_INTERFACE)) { - mono_mb_emit_ptr (mb, 0); - mono_mb_emit_stloc (mb, conv_arg); - - if (t->byref) { - /* we dont need any conversions for out parameters */ - if (t->attrs & PARAM_ATTRIBUTE_OUT) - break; - else { - char *msg = g_strdup_printf ("non out object references are no implemented"); - MonoException *exc = mono_get_exception_not_implemented (msg); - g_warning (msg); - g_free (msg); - mono_raise_exception (exc); - - } - } else { - char *msg = NULL; - guint32 pos_failed = 0, pos_rcw = 0; - mono_mb_emit_ldarg (mb, argnum); - // if null just break, conv arg was already inited to 0 - pos_failed = mono_mb_emit_short_branch (mb, CEE_BRFALSE_S); - - mono_mb_emit_ldarg (mb, argnum); - mono_mb_emit_icall (mb, cominterop_object_is_rcw); - pos_rcw = mono_mb_emit_short_branch (mb, CEE_BRFALSE_S); - - mono_mb_emit_ldarg (mb, argnum); - mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoTransparentProxy, rp)); - mono_mb_emit_byte (mb, CEE_LDIND_REF); - - /* load the RCW from the ComInteropProxy*/ - mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoComInteropProxy, com_object)); - mono_mb_emit_byte (mb, CEE_LDIND_REF); - - if (klass && klass != mono_defaults.object_class) { - static MonoMethod* GetInterface = NULL; - - if (!GetInterface) - GetInterface = mono_class_get_method_from_name (mono_defaults.com_object_class, "GetInterface", 1); - mono_mb_emit_ptr (mb, t); - mono_mb_emit_icall (mb, type_from_handle); - mono_mb_emit_managed_call (mb, GetInterface, NULL); - } - else if (spec->native == MONO_NATIVE_IUNKNOWN) { - static MonoProperty* iunknown = NULL; - - if (!iunknown) - iunknown = mono_class_get_property_from_name (mono_defaults.com_object_class, "IUnknown"); - mono_mb_emit_managed_call (mb, iunknown->get, NULL); - } - else if (spec->native == MONO_NATIVE_IDISPATCH) { - static MonoProperty* idispatch = NULL; - - if (!idispatch) - idispatch = mono_class_get_property_from_name (mono_defaults.com_object_class, "IDispatch"); - mono_mb_emit_managed_call (mb, idispatch->get, NULL); - } - else { - } - mono_mb_emit_stloc (mb, conv_arg); - - // if not rcw - mono_mb_patch_short_branch (mb, pos_rcw); - msg = g_strdup ("Marshalling of COM Callable Wrappers is not yet implemented."); - mono_mb_emit_exception_marshal_directive (mb, msg); - - // case if null - mono_mb_patch_short_branch (mb, pos_failed); - } - } - else if (klass->delegate) { + + if (klass->delegate) { g_assert (!t->byref); mono_mb_emit_ldarg (mb, argnum); mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN)); @@ -6386,70 +6307,6 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, break; case MARSHAL_ACTION_CONV_OUT: - if (spec && spec->native == MONO_NATIVE_STRUCT) { - static MonoMethod *variant_clear = NULL; - static MonoMethod *get_object_for_native_variant = NULL; - if (!variant_clear) - variant_clear = mono_class_get_method_from_name (mono_defaults.variant_class, "Clear", 0); - if (!get_object_for_native_variant) - get_object_for_native_variant = mono_class_get_method_from_name (mono_defaults.marshal_class, "GetObjectForNativeVariant", 1); - if (t->byref) { - mono_mb_emit_ldarg (mb, argnum); - mono_mb_emit_ldloc_addr (mb, conv_arg); - mono_mb_emit_managed_call (mb, get_object_for_native_variant, NULL); - mono_mb_emit_byte (mb, CEE_STIND_REF); - } - - mono_mb_emit_ldloc_addr (mb, conv_arg); - mono_mb_emit_managed_call (mb, variant_clear, NULL); - break; - } - - if (spec && (spec->native == MONO_NATIVE_IUNKNOWN || - spec->native == MONO_NATIVE_IDISPATCH || - spec->native == MONO_NATIVE_INTERFACE)) { - if (t->byref && (t->attrs & PARAM_ATTRIBUTE_OUT)) { - static MonoClass* com_interop_proxy_class = NULL; - static MonoMethod* com_interop_proxy_get_proxy = NULL; - static MonoMethod* get_transparent_proxy = NULL; - int real_proxy; - guint32 pos_failed = 0; - - mono_mb_emit_ldarg (mb, argnum); - mono_mb_emit_byte (mb, CEE_LDNULL); - mono_mb_emit_byte (mb, CEE_STIND_REF); - - mono_mb_emit_ldloc (mb, conv_arg); - pos_failed = mono_mb_emit_short_branch (mb, CEE_BRFALSE_S); - - if (!com_interop_proxy_class) - com_interop_proxy_class = mono_class_from_name (mono_defaults.corlib, "Mono.Interop", "ComInteropProxy"); - if (!com_interop_proxy_get_proxy) - com_interop_proxy_get_proxy = mono_class_get_method_from_name_flags (com_interop_proxy_class, "GetProxy", 2, METHOD_ATTRIBUTE_PRIVATE); - if (!get_transparent_proxy) - get_transparent_proxy = mono_class_get_method_from_name (mono_defaults.real_proxy_class, "GetTransparentProxy", 0); - - real_proxy = mono_mb_add_local (mb, &com_interop_proxy_class->byval_arg); - - mono_mb_emit_ldloc (mb, conv_arg); - mono_mb_emit_ptr (mb, &mono_defaults.com_object_class->byval_arg); - mono_mb_emit_icall (mb, type_from_handle); - mono_mb_emit_managed_call (mb, com_interop_proxy_get_proxy, NULL); - mono_mb_emit_stloc (mb, real_proxy); - - - mono_mb_emit_ldarg (mb, argnum); - mono_mb_emit_ldloc (mb, real_proxy); - mono_mb_emit_managed_call (mb, get_transparent_proxy, NULL); - if (klass && klass != mono_defaults.object_class) - mono_mb_emit_op (mb, CEE_CASTCLASS, klass); - mono_mb_emit_byte (mb, CEE_STIND_REF); - - // case if null - mono_mb_patch_short_branch (mb, pos_failed); - } - break; - } if (klass == mono_defaults.stringbuilder_class) { gboolean need_free; MonoMarshalNative encoding; @@ -6555,11 +6412,6 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, mono_mb_emit_ldloc (mb, 0); mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL)); mono_mb_emit_stloc (mb, 3); - } else if (spec && (spec->native == MONO_NATIVE_IUNKNOWN || - spec->native == MONO_NATIVE_IDISPATCH || - spec->native == MONO_NATIVE_INTERFACE)) { - char *msg = g_strdup ("Marshalling of COM Objects is not yet implemented."); - mono_mb_emit_exception_marshal_directive (mb, msg); } else { /* set src */ mono_mb_emit_stloc (mb, 0); @@ -6760,6 +6612,289 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, return conv_arg; } +static int +emit_marshal_com_interface (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, + int conv_arg, MonoType **conv_arg_type, + MarshalAction action) +{ + MonoMethodBuilder *mb = m->mb; + MonoClass *klass = t->data.klass; + + switch (action) { + case MARSHAL_ACTION_CONV_IN: { + *conv_arg_type = &mono_defaults.int_class->byval_arg; + conv_arg = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); + + m->orig_conv_args [argnum] = 0; + + mono_mb_emit_ptr (mb, 0); + mono_mb_emit_stloc (mb, conv_arg); + + if (t->byref) { + /* we dont need any conversions for out parameters */ + if (t->attrs & PARAM_ATTRIBUTE_OUT) + break; + else { + char *msg = g_strdup_printf ("non out object references are no implemented"); + MonoException *exc = mono_get_exception_not_implemented (msg); + g_warning (msg); + g_free (msg); + mono_raise_exception (exc); + + } + } else { + char *msg = NULL; + guint32 pos_failed = 0, pos_rcw = 0; + mono_mb_emit_ldarg (mb, argnum); + // if null just break, conv arg was already inited to 0 + pos_failed = mono_mb_emit_short_branch (mb, CEE_BRFALSE_S); + + mono_mb_emit_ldarg (mb, argnum); + mono_mb_emit_icall (mb, cominterop_object_is_rcw); + pos_rcw = mono_mb_emit_short_branch (mb, CEE_BRFALSE_S); + + mono_mb_emit_ldarg (mb, argnum); + mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoTransparentProxy, rp)); + mono_mb_emit_byte (mb, CEE_LDIND_REF); + + /* load the RCW from the ComInteropProxy*/ + mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoComInteropProxy, com_object)); + mono_mb_emit_byte (mb, CEE_LDIND_REF); + + if (klass && klass != mono_defaults.object_class) { + static MonoMethod* GetInterface = NULL; + + if (!GetInterface) + GetInterface = mono_class_get_method_from_name (mono_defaults.com_object_class, "GetInterface", 1); + mono_mb_emit_ptr (mb, t); + mono_mb_emit_icall (mb, type_from_handle); + mono_mb_emit_managed_call (mb, GetInterface, NULL); + } + else if (spec->native == MONO_NATIVE_IUNKNOWN) { + static MonoProperty* iunknown = NULL; + + if (!iunknown) + iunknown = mono_class_get_property_from_name (mono_defaults.com_object_class, "IUnknown"); + mono_mb_emit_managed_call (mb, iunknown->get, NULL); + } + else if (spec->native == MONO_NATIVE_IDISPATCH) { + static MonoProperty* idispatch = NULL; + + if (!idispatch) + idispatch = mono_class_get_property_from_name (mono_defaults.com_object_class, "IDispatch"); + mono_mb_emit_managed_call (mb, idispatch->get, NULL); + } + else { + } + mono_mb_emit_stloc (mb, conv_arg); + + // if not rcw + mono_mb_patch_short_branch (mb, pos_rcw); + msg = g_strdup ("Marshalling of COM Callable Wrappers is not yet implemented."); + mono_mb_emit_exception_marshal_directive (mb, msg); + + // case if null + mono_mb_patch_short_branch (mb, pos_failed); + } + break; + } + + case MARSHAL_ACTION_CONV_OUT: { + if (t->byref && (t->attrs & PARAM_ATTRIBUTE_OUT)) { + static MonoClass* com_interop_proxy_class = NULL; + static MonoMethod* com_interop_proxy_get_proxy = NULL; + static MonoMethod* get_transparent_proxy = NULL; + int real_proxy; + guint32 pos_failed = 0; + + mono_mb_emit_ldarg (mb, argnum); + mono_mb_emit_byte (mb, CEE_LDNULL); + mono_mb_emit_byte (mb, CEE_STIND_REF); + + mono_mb_emit_ldloc (mb, conv_arg); + pos_failed = mono_mb_emit_short_branch (mb, CEE_BRFALSE_S); + + if (!com_interop_proxy_class) + com_interop_proxy_class = mono_class_from_name (mono_defaults.corlib, "Mono.Interop", "ComInteropProxy"); + if (!com_interop_proxy_get_proxy) + com_interop_proxy_get_proxy = mono_class_get_method_from_name_flags (com_interop_proxy_class, "GetProxy", 2, METHOD_ATTRIBUTE_PRIVATE); + if (!get_transparent_proxy) + get_transparent_proxy = mono_class_get_method_from_name (mono_defaults.real_proxy_class, "GetTransparentProxy", 0); + + real_proxy = mono_mb_add_local (mb, &com_interop_proxy_class->byval_arg); + + mono_mb_emit_ldloc (mb, conv_arg); + mono_mb_emit_ptr (mb, &mono_defaults.com_object_class->byval_arg); + mono_mb_emit_icall (mb, type_from_handle); + mono_mb_emit_managed_call (mb, com_interop_proxy_get_proxy, NULL); + mono_mb_emit_stloc (mb, real_proxy); + + + mono_mb_emit_ldarg (mb, argnum); + mono_mb_emit_ldloc (mb, real_proxy); + mono_mb_emit_managed_call (mb, get_transparent_proxy, NULL); + if (klass && klass != mono_defaults.object_class) + mono_mb_emit_op (mb, CEE_CASTCLASS, klass); + mono_mb_emit_byte (mb, CEE_STIND_REF); + + // case if null + mono_mb_patch_short_branch (mb, pos_failed); + } + break; + } + + case MARSHAL_ACTION_PUSH: + if (t->byref) + mono_mb_emit_ldloc_addr (mb, conv_arg); + else + mono_mb_emit_ldloc (mb, conv_arg); + break; + + case MARSHAL_ACTION_CONV_RESULT: { + char *msg = g_strdup ("Marshalling of COM Objects is not yet implemented."); + mono_mb_emit_exception_marshal_directive (mb, msg); + break; + } + + case MARSHAL_ACTION_MANAGED_CONV_IN: { + char *msg = g_strdup ("Marshalling of COM Objects is not yet implemented."); + mono_mb_emit_exception_marshal_directive (mb, msg); + break; + } + + case MARSHAL_ACTION_MANAGED_CONV_OUT: { + char *msg = g_strdup ("Marshalling of COM Objects is not yet implemented."); + mono_mb_emit_exception_marshal_directive (mb, msg); + break; + } + + case MARSHAL_ACTION_MANAGED_CONV_RESULT: { + char *msg = g_strdup ("Marshalling of COM Objects is not yet implemented."); + mono_mb_emit_exception_marshal_directive (mb, msg); + break; + } + + default: + g_assert_not_reached (); + } + + return conv_arg; +} + +static int +emit_marshal_variant (EmitMarshalContext *m, int argnum, MonoType *t, + MonoMarshalSpec *spec, + int conv_arg, MonoType **conv_arg_type, + MarshalAction action) +{ + MonoMethodBuilder *mb = m->mb; + static MonoMethod *get_object_for_native_variant = NULL; + static MonoMethod *get_native_variant_for_object = NULL; + + if (!get_object_for_native_variant) + get_object_for_native_variant = mono_class_get_method_from_name (mono_defaults.marshal_class, "GetObjectForNativeVariant", 1); + g_assert (get_object_for_native_variant); + + if (!get_native_variant_for_object) + get_native_variant_for_object = mono_class_get_method_from_name (mono_defaults.marshal_class, "GetNativeVariantForObject", 2); + g_assert (get_native_variant_for_object); + + switch (action) { + case MARSHAL_ACTION_CONV_IN: { + conv_arg = mono_mb_add_local (mb, &mono_defaults.variant_class->byval_arg); + + if (t->byref) + *conv_arg_type = &mono_defaults.variant_class->this_arg; + else + *conv_arg_type = &mono_defaults.variant_class->byval_arg; + + if (t->byref && t->attrs & PARAM_ATTRIBUTE_OUT) + break; + + mono_mb_emit_ldarg (mb, argnum); + if (t->byref) + mono_mb_emit_byte(mb, CEE_LDIND_REF); + mono_mb_emit_ldloc_addr (mb, conv_arg); + mono_mb_emit_managed_call (mb, get_native_variant_for_object, NULL); + break; + } + + case MARSHAL_ACTION_CONV_OUT: { + static MonoMethod *variant_clear = NULL; + + if (!variant_clear) + variant_clear = mono_class_get_method_from_name (mono_defaults.variant_class, "Clear", 0); + g_assert (variant_clear); + + + if (t->byref) { + mono_mb_emit_ldarg (mb, argnum); + mono_mb_emit_ldloc_addr (mb, conv_arg); + mono_mb_emit_managed_call (mb, get_object_for_native_variant, NULL); + mono_mb_emit_byte (mb, CEE_STIND_REF); + } + + mono_mb_emit_ldloc_addr (mb, conv_arg); + mono_mb_emit_managed_call (mb, variant_clear, NULL); + break; + } + + case MARSHAL_ACTION_PUSH: + if (t->byref) + mono_mb_emit_ldloc_addr (mb, conv_arg); + else + mono_mb_emit_ldloc (mb, conv_arg); + break; + + case MARSHAL_ACTION_CONV_RESULT: { + char *msg = g_strdup ("Marshalling of VARIANT not supported as a return type."); + mono_mb_emit_exception_marshal_directive (mb, msg); + break; + } + + case MARSHAL_ACTION_MANAGED_CONV_IN: { + conv_arg = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg); + + if (t->byref) + *conv_arg_type = &mono_defaults.variant_class->this_arg; + else + *conv_arg_type = &mono_defaults.variant_class->byval_arg; + + if (t->byref && t->attrs & PARAM_ATTRIBUTE_OUT) + break; + + if (t->byref) + mono_mb_emit_ldarg (mb, argnum); + else + mono_mb_emit_ldarg_addr (mb, argnum); + mono_mb_emit_managed_call (mb, get_object_for_native_variant, NULL); + mono_mb_emit_stloc (mb, conv_arg); + break; + } + + case MARSHAL_ACTION_MANAGED_CONV_OUT: { + if (t->byref) { + mono_mb_emit_ldloc (mb, conv_arg); + mono_mb_emit_ldarg (mb, argnum); + mono_mb_emit_managed_call (mb, get_native_variant_for_object, NULL); + } + break; + } + + case MARSHAL_ACTION_MANAGED_CONV_RESULT: { + char *msg = g_strdup ("Marshalling of VARIANT not supported as a return type."); + mono_mb_emit_exception_marshal_directive (mb, msg); + break; + } + + default: + g_assert_not_reached (); + } + + return conv_arg; +} + static int emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, @@ -7609,6 +7744,14 @@ emit_marshal (EmitMarshalContext *m, int argnum, MonoType *t, return emit_marshal_string (m, argnum, t, spec, conv_arg, conv_arg_type, action); case MONO_TYPE_CLASS: case MONO_TYPE_OBJECT: + if (spec && spec->native == MONO_NATIVE_STRUCT) + return emit_marshal_variant (m, argnum, t, spec, conv_arg, conv_arg_type, action); + + if (spec && (spec->native == MONO_NATIVE_IUNKNOWN || + spec->native == MONO_NATIVE_IDISPATCH || + spec->native == MONO_NATIVE_INTERFACE)) + return emit_marshal_com_interface (m, argnum, t, spec, conv_arg, conv_arg_type, action); + if (mono_defaults.safehandle_class != NULL && mono_class_is_subclass_of (t->data.klass, mono_defaults.safehandle_class, FALSE)) return emit_marshal_safehandle (m, argnum, t, spec, conv_arg, conv_arg_type, action); @@ -8157,6 +8300,7 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i switch (t->type) { case MONO_TYPE_CLASS: case MONO_TYPE_VALUETYPE: + case MONO_TYPE_OBJECT: emit_marshal (m, i, t, mspecs [i + 1], tmp_locals [i], NULL, MARSHAL_ACTION_MANAGED_CONV_OUT); break; } @@ -9894,6 +10038,18 @@ ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem (void *ptr) #endif } +gpointer +ves_icall_System_Runtime_InteropServices_Marshal_ReAllocCoTaskMem (gpointer ptr, int size) +{ + MONO_ARCH_SAVE_REGS; + +#ifdef PLATFORM_WIN32 + return CoTaskMemRealloc (ptr, size); +#else + return g_try_realloc (ptr, (gulong)size); +#endif +} + void* ves_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement (MonoArray *arrayobj, int index) {