Merge pull request #2770 from lambdageek/dev/monoerror-object_isinst_mbyref
authormonojenkins <jo.shields+jenkins@xamarin.com>
Mon, 28 Mar 2016 14:45:22 +0000 (15:45 +0100)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Mon, 28 Mar 2016 14:45:22 +0000 (15:45 +0100)
[runtime] MonoError-ize mono_object_isinst{,_mbyref}

Also mark them external only.  Runtime should use mono_object_isinst_mbyref_checked and mono_object_isinst_checked

20 files changed:
mcs/class/System/System.Net.Sockets/SafeSocketHandle.cs
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/console-unix.c
mono/metadata/icall.c
mono/metadata/marshal.c
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/object.h
mono/metadata/reflection.c
mono/metadata/remoting.c
mono/metadata/socket-io.c
mono/metadata/threadpool-ms-io.c
mono/metadata/threadpool-ms.c
mono/metadata/threadpool-ms.h
mono/mini/aot-runtime.c
mono/mini/debugger-agent.c
mono/mini/image-writer.c
mono/mini/jit-icalls.c
mono/mini/mini-runtime.c

index e0f8569969f680c662d71a55e2019a5650015656..33f83eccec481a4768b360eb7a4552b41b38f936 100644 (file)
@@ -16,6 +16,7 @@ namespace System.Net.Sockets {
        sealed class SafeSocketHandle : SafeHandleZeroOrMinusOneIsInvalid {
 
                List<Thread> blocking_threads;
+               bool in_cleanup;
 
                const int SOCKET_CLOSED = 10004;
 
@@ -43,32 +44,36 @@ namespace System.Net.Sockets {
 #endif
 
                        if (blocking_threads != null) {
-                               int abort_attempts = 0;
-                               while (blocking_threads.Count > 0) {
-                                       if (abort_attempts++ >= ABORT_RETRIES) {
-                                               if (THROW_ON_ABORT_RETRIES)
-                                                       throw new Exception ("Could not abort registered blocking threads before closing socket.");
-
-                                               // Attempts to close the socket safely failed.
-                                               // We give up, and close the socket with pending blocking system calls.
-                                               // This should not occur, nonetheless if it does this avoids an endless loop.
-                                               break;
-                                       }
-
-                                       /*
-                                        * This method can be called by the DangerousRelease inside RegisterForBlockingSyscall
-                                        * When this happens blocking_threads contains the current thread.
-                                        * We can safely close the socket and throw SocketException in RegisterForBlockingSyscall
-                                        * before the blocking system call.
-                                        */
-                                       lock (blocking_threads) {
+                               lock (blocking_threads) {
+                                       int abort_attempts = 0;
+                                       while (blocking_threads.Count > 0) {
+                                               if (abort_attempts++ >= ABORT_RETRIES) {
+                                                       if (THROW_ON_ABORT_RETRIES)
+                                                               throw new Exception ("Could not abort registered blocking threads before closing socket.");
+
+                                                       // Attempts to close the socket safely failed.
+                                                       // We give up, and close the socket with pending blocking system calls.
+                                                       // This should not occur, nonetheless if it does this avoids an endless loop.
+                                                       break;
+                                               }
+
+                                               /*
+                                               * This method can be called by the DangerousRelease inside RegisterForBlockingSyscall
+                                               * When this happens blocking_threads contains the current thread.
+                                               * We can safely close the socket and throw SocketException in RegisterForBlockingSyscall
+                                               * before the blocking system call.
+                                               */
                                                if (blocking_threads.Count == 1 && blocking_threads[0] == Thread.CurrentThread)
                                                        break;
-                                       }
 
-                                       AbortRegisteredThreads ();
-                                       // Sleep so other threads can resume
-                                       Thread.Sleep (1);
+                                               // abort registered threads
+                                               foreach (var t in blocking_threads)
+                                                       Socket.cancel_blocking_socket_operation (t);
+
+                                               // Sleep so other threads can resume
+                                               in_cleanup = true;
+                                               Monitor.Wait (blocking_threads, 100);
+                                       }
                                }
                        }
 
@@ -105,16 +110,8 @@ namespace System.Net.Sockets {
                        //If this NRE, we're in deep problems because Register Must have
                        lock (blocking_threads) {
                                blocking_threads.Remove (Thread.CurrentThread);
-                       }
-               }
-
-               void AbortRegisteredThreads () {
-                       if (blocking_threads == null)
-                               return;
-
-                       lock (blocking_threads) {
-                               foreach (var t in blocking_threads)
-                                       Socket.cancel_blocking_socket_operation (t);
+                               if (in_cleanup && blocking_threads.Count == 0)
+                                       Monitor.Pulse (blocking_threads);
                        }
                }
        }
index c8323fbe935a51f5649a502b17580f71472f8934..51d6b04a1830bc292a564151b4792b20f05bee4c 100644 (file)
@@ -941,7 +941,7 @@ void
 mono_classes_cleanup (void);
 
 void
-mono_class_layout_fields   (MonoClass *klass);
+mono_class_layout_fields   (MonoClass *klass, int instance_size);
 
 void
 mono_class_setup_interface_offsets (MonoClass *klass);
index 952bea941afeee6256826b7ad6e0ea0fceebf8c3..801d7851be5ba77b9b9a35cf80353b53de76a7fd 100644 (file)
@@ -1480,6 +1480,7 @@ mono_class_setup_fields (MonoClass *klass)
        int i, blittable = TRUE;
        guint32 real_size = 0;
        guint32 packing_size = 0;
+       int instance_size;
        gboolean explicit_size;
        MonoClassField *field;
        MonoGenericContainer *container = NULL;
@@ -1555,7 +1556,7 @@ mono_class_setup_fields (MonoClass *klass)
                }
        }
 
-       klass->instance_size = 0;
+       instance_size = 0;
        if (!klass->rank)
                klass->sizes.class_size = 0;
 
@@ -1569,13 +1570,13 @@ mono_class_setup_fields (MonoClass *klass)
                                return;
                        }
                }
