#include <mono/metadata/loader.h>
#include <mono/metadata/object.h>
#include <mono/metadata/appdomain.h>
-#if G_BYTE_ORDER != G_LITTLE_ENDIAN
-#include <sys/mman.h>
-#include <limits.h> /* for PAGESIZE */
-#ifndef PAGESIZE
-#define PAGESIZE 4096
-#endif
+#if HAVE_BOEHM_GC
+#include <gc/gc.h>
#endif
static void
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;
}
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
}
/**
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;
}
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];
{
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);
}
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;
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
vt->interface_offsets [klass->interface_id])
return obj;
} else {
- if ((oklass->baseval - klass->baseval) <= klass->diffval)
+ 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)
+ return obj;
+ } else if ((oklass->baseval - klass->baseval) <= klass->diffval)
return obj;
}
return NULL;
}
-
-typedef struct {
- MonoString *obj;
- MonoString *found;
-} InternCheck;
-
-static void
-check_interned (gpointer key, MonoString *value, InternCheck *check)
+static MonoString*
+mono_string_is_interned_lookup (MonoString *str, int insert)
{
- 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)
-{
- GHashTable *ldstr_table;
+ MonoGHashTable *ldstr_table;
MonoString *res;
char *ins = g_malloc (4 + str->length * 2);
char *p;
p = ins;
mono_metadata_encode_value (bloblen + 2 * str->length, p, &p);
bloblen = (p - ins) + 2 * str->length;
+ /*
+ * ins is stored in the hash table as a key and needs to have the same
+ * representation as in the metadata: we swap the character bytes on big
+ * endian boxes.
+ */
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+ {
+ int i;
+ char *p2 = mono_array_addr (str->c_str, char, 0);
+ for (i = 0; i < str->length; ++i) {
+ *p++ = p2 [1];
+ *p++ = p2 [0];
+ p2 += 2;
+ }
+ }
+#else
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*
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);
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
-#define SWAP16(x) (x) = GUINT16_FROM_LE ((x))
{
- gint i;
- guint16 *s;
- /* FIXME: we need to find better way for swapping strings, i.e. swap all string after image load */
- static GHashTable *converted_strings = NULL;
-
- if (!converted_strings)
- converted_strings = g_hash_table_new (g_str_hash, g_str_equal);
-
- if (converted_strings && !g_hash_table_lookup (converted_strings, str)) {
- /* FIXME: it will be better to just add WRITE and after get it to previous state */
- mprotect ((void *) ((int) str & ~(PAGESIZE - 1)), len2 + ((int) str & (PAGESIZE - 1)),
- PROT_READ | PROT_WRITE | PROT_EXEC);
- len2 >>= 1;
- /* printf ("swap %p\n", str); */
- for (i = 0, s = (guint16 *) str; i < len2; i++, s++) {
- *s = ((*s & 0xff) << 8) | (*s >> 8);
- }
- g_hash_table_insert (converted_strings, (gpointer) str, (gpointer) str);
- } else
- len2 >>= 1;
+ int i;
+ guint16 *p2 = (guint16*)mono_array_addr (o->c_str, guint16, 0);
+ for (i = 0; i < len2; ++i) {
+ *p2 = GUINT16_FROM_LE (*p2);
+ ++p2;
+ }
}
-#undef SWAP16
-#else
- len2 >>= 1;
#endif
-
- o = mono_string_new_utf16 (domain, (guint16*)str, len2);
- g_hash_table_insert (domain->ldstr_table, (gpointer)sig, o);
+ mono_g_hash_table_insert (domain->ldstr_table, (gpointer)sig, o);
return o;
}
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;
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
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;
+}
+