2007-05-01 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / metadata / object.c
index 4f34e30f43f289a4691ea4bfdd2a46cec251846d..30d3059882003d455a157ec6adde2b4de045d58d 100644 (file)
@@ -245,6 +245,13 @@ mono_runtime_class_init (MonoVTable *vtable)
        exc = NULL;
        klass = vtable->klass;
 
+       if (!klass->image->checked_module_cctor) {
+               mono_image_check_for_module_cctor (klass->image);
+               if (klass->image->has_module_cctor) {
+                       MonoClass *module_klass = mono_class_get (klass->image, MONO_TOKEN_TYPE_DEF | 1);
+                       mono_runtime_class_init (mono_class_vtable (vtable->domain, module_klass));
+               }
+       }
        method = mono_class_get_cctor (klass);
 
        if (method) {
@@ -586,13 +593,17 @@ compute_class_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int
 
                        type = mono_type_get_underlying_type (field->type);
                        switch (type->type) {
-                       /* FIXME: _I and _U and _PTR should be removed eventually */
                        case MONO_TYPE_I:
-                       case MONO_TYPE_U:
                        case MONO_TYPE_PTR:
                        case MONO_TYPE_FNPTR:
+                               break;
+                       /* only UIntPtr is allowed to be GC-tracked and only in mscorlib */
+                       case MONO_TYPE_U:
 #ifdef HAVE_SGEN_GC
                                break;
+#else
+                               if (class->image != mono_defaults.corlib)
+                                       break;
 #endif
                        case MONO_TYPE_STRING:
                        case MONO_TYPE_SZARRAY:
@@ -952,7 +963,6 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class)
                if (!mono_class_init (class) || class->exception_type){
                        MonoException *exc;
                        mono_domain_unlock (domain);
-                       mono_loader_clear_error ();
                        exc = mono_class_get_exception_for_failure (class);
                        g_assert (exc);
                        mono_raise_exception (exc);
@@ -1493,7 +1503,7 @@ mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mon
                MonoClass *klass;
                type = ((MonoReflectionType *)rp->class_to_proxy)->type;
                klass = mono_class_from_mono_type (type);
-               if ((klass->is_com_object || klass == mono_defaults.com_object_class) && !mono_class_vtable (mono_domain_get (), klass)->remote)
+               if ((klass->is_com_object || (mono_defaults.com_object_class && klass == mono_defaults.com_object_class)) && !mono_class_vtable (mono_domain_get (), klass)->remote)
                        remote_class->default_vtable = mono_class_proxy_vtable (domain, remote_class, MONO_REMOTING_TARGET_COMINTEROP);
                else
                        remote_class->default_vtable = mono_class_proxy_vtable (domain, remote_class, MONO_REMOTING_TARGET_UNKNOWN);
@@ -1713,7 +1723,8 @@ handle_enum:
                return;
        }
        case MONO_TYPE_VALUETYPE:
-               if (type->data.klass->enumtype) {
+               /* note that 't' and 'type->type' can be different */
+               if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
                        t = type->data.klass->enum_basetype->type;
                        goto handle_enum;
                } else {
@@ -1741,7 +1752,8 @@ handle_enum:
  * @value: The value to be set
  *
  * Sets the value of the field described by @field in the object instance @obj
- * to the value passed in @value.
+ * to the value passed in @value.   This method should only be used for instance
+ * fields.   For static fields, use mono_field_static_set_value.
  *
  * The value must be on the native format of the field type. 
  */
@@ -2829,7 +2841,11 @@ mono_object_clone (MonoObject *obj)
        o = mono_object_allocate (size, obj->vtable);
        /* do not copy the sync state */
        memcpy ((char*)o + sizeof (MonoObject), (char*)obj + sizeof (MonoObject), size - sizeof (MonoObject));
-       
+
+#ifdef HAVE_SGEN_GC
+       if (obj->vtable->klass->has_references)
+               mono_gc_wbarrier_object (o);
+#endif
        mono_profiler_allocation (o, obj->vtable->klass);
 
        if (obj->vtable->klass->has_finalize)
@@ -2857,7 +2873,18 @@ mono_array_full_copy (MonoArray *src, MonoArray *dest)
        size = mono_array_length (src);
        g_assert (size == mono_array_length (dest));
        size *= mono_array_element_size (klass);
+#ifdef HAVE_SGEN_GC
+       if (klass->valuetype) {
+               if (klass->has_references)
+                       mono_value_copy_array (dest, 0, src, mono_array_length (src));
+               else
+                       memcpy (&dest->vector, &src->vector, size);
+       } else {
+               mono_array_memcpy_refs (dest, 0, src, 0, mono_array_length (src));
+       }
+#else
        memcpy (&dest->vector, &src->vector, size);
+#endif
 }
 
 /**
@@ -2883,7 +2910,18 @@ mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
                o = mono_array_new_full (domain, klass, &size, NULL);
 
                size *= mono_array_element_size (klass);
+#ifdef HAVE_SGEN_GC
+               if (klass->valuetype) {
+                       if (klass->has_references)
+                               mono_value_copy_array (o, 0, array, mono_array_length (array));
+                       else
+                               memcpy (&o->vector, &array->vector, size);
+               } else {
+                       mono_array_memcpy_refs (o, 0, array, 0, mono_array_length (array));
+               }
+#else
                memcpy (&o->vector, &array->vector, size);
+#endif
                return o;
        }
        
@@ -2895,7 +2933,18 @@ mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
                sizes [i + klass->rank] = array->bounds [i].lower_bound;
        }
        o = mono_array_new_full (domain, klass, sizes, sizes + klass->rank);
+#ifdef HAVE_SGEN_GC
+       if (klass->valuetype) {
+               if (klass->has_references)
+                       mono_value_copy_array (o, 0, array, mono_array_length (array));
+               else
+                       memcpy (&o->vector, &array->vector, size);
+       } else {
+               mono_array_memcpy_refs (o, 0, array, 0, mono_array_length (array));
+       }
+#else
        memcpy (&o->vector, &array->vector, size);
+#endif
 
        return o;
 }
@@ -3229,6 +3278,10 @@ mono_value_box (MonoDomain *domain, MonoClass *class, gpointer value)
 
        size = size - sizeof (MonoObject);
 
+#ifdef HAVE_SGEN_GC
+       mono_gc_wbarrier_value_copy ((char *)res + sizeof (MonoObject), value, 1, class);
+#endif
+
 #if NO_UNALIGNED_ACCESS
        memcpy ((char *)res + sizeof (MonoObject), value, size);
 #else
@@ -3773,14 +3826,43 @@ MonoWaitHandle *
 mono_wait_handle_new (MonoDomain *domain, HANDLE handle)
 {
        MonoWaitHandle *res;
+       gpointer params [1];
+       static MonoMethod *handle_set;
 
        res = (MonoWaitHandle *)mono_object_new (domain, mono_defaults.waithandle_class);
 
-       res->handle = handle;
+       /* Even though this method is virtual, it's safe to invoke directly, since the object type matches.  */
+       if (!handle_set)
+               handle_set = mono_class_get_property_from_name (mono_defaults.waithandle_class, "Handle")->set;
+
+       params [0] = &handle;
+       mono_runtime_invoke (handle_set, res, params, NULL);
 
        return res;
 }
 
+HANDLE
+mono_wait_handle_get_handle (MonoWaitHandle *handle)
+{
+       static MonoClassField *f_os_handle;
+       static MonoClassField *f_safe_handle;
+
+       if (!f_os_handle && !f_safe_handle) {
+               f_os_handle = mono_class_get_field_from_name (mono_defaults.waithandle_class, "os_handle");
+               f_safe_handle = mono_class_get_field_from_name (mono_defaults.waithandle_class, "safe_wait_handle");
+       }
+
+       if (f_os_handle) {
+               HANDLE retval;
+               mono_field_get_value ((MonoObject*)handle, f_os_handle, &retval);
+               return retval;
+       } else {
+               MonoSafeHandle *sh;
+               mono_field_get_value ((MonoObject*)handle, f_safe_handle, &sh);
+               return sh->handle;
+       }
+}
+
 /**
  * mono_async_result_new:
  * @domain:domain where the object will be created.