-               klass->instance_size += klass->parent->instance_size;
+               instance_size += klass->parent->instance_size;
                klass->min_align = klass->parent->min_align;
                /* we use |= since it may have been set already */
                klass->has_references |= klass->parent->has_references;
                blittable = klass->parent->blittable;
        } else {
-               klass->instance_size = sizeof (MonoObject);
+               instance_size = sizeof (MonoObject);
                klass->min_align = 1;
        }
 
@@ -1597,14 +1598,16 @@ mono_class_setup_fields (MonoClass *klass)
                        return;
                }
                klass->packing_size = packing_size;
-               real_size += klass->instance_size;
+               real_size += instance_size;
        }
 
        if (!top) {
                if (explicit_size && real_size) {
-                       klass->instance_size = MAX (real_size, klass->instance_size);
+                       instance_size = MAX (real_size, instance_size);
                }
                klass->blittable = blittable;
+               if (!klass->instance_size)
+                       klass->instance_size = instance_size;
                mono_memory_barrier ();
                klass->size_inited = 1;
                klass->fields_inited = 1;
@@ -1718,12 +1721,12 @@ mono_class_setup_fields (MonoClass *klass)
                return;
        }
        if (explicit_size && real_size) {
-               klass->instance_size = MAX (real_size, klass->instance_size);
+               instance_size = MAX (real_size, instance_size);
        }
 
        if (mono_class_has_failure (klass))
                return;
-       mono_class_layout_fields (klass);
+       mono_class_layout_fields (klass, instance_size);
 
        /*valuetypes can't be neither bigger than 1Mb or empty. */
        if (klass->valuetype && (klass->instance_size <= 0 || klass->instance_size > (0x100000 + sizeof (MonoObject))))
@@ -1804,6 +1807,7 @@ type_has_references (MonoClass *klass, MonoType *ftype)
 /*
  * mono_class_layout_fields:
  * @class: a class
+ * @instance_size: base instance size
  *
  * Compute the placement of fields inside an object or struct, according to
  * the layout rules and set the following fields in @class:
@@ -1816,7 +1820,7 @@ type_has_references (MonoClass *klass, MonoType *ftype)
  * LOCKING: this is supposed to be called with the loader lock held.
  */
 void
-mono_class_layout_fields (MonoClass *klass)
+mono_class_layout_fields (MonoClass *klass, int instance_size)
 {
        int i;
        const int top = klass->field.count;
@@ -1897,7 +1901,6 @@ mono_class_layout_fields (MonoClass *klass)
        /*
         * Compute field layout and total size (not considering static fields)
         */
-
        switch (layout) {
        case TYPE_ATTRIBUTE_AUTO_LAYOUT:
        case TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT:
@@ -1973,11 +1976,11 @@ mono_class_layout_fields (MonoClass *klass)
                                real_size = field->offset + size;
                        }
 
-                       klass->instance_size = MAX (real_size, klass->instance_size);
+                       instance_size = MAX (real_size, instance_size);
        
-                       if (klass->instance_size & (klass->min_align - 1)) {
-                               klass->instance_size += klass->min_align - 1;
-                               klass->instance_size &= ~(klass->min_align - 1);
+                       if (instance_size & (klass->min_align - 1)) {
+                               instance_size += klass->min_align - 1;
+                               instance_size &= ~(klass->min_align - 1);
                        }
                }
                break;
@@ -2062,10 +2065,10 @@ mono_class_layout_fields (MonoClass *klass)
                        g_free (ref_bitmap);
                }
 
-               klass->instance_size = MAX (real_size, klass->instance_size);
-               if (klass->instance_size & (klass->min_align - 1)) {
-                       klass->instance_size += klass->min_align - 1;
-                       klass->instance_size &= ~(klass->min_align - 1);
+               instance_size = MAX (real_size, instance_size);
+               if (instance_size & (klass->min_align - 1)) {
+                       instance_size += klass->min_align - 1;
+                       instance_size &= ~(klass->min_align - 1);
                }
                break;
        }
