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 (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);
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: {
- static MonoMethod *get_native_variant_for_object = NULL;
-
- 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);
-
- *conv_arg_type = &mono_defaults.variant_class->byval_arg;
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)
case MARSHAL_ACTION_CONV_OUT: {
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);
g_assert (variant_clear);
- 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 (t->byref) {
mono_mb_emit_ldarg (mb, argnum);
break;
case MARSHAL_ACTION_CONV_RESULT: {
- char *msg = g_strdup ("Marshalling of VARIANT not supported.");
+ 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: {
- char *msg = g_strdup ("Marshalling of VARIANT not supported.");
- mono_mb_emit_exception_marshal_directive (mb, msg);
+ 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: {
- char *msg = g_strdup ("Marshalling of VARIANT not supported.");
- mono_mb_emit_exception_marshal_directive (mb, msg);
+ 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.");
+ char *msg = g_strdup ("Marshalling of VARIANT not supported as a return type.");
mono_mb_emit_exception_marshal_directive (mb, msg);
break;
}
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;
}
#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)
{