2009-07-11 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sat, 11 Jul 2009 18:00:04 +0000 (18:00 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sat, 11 Jul 2009 18:00:04 +0000 (18:00 -0000)
* object-internals.h (MonoIntPtr): New structure describing a boxed
IntPtr.

* object.c (mono_runtime_invoke_array): Handle ptr arguments and
returns. Fixes #519953.

* marshal.c (mono_marshal_get_runtime_invoke): Handle pointer returns.

svn path=/trunk/mono/; revision=137747

mono/metadata/ChangeLog
mono/metadata/marshal.c
mono/metadata/object-internals.h
mono/metadata/object.c

index dd45e1c0c0d8b6e172d78643515a45dbdaf81c30..1d9e1548437c7a6e1e504c2f8cbc0401c4309bec 100644 (file)
@@ -1,3 +1,13 @@
+2009-07-11  Zoltan Varga  <vargaz@gmail.com>
+
+       * object-internals.h (MonoIntPtr): New structure describing a boxed
+       IntPtr.
+
+       * object.c (mono_runtime_invoke_array): Handle ptr arguments and
+       returns. Fixes #519953.
+
+       * marshal.c (mono_marshal_get_runtime_invoke): Handle pointer returns.
+
 2009-07-09  Mark Probst  <mark.probst@gmail.com>
 
        * class-internals.h, generic-sharing.c: New RGCTX info type for
index 3b5c54f92af8abb1cb2a47733c660d5c000d5916..ea28a3325553acc515b0f0b2a0a0e26a3f95b00f 100644 (file)
@@ -4242,6 +4242,9 @@ handle_enum:
                /* nothing to do */
                break;
        case MONO_TYPE_PTR:
+               /* The result is an IntPtr */
+               mono_mb_emit_op (mb, CEE_BOX, mono_defaults.int_class);
+               break;
        default:
                g_assert_not_reached ();
        }
index fef0e5320352bdc37c02fd1252956d4d2894e8cb..4d3c495c79591de1e74f914dbdd118c5e1332ce8 100644 (file)
@@ -1224,6 +1224,12 @@ typedef struct {
        guint32 location;
 } MonoManifestResourceInfo;
 
+/* A boxed IntPtr */
+typedef struct {
+       MonoObject object;
+       gpointer m_value;
+} MonoIntPtr;
+
 /* Keep in sync with System.GenericParameterAttributes */
 typedef enum {
        GENERIC_PARAMETER_ATTRIBUTE_NON_VARIANT         = 0,
index 1e257dc3e3e60232947e7a2271c6d8b4a918f0df..18c31b20e022e176d04dc59cedcd0b5385c7ec97 100644 (file)
@@ -3594,8 +3594,21 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
                                else
                                        t = &t->data.generic_class->container_class->byval_arg;
                                goto again;
+                       case MONO_TYPE_PTR: {
+                               MonoObject *arg;
+
+                               /* The argument should be an IntPtr */
+                               arg = mono_array_get (params, MonoObject*, i);
+                               if (arg == NULL) {
+                                       pa [i] = NULL;
+                               } else {
+                                       g_assert (arg->vtable->klass == mono_defaults.int_class);
+                                       pa [i] = ((MonoIntPtr*)arg)->m_value;
+                               }
+                               break;
+                       }
                        default:
-                               g_error ("type 0x%x not handled in ves_icall_InternalInvoke", sig->params [i]->type);
+                               g_error ("type 0x%x not handled in mono_runtime_invoke_array", sig->params [i]->type);
                        }
                }
        }
@@ -3642,6 +3655,27 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
                /* obj must be already unboxed if needed */
                res = mono_runtime_invoke (method, obj, pa, exc);
 
+               if (sig->ret->type == MONO_TYPE_PTR) {
+                       MonoClass *pointer_class;
+                       static MonoMethod *box_method;
+                       void *box_args [2];
+                       MonoObject *box_exc;
+
+                       /* 
+                        * The runtime-invoke wrapper returns a boxed IntPtr, need to 
+                        * convert it to a Pointer object.
+                        */
+                       pointer_class = mono_class_from_name_cached (mono_defaults.corlib, "System.Reflection", "Pointer");
+                       if (!box_method)
+                               box_method = mono_class_get_method_from_name (pointer_class, "Box", -1);
+
+                       g_assert (res->vtable->klass == mono_defaults.int_class);
+                       box_args [0] = ((MonoIntPtr*)res)->m_value;
+                       box_args [1] = mono_type_get_object (mono_domain_get (), sig->ret);
+                       res = mono_runtime_invoke (box_method, NULL, box_args, &box_exc);
+                       g_assert (!box_exc);
+               }
+
                if (has_byref_nullables) {
                        /* 
                         * The runtime invoke wrapper already converted byref nullables back,