@@ -2081,11 +2084,17 @@ mono_class_layout_fields (MonoClass *klass)
                 * unaligned accesses otherwise. See #78990 for a testcase.
                 */
                if (mono_align_small_structs) {
-                       if (klass->instance_size <= sizeof (MonoObject) + sizeof (gpointer))
-                               klass->min_align = MAX (klass->min_align, klass->instance_size - sizeof (MonoObject));
+                       if (instance_size <= sizeof (MonoObject) + sizeof (gpointer))
+                               klass->min_align = MAX (klass->min_align, instance_size - sizeof (MonoObject));
                }
        }
 
+       if (klass->instance_size && !klass->image->dynamic) {
+               /* Might be already set using cached info */
+               g_assert (klass->instance_size == instance_size);
+       } else {
+               klass->instance_size = instance_size;
+       }
        mono_memory_barrier ();
        klass->size_inited = 1;
 
index fe59f700ea987d7a621daff20544b7808ec62acd..43c97c7cfef1a574191fb8a994edc27e90c22acc 100644 (file)
@@ -254,7 +254,11 @@ do_console_cancel_event (void)
        method = mono_class_get_method_from_name (klass, "BeginInvoke", -1);
        g_assert (method != NULL);
 
-       mono_threadpool_ms_begin_invoke (domain, (MonoObject*) load_value, method, NULL);
+       mono_threadpool_ms_begin_invoke (domain, (MonoObject*) load_value, method, NULL, &error);
+       if (!is_ok (&error)) {
+               g_warning ("Couldn't invoke System.Console cancel handler due to %s", mono_error_get_message (&error));
+               mono_error_cleanup (&error);
+       }
 }
 
 static int need_cancel = FALSE;
index 6d52508576935d0ac419ea08554d4a9d71e6dfd4..7cdd170e90c21362efb46c2441889359a96c24d5 100644 (file)
@@ -138,19 +138,23 @@ mono_class_init_checked (MonoClass *klass, MonoError *error)
 ICALL_EXPORT MonoObject *
 ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
 {
+       MonoError error;
        MonoClass *ac;
        gint32 esize;
        gpointer *ea;
+       MonoObject *result = NULL;
 
        ac = (MonoClass *)arr->obj.vtable->klass;
 
        esize = mono_array_element_size (ac);
        ea = (gpointer*)((char*)arr->vector + (pos * esize));
 
-       if (ac->element_class->valuetype)
-               return mono_value_box (arr->obj.vtable->domain, ac->element_class, ea);
-       else
-               return (MonoObject *)*ea;
+       if (ac->element_class->valuetype) {
+               result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
+               mono_error_set_pending_exception (&error);
+       } else
+               result = (MonoObject *)*ea;
+       return result;
 }
 
 ICALL_EXPORT MonoObject *
@@ -3192,6 +3196,7 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, Mo
 ICALL_EXPORT MonoObject *
 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs) 
 {
+       MonoError error;
        MonoDomain *domain = mono_object_domain (method); 
        MonoMethod *m = method->method;
        MonoMethodSignature *sig = mono_method_signature (m);
@@ -3220,9 +3225,11 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, M
                                MonoClassField* field = mono_class_get_field_from_name (k, str);
                                if (field) {
                                        MonoClass *field_klass =  mono_class_from_mono_type (field->type);
-                                       if (field_klass->valuetype)
-                                               result = mono_value_box (domain, field_klass, (char *)this_arg + field->offset);
-                                       else 
+                                       if (field_klass->valuetype) {
+                                               result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
+                                               mono_error_set_pending_exception (&error);
+                                               /* fallthru to cleanup */
+                                       } else 
                                                result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
                                
                                        out_args = mono_array_new (domain, mono_defaults.object_class, 1);
@@ -4383,8 +4390,7 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, MonoString *name, guint
 
        mono_ptr_array_destroy (tmp_array);
 
-       if (!str)
-               g_free (str);
+       g_free (str);
 
        return res;
 }
@@ -7632,12 +7638,16 @@ mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
 ICALL_EXPORT MonoObject*
 mono_TypedReference_ToObject (MonoTypedRef* tref)
 {
+       MonoError error;
+       MonoObject *result = NULL;
        if (MONO_TYPE_IS_REFERENCE (tref->type)) {
                MonoObject** objp = (MonoObject **)tref->value;
                return *objp;
        }
 
-       return mono_value_box (mono_domain_get (), tref->klass, tref->value);
+       result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
 }
 
 ICALL_EXPORT MonoTypedRef
index b4bd2de1129ef354430278735af2ba28485027e5..1874918e1509a31d11b37083570faae4a11a9c40 100644 (file)
@@ -528,7 +528,11 @@ mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn)
 
                if (use_aot_wrappers) {
                        wrapper = mono_marshal_get_native_func_wrapper_aot (klass);
-                       this_obj = mono_value_box (mono_domain_get (), mono_defaults.int_class, &ftn);
+                       this_obj = mono_value_box_checked (mono_domain_get (), mono_defaults.int_class, &ftn, &error);
+                       if (!is_ok (&error)) {
+                               mono_error_set_pending_exception (&error);
+                               return NULL;
+                       }
                } else {
                        memset (&piinfo, 0, sizeof (piinfo));
                        parse_unmanaged_function_pointer_attr (klass, &piinfo);
@@ -2214,7 +2218,9 @@ mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params)
                method = mono_get_delegate_invoke (klass);
        g_assert (method);
 
