// 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;
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;
}
/**
* @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)
}
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
ares = mono_array_get (msg->args, gpointer, sig->param_count - 1);
g_assert (ares);
+ if (ares->async_delegate != 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);
}
}
- if (mono_class_from_mono_type (t) == mono_defaults.stringbuilder_class)
- return MONO_MARSHAL_COPY;
-
return MONO_MARSHAL_SERIALIZE;
}
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++)
g_assert (method);
- target_klass = method->klass;
-
mono_marshal_lock ();
if (method->string_ctor) {
}
}
- 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);
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);
/* 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;
}
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"));
}
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));
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;
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);
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,
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);
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;
}
mono_struct_delete_old (klass, (char *)src);
}
-
-/* FIXME: on win32 we should probably use GlobalAlloc(). */
void*
ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal (int size)
{
/* This returns a valid pointer for size 0 on MS.NET */
size = 4;
+#ifdef PLATFORM_WIN32
+ res = GlobalAlloc (GMEM_FIXED, (gulong)size);
+#else
res = g_try_malloc ((gulong)size);
+#endif
if (!res)
mono_gc_out_of_memory ((gulong)size);
{
MONO_ARCH_SAVE_REGS;
+#ifdef PLATFORM_WIN32
+ GlobalFree (ptr);
+#else
g_free (ptr);
+#endif
}
void*
#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)
{