Fri Mar 29 18:09:08 CET 2002 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / object.c
index 27669fb13df7e7da18dd55cba9ba72515f725ce5..365f1a2170003c372584f2a6bc512772ff5613e6 100644 (file)
@@ -15,6 +15,9 @@
 #include <mono/metadata/loader.h>
 #include <mono/metadata/object.h>
 #include <mono/metadata/appdomain.h>
+#if HAVE_BOEHM_GC
+#include <gc/gc.h>
+#endif
 
 static void
 default_runtime_object_init (MonoObject *o)
@@ -49,7 +52,11 @@ mono_install_runtime_exec_main (MonoRuntimeExecMain func)
 void *
 mono_object_allocate (size_t size)
 {
+#if HAVE_BOEHM_GC
+       void *o = GC_debug_malloc (size, "object", 1);
+#else
        void *o = calloc (1, size);
+#endif
 
        return o;
 }
@@ -63,10 +70,14 @@ mono_object_allocate (size_t size)
 void
 mono_object_free (MonoObject *o)
 {
+#if HAVE_BOEHM_GC
+       g_error ("mono_object_free called with boehm gc.");
+#else
        MonoClass *c = o->vtable->klass;
        
        memset (o, 0, c->instance_size);
        free (o);
+#endif
 }
 
 /**
@@ -79,13 +90,23 @@ mono_object_free (MonoObject *o)
 MonoObject *
 mono_object_new (MonoDomain *domain, MonoClass *klass)
 {
+       static guint32 uoid = 0;
        MonoObject *o;
 
        if (!klass->inited)
                mono_class_init (klass);
 
-       o = mono_object_allocate (klass->instance_size);
-       o->vtable = mono_class_vtable (domain, klass);
+
+       if (klass->ghcimpl) {
+               o = mono_object_allocate (klass->instance_size);
+               o->vtable = mono_class_vtable (domain, klass);
+       } else {
+               guint32 *t;
+               t = mono_object_allocate (klass->instance_size + 4);
+               *t = ++uoid;
+               o = (MonoObject *)(++t);
+               o->vtable = mono_class_vtable (domain, klass);
+       }
 
        return o;
 }
@@ -172,7 +193,11 @@ mono_array_new_full (MonoDomain *domain, MonoClass *array_class,
 
        byte_len = mono_array_element_size (array_class);
 
+#if HAVE_BOEHM_GC
+       bounds = GC_debug_malloc (sizeof (MonoArrayBounds) * array_class->rank, "bounds", 0);
+#else
        bounds = g_malloc0 (sizeof (MonoArrayBounds) * array_class->rank);
+#endif
        for (i = 0; i < array_class->rank; ++i) {
                bounds [i].length = lengths [i];
                byte_len *= lengths [i];
@@ -211,7 +236,7 @@ mono_array_new (MonoDomain *domain, MonoClass *eclass, guint32 n)
 {
        MonoClass *ac;
 
-       ac = mono_array_class_get (eclass, 1);
+       ac = mono_array_class_get (&eclass->byval_arg, 1);
        g_assert (ac != NULL);
 
        return mono_array_new_full (domain, ac, &n, NULL);
@@ -245,8 +270,7 @@ mono_string_new_utf16 (MonoDomain *domain, const guint16 *text, gint32 len)
 }
 
 MonoString*
-mono_string_new_len
-(MonoDomain *domain, const char *text, guint length)
+mono_string_new_len (MonoDomain *domain, const char *text, guint length)
 {
        GError *error = NULL;
        MonoString *o = NULL;
@@ -295,6 +319,14 @@ mono_string_new (MonoDomain *domain, const char *text)
        return o;
 }
 
+MonoString*
+mono_string_new_wrapper (const char *text)
+{
+       MonoDomain *domain = mono_domain_get ();
+
+       return mono_string_new (domain, text);
+}
+
 /**
  * mono_value_box:
  * @class: the class of the value
@@ -348,6 +380,13 @@ mono_object_isinst (MonoObject *obj, MonoClass *klass)
                    vt->interface_offsets [klass->interface_id])
                        return obj;
        } else {
+               if (oklass == mono_defaults.transparent_proxy_class) {
+                       /* fixme: add check for IRemotingTypeInfo */
+                       MonoRealProxy *rp = ((MonoTransparentProxy *)obj)->rp;
+                       MonoType *type;
+                       type = ((MonoReflectionType *)rp->class_to_proxy)->type;
+                       oklass = mono_class_from_mono_type (type);
+               }
                if (oklass->rank && oklass->rank == klass->rank) {
                        if ((oklass->element_class->baseval - klass->element_class->baseval) <= 
                            klass->element_class->diffval)
@@ -359,38 +398,10 @@ mono_object_isinst (MonoObject *obj, MonoClass *klass)
        return NULL;
 }
 