-       return mono_threadpool_ms_begin_invoke (mono_domain_get (), (MonoObject*) delegate, method, params);
+       MonoAsyncResult *result = mono_threadpool_ms_begin_invoke (mono_domain_get (), (MonoObject*) delegate, method, params, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
 }
 
 #ifndef DISABLE_JIT
index bd702ff35b3e477c7e022b46dd57da46294b1e6b..0abd946be1810387f47d20ff7af0020acda250a3 100644 (file)
@@ -1454,8 +1454,11 @@ mono_get_addr_from_ftnptr (gpointer descr);
 void
 mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass);
 
+MonoObject *
+mono_value_box_checked (MonoDomain *domain, MonoClass *klass, void* val, MonoError *error);
+
 MonoObject*
-mono_nullable_box (guint8 *buf, MonoClass *klass);
+mono_nullable_box (guint8 *buf, MonoClass *klass, MonoError *error);
 
 #ifdef MONO_SMALL_CONFIG
 #define MONO_IMT_SIZE 9
index ace688284a166f5f1fd8554ad8c8fca2adf778ce..55f5c898b3b42bb6822c399458f82575e145b07f 100644 (file)
@@ -3506,7 +3506,7 @@ mono_field_get_value_object_checked (MonoDomain *domain, MonoClassField *field,
        klass = mono_class_from_mono_type (type);
 
        if (mono_class_is_nullable (klass))
-               return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass);
+               return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass, error);
 
        o = mono_object_new_checked (domain, klass, error);
        return_val_if_nok (error, NULL);
@@ -3734,17 +3734,17 @@ mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass)
  * mono_nullable_box:
  * @buf: The buffer representing the data to be boxed
  * @klass: the type to box it as.
+ * @error: set on oerr
  *
  * Creates a boxed vtype or NULL from the Nullable structure pointed to by
- * @buf.
+ * @buf.  On failure returns NULL and sets @error
  */
 MonoObject*
-mono_nullable_box (guint8 *buf, MonoClass *klass)
+mono_nullable_box (guint8 *buf, MonoClass *klass, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoError error;
-       
+       mono_error_init (error);
        MonoClass *param_class = klass->cast_class;
 
        mono_class_setup_fields_locking (klass);
@@ -3754,8 +3754,8 @@ mono_nullable_box (guint8 *buf, MonoClass *klass)
        g_assert (mono_class_from_mono_type (klass->fields [1].type) == mono_defaults.boolean_class);
 
        if (*(guint8*)(buf + klass->fields [1].offset - sizeof (MonoObject))) {
-               MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, error);
+               return_val_if_nok (error, NULL);
                if (param_class->has_references)
                        mono_gc_wbarrier_value_copy (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), 1, param_class);
                else
@@ -4600,7 +4600,8 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
                                                 * boxed object in the arg array with the copy.
                                                 */
                                                MonoObject *orig = mono_array_get (params, MonoObject*, i);
-                                               MonoObject *copy = mono_value_box (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig));
+                                               MonoObject *copy = mono_value_box_checked (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig), &error);
+                                               mono_error_raise_exception (&error); /* FIXME don't raise here */
                                                mono_array_setref (params, i, copy);
                                        }
                                                
@@ -4652,8 +4653,11 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
 
                        if (!params)
                                return NULL;
-                       else
-                               return mono_value_box (mono_domain_get (), method->klass->cast_class, pa [0]);
+                       else {
+                               MonoObject *result = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, pa [0], &error);
+                               mono_error_raise_exception (&error); /* FIXME don't raise here */
+                               return result;
+                       }
                }
 
                if (!obj) {
@@ -4669,7 +4673,8 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
                        else
                                o = obj;
                } else if (method->klass->valuetype) {
-                       obj = mono_value_box (mono_domain_get (), method->klass, obj);
+                       obj = mono_value_box_checked (mono_domain_get (), method->klass, obj, &error);
+                       mono_error_raise_exception (&error); /* FIXME don't raise here */
                }
 
                if (exc) {
@@ -4692,7 +4697,9 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
                        nullable = mono_object_new_checked (mono_domain_get (), method->klass, &error);
                        mono_error_raise_exception (&error); /* FIXME don't raise here */
 
-                       mono_nullable_init ((guint8 *)mono_object_unbox (nullable), mono_value_box (mono_domain_get (), method->klass->cast_class, obj), method->klass);
+                       MonoObject *boxed = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, obj, &error);
+                       mono_error_raise_exception (&error); /* FIXME don't raise here */
+                       mono_nullable_init ((guint8 *)mono_object_unbox (nullable), boxed, method->klass);
                        obj = mono_object_unbox (nullable);
                }
 
@@ -5798,23 +5805,42 @@ mono_string_new_wrapper (const char *text)
 MonoObject *
 mono_value_box (MonoDomain *domain, MonoClass *klass, gpointer value)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
        MonoError error;
