X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmarshal.c;h=ae4355b04c513b79a36cd765f4362a27fa1e8894;hb=4a5d0b18890aa9344b129bda425af5798bd4ce3d;hp=d84d93f5d0609ef1dfce9ae4d22cede4bfab670a;hpb=42c5a92ddd2f5b2b1f4a26c81277dad0685d07f0;p=mono.git diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index d84d93f5d06..ae4355b04c5 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -2957,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); @@ -4272,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++) @@ -4479,8 +4485,6 @@ mono_marshal_get_runtime_invoke (MonoMethod *method) g_assert (method); - target_klass = method->klass; - mono_marshal_lock (); if (method->string_ctor) { @@ -4515,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); @@ -4531,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); @@ -4541,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) @@ -6772,17 +6789,28 @@ emit_marshal_variant (EmitMarshalContext *m, int argnum, MonoType *t, 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) @@ -6794,15 +6822,11 @@ emit_marshal_variant (EmitMarshalContext *m, int argnum, MonoType *t, 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); @@ -6824,25 +6848,42 @@ emit_marshal_variant (EmitMarshalContext *m, int argnum, MonoType *t, 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; } @@ -8259,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; } @@ -9996,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) {