-
-typedef struct {
-       MonoString *obj;
-       MonoString *found;
-} InternCheck;
-
-static void
-check_interned (gpointer key, MonoString *value, InternCheck *check)
-{
-       if (value == check->obj)
-               check->found = value;
-}
-
-MonoString*
-mono_string_is_interned (MonoString *o)
-{
-       InternCheck check;
-       check.obj = o;
-       check.found = NULL;
-
-       /*
-        * Yes, this is slow. Our System.String implementation needs to be redone.
-        * And GLib needs foreach() methods that can be stopped halfway.
-        */
-       g_hash_table_foreach (((MonoObject *)o)->vtable->domain->ldstr_table, (GHFunc)check_interned, &check);
-       return check.found;
-}
-
-MonoString*
-mono_string_intern (MonoString *str)
+static MonoString*
+mono_string_is_interned_lookup (MonoString *str, int insert)
 {
-       GHashTable *ldstr_table;
+       MonoGHashTable *ldstr_table;
        MonoString *res;
        char *ins = g_malloc (4 + str->length * 2);
        char *p;
@@ -422,12 +433,28 @@ mono_string_intern (MonoString *str)
        memcpy (p, str->c_str->vector, str->length * 2);
 #endif
        ldstr_table = ((MonoObject *)str)->vtable->domain->ldstr_table;
-       if ((res = g_hash_table_lookup (ldstr_table, ins))) {
+       if ((res = mono_g_hash_table_lookup (ldstr_table, ins))) {
                g_free (ins);
                return res;
        }
-       g_hash_table_insert (ldstr_table, ins, str);
-       return str;
+       if (insert) {
+               mono_g_hash_table_insert (ldstr_table, ins, str);
+               return str;
+       }
+       g_free (ins);
+       return NULL;
+}
+
+MonoString*
+mono_string_is_interned (MonoString *o)
+{
+       return mono_string_is_interned_lookup (o, FALSE);
+}
+
+MonoString*
+mono_string_intern (MonoString *str)
+{
+       return mono_string_is_interned_lookup (str, TRUE);
 }
 
 MonoString*
@@ -438,11 +465,11 @@ mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 index)
        size_t len2;
                
        sig = str = mono_metadata_user_string (image, index);
-       len2 = mono_metadata_decode_blob_size (str, &str);
        
-       if ((o = g_hash_table_lookup (domain->ldstr_table, sig)))
+       if ((o = mono_g_hash_table_lookup (domain->ldstr_table, sig)))
                return o;
        
+       len2 = mono_metadata_decode_blob_size (str, &str);
        len2 >>= 1;
 
        o = mono_string_new_utf16 (domain, (guint16*)str, len2);
@@ -456,7 +483,7 @@ mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 index)
                }
        }
 #endif
-       g_hash_table_insert (domain->ldstr_table, (gpointer)sig, o);
+       mono_g_hash_table_insert (domain->ldstr_table, (gpointer)sig, o);
 
        return o;
 }
@@ -477,13 +504,13 @@ mono_string_to_utf8 (MonoString *s)
        g_assert (vector != NULL);
 
        as = g_utf16_to_utf8 ((gunichar2 *)vector, s->length, NULL, NULL, &error);
-
-       g_assert (!error);
+       if (error)
+               g_warning (error->message);
 
        return as;
 }
 
-char *
+gunichar2 *
 mono_string_to_utf16 (MonoString *s)
 {
        char *as;
@@ -495,12 +522,12 @@ mono_string_to_utf16 (MonoString *s)
        as [(s->length * 2) + 1] = '\0';
 
        if (!s->length || !s->c_str) {
-               return (as);
+               return (gunichar2 *)(as);
        }
        
        memcpy (as, mono_string_chars(s), s->length * 2);
        
-       return (as);
+       return (gunichar2 *)(as);
 }
 
 static void
@@ -524,3 +551,31 @@ mono_raise_exception (MonoException *ex)
        ex_handler (ex);
 }
 
+MonoWaitHandle *
+mono_wait_handle_new (MonoDomain *domain, HANDLE handle)
+{
+       MonoWaitHandle *res;
+
+       res = (MonoWaitHandle *)mono_object_new (domain, mono_defaults.waithandle_class);
+
+       res->handle = handle;
+
+       return res;
+}
+
+MonoAsyncResult *
+mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data)
+{
+       MonoAsyncResult *res;
+
+       res = (MonoAsyncResult *)mono_object_new (domain, mono_defaults.asyncresult_class);
+
+       res->data = data;
+       res->async_state = state;
+       res->handle = mono_wait_handle_new (domain, handle);
+       res->sync_completed = FALSE;
+       res->completed = FALSE;
+
+       return res;
+}
+