+       MonoObject *result = mono_value_box_checked (domain, klass, value, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+/**
+ * mono_value_box_checked:
+ * @domain: the domain of the new object
+ * @class: the class of the value
+ * @value: a pointer to the unboxed data
+ * @error: set on error
+ *
+ * Returns: A newly created object which contains @value. On failure
+ * returns NULL and sets @error.
+ */
+MonoObject *
+mono_value_box_checked (MonoDomain *domain, MonoClass *klass, gpointer value, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
        MonoObject *res;
        int size;
        MonoVTable *vtable;
 
+       mono_error_init (error);
+
        g_assert (klass->valuetype);
        if (mono_class_is_nullable (klass))
-               return mono_nullable_box ((guint8 *)value, klass);
+               return mono_nullable_box ((guint8 *)value, klass, error);
 
        vtable = mono_class_vtable (domain, klass);
        if (!vtable)
                return NULL;
        size = mono_class_instance_size (klass);
-       res = mono_object_new_alloc_specific_checked (vtable, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       res = mono_object_new_alloc_specific_checked (vtable, error);
+       return_val_if_nok (error, NULL);
 
        size = size - sizeof (MonoObject);
 
@@ -5844,8 +5870,8 @@ mono_value_box (MonoDomain *domain, MonoClass *klass, gpointer value)
 #endif
 #endif
        if (klass->has_finalize) {
-               mono_object_register_finalizer (res, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               mono_object_register_finalizer (res, error);
+               return_val_if_nok (error, NULL);
        }
        return res;
 }
@@ -7275,9 +7301,10 @@ mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *
 
                klass = mono_class_from_mono_type (sig->params [i]);
 
-               if (klass->valuetype)
-                       arg = mono_value_box (domain, klass, vpos);
-               else 
+               if (klass->valuetype) {
+                       arg = mono_value_box_checked (domain, klass, vpos, &error);
+                       mono_error_raise_exception (&error); /* FIXME don't raise here */
+               } else 
                        arg = *((MonoObject **)vpos);
                      
                mono_array_setref (msg->args, i, arg);
@@ -7538,9 +7565,10 @@ mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField
                        mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
        }
 
-       if (field_class->valuetype)
-               arg = mono_value_box (domain, field_class, val);
-       else 
+       if (field_class->valuetype) {
+               arg = mono_value_box_checked (domain, field_class, val, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
+       } else 
                arg = *((MonoObject **)val);
                
 
index 5f7551ddb2da5c1f13c1d2c7029122dad6eaf0fa..360dcd0d63188714790752d0e38c6e846496e662 100644 (file)
@@ -162,6 +162,7 @@ mono_object_hash            (MonoObject* obj);
 MONO_API MonoString *
 mono_object_to_string (MonoObject *obj, MonoObject **exc);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoObject *
 mono_value_box             (MonoDomain *domain, MonoClass *klass, void* val);
 
index 48df2f05256615cf76100fa277b2756c8d599fe8..59e958c10f67db3cbe116a210cad48b715e5e227 100644 (file)
@@ -187,6 +187,8 @@ static gboolean is_sr_mono_property (MonoClass *klass);
 static gboolean is_sre_method_on_tb_inst (MonoClass *klass);
 static gboolean is_sre_ctor_on_tb_inst (MonoClass *klass);
 
+static gboolean type_is_reference (MonoType *type);
+
 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
 static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
@@ -9215,6 +9217,28 @@ handle_type:
        return NULL;
 }
 
+static MonoObject*
+load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char** end, MonoError *error)
+{
+       mono_error_init (error);
+
+       gboolean is_ref = type_is_reference (t);
+
+       void *val = load_cattr_value (image, t, p, end, error);
+       if (!is_ok (error)) {
+               if (is_ref)
+                       g_free (val);
+               return NULL;
+       }
+
+       if (is_ref)
+               return (MonoObject*)val;
+
+       MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (t), val, error);
+       g_free (val);
+       return boxed;
+}
+
 static MonoObject*
 create_cattr_typed_arg (MonoType *t, MonoObject *val, MonoError *error)
 {
@@ -9550,21 +9574,10 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
        p += 2;
        for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
                MonoObject *obj;
-               void *val;
 
-               val = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p, error);
-               if (!mono_error_ok (error)) {
-                       if (!type_is_reference (mono_method_signature (method)->params [i]))
-                               g_free (val);
-                       return;
-               }
-
-               obj = (MonoObject *)(type_is_reference (mono_method_signature (method)->params [i]) ?
-                       val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val));
+               obj = load_cattr_value_boxed (domain, image, mono_method_signature (method)->params [i], p, &p, error);
+               return_if_nok (error);
                mono_array_setref (typedargs, i, obj);
-
-               if (!type_is_reference (mono_method_signature (method)->params [i]))
-                       g_free (val);
        }
 
        named = p;
@@ -9607,7 +9620,6 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
                if (named_type == 0x53) {
                        MonoObject *obj;
                        MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
-                       void *val;
 
                        if (!field) {
                                g_free (name);
@@ -9617,23 +9629,17 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
                        arginfo [j].type = field->type;
                        arginfo [j].field = field;
 
-                       val = load_cattr_value (image, field->type, named, &named, error);
-                       if (!mono_error_ok (error)) {
-                               if (!type_is_reference (field->type))
-                                       g_free (val);
+                       obj = load_cattr_value_boxed (domain, image, field->type, named, &named, error);
+                       if (!is_ok (error)) {
                                g_free (name);
                                return;
                        }
-
-                       obj = (MonoObject *)(type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val));
                        mono_array_setref (namedargs, j, obj);
-                       if (!type_is_reference (field->type))
-                               g_free (val);
+
                } else if (named_type == 0x54) {
                        MonoObject *obj;
                        MonoType *prop_type;
                        MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
-                       void *val;
 
                        if (!prop || !prop->set) {
                                g_free (name);
@@ -9646,18 +9652,12 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
                        arginfo [j].type = prop_type;
                        arginfo [j].prop = prop;
 
-                       val = load_cattr_value (image, prop_type, named, &named, error);
-                       if (!mono_error_ok (error)) {
-                               if (!type_is_reference (prop_type))
-                                       g_free (val);
+                       obj = load_cattr_value_boxed (domain, image, prop_type, named, &named, error);
+                       if (!is_ok (error)) {
                                g_free (name);
                                return;
                        }
-
-                       obj = (MonoObject *)(type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val));
                        mono_array_setref (namedargs, j, obj);
-                       if (!type_is_reference (prop_type))
-                               g_free (val);
                }
                g_free (name);
        }
@@ -12898,7 +12898,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        }
 
        klass->instance_size = MAX (klass->instance_size, real_size);
-       mono_class_layout_fields (klass);
+       mono_class_layout_fields (klass, klass->instance_size);
 }
 
 static void
index 9b621c92fc577f1ec9e486e9f7fe2e8db2cfd4d3..9c329f4934247bb8218f87c7f518d48cca3e006a 100644 (file)
@@ -373,9 +373,10 @@ mono_remoting_wrapper (MonoMethod *method, gpointer *params)
                                        mparams[i] = *((gpointer *)params [i]);
                                } else {
                                        /* runtime_invoke expects a boxed instance */
-                                       if (mono_class_is_nullable (mono_class_from_mono_type (sig->params [i])))
-                                               mparams[i] = mono_nullable_box ((guint8 *)params [i], klass);
-                                       else
+                                       if (mono_class_is_nullable (mono_class_from_mono_type (sig->params [i]))) {
+                                               mparams[i] = mono_nullable_box ((guint8 *)params [i], klass, &error);
+                                               mono_error_raise_exception (&error); /* FIXME don't raise here */
+                                       } else
                                                mparams[i] = params [i];
                                }
                        } else {
@@ -2009,7 +2010,10 @@ mono_marshal_xdomain_copy_value (MonoObject *val)
        case MONO_TYPE_U8:
        case MONO_TYPE_R4:
        case MONO_TYPE_R8: {
-               return mono_value_box (domain, mono_object_class (val), ((char*)val) + sizeof(MonoObject));
+               MonoObject *res = mono_value_box_checked (domain, mono_object_class (val), ((char*)val) + sizeof(MonoObject), &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               return res;
+
        }
        case MONO_TYPE_STRING: {
                MonoString *str = (MonoString *) val;
index 56212ac57cf8df16137f7c781167cc76919b0561..7f8c7beaa2c59019244a98d143006fac2582c76e 100644 (file)
@@ -1925,7 +1925,10 @@ ves_icall_System_Net_Sockets_Socket_Select_internal (MonoArray **sockets, gint32
 static MonoObject*
 int_to_object (MonoDomain *domain, int val)
 {
-       return mono_value_box (domain, mono_get_int32_class (), &val);
+       MonoError error;
+       MonoObject *result = mono_value_box_checked (domain, mono_get_int32_class (), &val, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       return result;
 }
 
 void
index 11029082f8bda156b5a52d577f07c4a43e7fbbed..30e34e50a3c5bcdd5dc096fd8154953cafd9c690 100644 (file)
@@ -245,6 +245,8 @@ filter_jobs_for_domain (gpointer key, gpointer value, gpointer user_data)
 static void
 wait_callback (gint fd, gint events, gpointer user_data)
 {
+       MonoError error;
+
        if (mono_runtime_is_shutting_down ())
                return;
 
@@ -269,13 +271,18 @@ wait_callback (gint fd, gint events, gpointer user_data)
 
                if (list && (events & EVENT_IN) != 0) {
                        MonoIOSelectorJob *job = get_job_for_event (&list, EVENT_IN);
-                       if (job)
-                               mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job);
+                       if (job) {
+                               mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job, &error);
+                               mono_error_raise_exception (&error); /* FIXME don't raise here */
+                       }
+
                }
                if (list && (events & EVENT_OUT) != 0) {
                        MonoIOSelectorJob *job = get_job_for_event (&list, EVENT_OUT);
-                       if (job)
-                               mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job);
+                       if (job) {
+                               mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job, &error);
+                               mono_error_raise_exception (&error); /* FIXME don't raise here */
+                       }
                }
 
                remove_fd = (events & EVENT_ERR) == EVENT_ERR;
@@ -301,6 +308,7 @@ wait_callback (gint fd, gint events, gpointer user_data)
 static void
 selector_thread (gpointer data)
 {
+       MonoError error;
        MonoGHashTable *states;
 
        io_selector_running = TRUE;
@@ -368,8 +376,10 @@ selector_thread (gpointer data)
                                                        memset (update, 0, sizeof (ThreadPoolIOUpdate));
                                        }
 
-                                       for (; list; list = mono_mlist_remove_item (list, list))
-                                               mono_threadpool_ms_enqueue_work_item (mono_object_domain (mono_mlist_get_data (list)), mono_mlist_get_data (list));
+                                       for (; list; list = mono_mlist_remove_item (list, list)) {
+                                               mono_threadpool_ms_enqueue_work_item (mono_object_domain (mono_mlist_get_data (list)), mono_mlist_get_data (list), &error);
+                                               mono_error_raise_exception (&error); /* FIXME don't raise here */
+                                       }
 
                                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: del fd %3d", fd);
                                        threadpool_io->backend.remove_fd (fd);
index 1c5ac4f42f1bea25cace38a9fcb0098e6dab50bf..32d93e6e522490a4564332d022e0ddb013ca251f 100644 (file)
@@ -344,16 +344,16 @@ cleanup (void)
        mono_coop_mutex_unlock (&threadpool->active_threads_lock);
 }
 
-void
-mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item)
+gboolean
+mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item, MonoError *error)
 {
        static MonoClass *threadpool_class = NULL;
        static MonoMethod *unsafe_queue_custom_work_item_method = NULL;
-       MonoError error;
        MonoDomain *current_domain;
        MonoBoolean f;
        gpointer args [2];
 
+       mono_error_init (error);
        g_assert (work_item);
 
        if (!threadpool_class)
@@ -370,17 +370,21 @@ mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item)
 
        current_domain = mono_domain_get ();
        if (current_domain == domain) {
-               mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, error);
+               return_val_if_nok (error, FALSE);
        } else {
                mono_thread_push_appdomain_ref (domain);
                if (mono_domain_set (domain, FALSE)) {
-                       mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, &error);
-                       mono_error_raise_exception (&error); /* FIXME don't raise here */
+                       mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, error);
+                       if (!is_ok (error)) {
+                               mono_thread_pop_appdomain_ref ();
+                               return FALSE;
+                       }
                        mono_domain_set (current_domain, TRUE);
                }
                mono_thread_pop_appdomain_ref ();
        }
+       return TRUE;
 }
 
 /* LOCKING: threadpool->domains_lock must be held */
@@ -1314,10 +1318,9 @@ mono_threadpool_ms_cleanup (void)
 }
 
 MonoAsyncResult *
-mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMethod *method, gpointer *params)
+mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMethod *method, gpointer *params, MonoError *error)
 {
        static MonoClass *async_call_klass = NULL;
-       MonoError error;
        MonoMethodMessage *message;
        MonoAsyncResult *async_result;
        MonoAsyncCall *async_call;
@@ -1329,10 +1332,12 @@ mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMet
 
        mono_lazy_initialize (&status, initialize);
 
+       mono_error_init (error);
+
        message = mono_method_call_message_new (method, params, mono_get_delegate_invoke (method->klass), (params != NULL) ? (&async_callback) : NULL, (params != NULL) ? (&state) : NULL);
 
-       async_call = (MonoAsyncCall*) mono_object_new_checked (domain, async_call_klass, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       async_call = (MonoAsyncCall*) mono_object_new_checked (domain, async_call_klass, error);
+       return_val_if_nok (error, NULL);
 
        MONO_OBJECT_SETREF (async_call, msg, message);
        MONO_OBJECT_SETREF (async_call, state, state);
@@ -1345,7 +1350,8 @@ mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMet
        async_result = mono_async_result_new (domain, NULL, async_call->state, NULL, (MonoObject*) async_call);
        MONO_OBJECT_SETREF (async_result, async_delegate, target);
 
-       mono_threadpool_ms_enqueue_work_item (domain, (MonoObject*) async_result);
+       mono_threadpool_ms_enqueue_work_item (domain, (MonoObject*) async_result, error);
+       return_val_if_nok (error, NULL);
 
        return async_result;
 }
@@ -1583,7 +1589,9 @@ void
 ves_icall_System_Threading_ThreadPool_ReportThreadStatus (MonoBoolean is_working)
 {
        // TODO
-       mono_raise_exception (mono_get_exception_not_implemented (NULL));
+       MonoError error;
+       mono_error_set_not_implemented (&error, "");
+       mono_error_set_pending_exception (&error);
 }
 
 MonoBoolean
@@ -1596,7 +1604,9 @@ MonoBoolean G_GNUC_UNUSED
 ves_icall_System_Threading_ThreadPool_PostQueuedCompletionStatus (MonoNativeOverlapped *native_overlapped)
 {
        /* This copy the behavior of the current Mono implementation */
-       mono_raise_exception (mono_get_exception_not_implemented (NULL));
+       MonoError error;
+       mono_error_set_not_implemented (&error, "");
+       mono_error_set_pending_exception (&error);
        return FALSE;
 }
 
index 8aee68c4c035c10b0cfb88870a771de5ccc79d4e..9812ee57ba2a989617ac1b96f54997a3cc3c0b58 100644 (file)
@@ -15,7 +15,7 @@ void
 mono_threadpool_ms_cleanup (void);
 
 MonoAsyncResult *
-mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMethod *method, gpointer *params);
+mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMethod *method, gpointer *params, MonoError *error);
 MonoObject *
 mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, MonoObject **exc);
 
@@ -59,7 +59,7 @@ ves_icall_System_Threading_ThreadPool_IsThreadPoolHosted (void);
 
 /* Internals */
 
-void
-mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item);
+gboolean
+mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item, MonoError *error);
 
 #endif // _MONO_THREADPOOL_MICROSOFT_H_
index 70995807817dd3cf50f4978b046bcf45404f5724..4f633c190af2b0cac360db5e69a43ad7eda30728 100644 (file)
@@ -3059,7 +3059,7 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain,
                        mono_error_cleanup (&error); /* FIXME don't swallow the error */
                }
 
-               gi->generic_sharing_context = g_new0 (MonoGenericSharingContext, 1);
+               gi->generic_sharing_context = alloc0_jit_info_data (domain, sizeof (MonoGenericSharingContext), async);
                if (decode_value (p, &p)) {
                        /* gsharedvt */
                        MonoGenericSharingContext *gsctx = gi->generic_sharing_context;
index 4c791507cc3775777fb5e32e80d057292f1841e0..e69085073ec92c79b6f8f916477963336506168a 100644 (file)
@@ -6031,6 +6031,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr,
                        } else if (type == VALUE_TYPE_ID_NULL) {
                                *(MonoObject**)addr = NULL;
                        } else if (type == MONO_TYPE_VALUETYPE) {
+                               MonoError error;
                                guint8 *buf2;
                                gboolean is_enum;
                                MonoClass *klass;
@@ -6062,7 +6063,8 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr,
                                        g_free (vtype_buf);
                                        return err;
                                }
-                               *(MonoObject**)addr = mono_value_box (d, klass, vtype_buf);
+                               *(MonoObject**)addr = mono_value_box_checked (d, klass, vtype_buf, &error);
+                               mono_error_cleanup (&error);
                                g_free (vtype_buf);
                        } else {
                                char *name = mono_type_full_name (t);
@@ -6084,6 +6086,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr,
 static ErrorCode
 decode_value (MonoType *t, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8 **endbuf, guint8 *limit)
 {
+       MonoError error;
        ErrorCode err;
        int type = decode_byte (buf, &buf, limit);
 
@@ -6108,7 +6111,12 @@ decode_value (MonoType *t, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8
                                g_free (nullable_buf);
                                return err;
                        }
-                       mono_nullable_init (addr, mono_value_box (domain, mono_class_from_mono_type (targ), nullable_buf), mono_class_from_mono_type (t));
+                       MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (targ), nullable_buf, &error);
+                       if (!is_ok (&error)) {
+                               mono_error_cleanup (&error);
+                               return ERR_INVALID_OBJECT;
+                       }
+                       mono_nullable_init (addr, boxed, mono_class_from_mono_type (t));
                        g_free (nullable_buf);
                        *endbuf = buf;
                        return ERR_NONE;
index c216f3b25755f4231091b096a4f506990e4a8d2f..c060fdc99a66028193f1d3efa63033a18d6a0eca 100644 (file)
@@ -1686,6 +1686,9 @@ bin_writer_emit_writeout (MonoImageWriter *acfg)
 static void
 asm_writer_emit_start (MonoImageWriter *acfg)
 {
+#if defined(TARGET_ASM_APPLE)
+       fprintf (acfg->fp, ".subsections_via_symbols\n");
+#endif
 }
 
 static int
index 5297283f5191ff7d75020bbbad1b6764566cef2d..dbf89a8d517e0ea20d793f181a7c8f65487aeffb 100644 (file)
@@ -1334,7 +1334,7 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
                /*
                 * Calling a non-vtype method with a vtype receiver, has to box.
                 */
-               *this_arg = mono_value_box (mono_domain_get (), klass, mp);
+               *this_arg = mono_value_box_checked (mono_domain_get (), klass, mp, error);
        else if (klass->valuetype)
                /*
                 * Calling a vtype method with a vtype receiver
index cce368bdcffebb3489011cd609228d17131ab67e..ba0aad7dce30161796170b5ec6173d927b8c9b99 100644 (file)
@@ -2502,7 +2502,7 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void
                mono_error_set_exception_instance (error, (MonoException*) *exc);
 
        if (sig->ret->type != MONO_TYPE_VOID && info->ret_box_class)
-               return mono_value_box (domain, info->ret_box_class, retval);
+               return mono_value_box_checked (domain, info->ret_box_class, retval, error);
        else
                return *(MonoObject**)retval;
 }
@@ -2677,7 +2677,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                mono_arch_finish_dyn_call (info->dyn_call_info, buf);
 
                if (info->ret_box_class)
-                       return mono_value_box (domain, info->ret_box_class, retval);
+                       return mono_value_box_checked (domain, info->ret_box_class, retval, error);
                else
                        return *(MonoObject**)retval;
        }