2003-05-27 Dietmar Maurer <dietmar@ximian.com>
[mono.git] / mono / mini / jit-icalls.c
index 9c25a351c8a380bd2ecd95e5fc0a327ae1bb497a..2e2a6d19707bbfb1f44c4be4976c925ed14dd5b0 100644 (file)
@@ -60,6 +60,20 @@ helper_memset (void *addr, int val, int size)
        memset (addr, val, size);
 }
 
+static void
+helper_stelem_ref (MonoArray *array, int index, MonoObject *val)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       if (index >= array->max_length)
+               mono_raise_exception (mono_get_exception_index_out_of_range ());
+
+       if (val && !mono_object_isinst (val, array->obj.vtable->klass->element_class))
+               mono_raise_exception (mono_get_exception_array_type_mismatch ());
+
+       mono_array_set (array, gpointer, index, val);
+}
+
 static gint64 
 mono_llmult (gint64 a, gint64 b)
 {
@@ -168,6 +182,9 @@ mono_llmult_ovf (guint32 al, gint32 ah, guint32 bl, gint32 bh)
 
        res += t1;
 
+       if (res < 0)
+               goto raise_exception;
+
        if (sign < 0)
                return -res;
        else
@@ -260,7 +277,7 @@ ves_array_element_address (MonoArray *this, ...)
 {
        MonoClass *class;
        va_list ap;
-       int i, ind, esize;
+       int i, ind, esize, realidx;
        gpointer ea;
 
        MONO_ARCH_SAVE_REGS;
@@ -271,20 +288,23 @@ ves_array_element_address (MonoArray *this, ...)
 
        class = this->obj.vtable->klass;
 
-       ind = va_arg(ap, int);
        g_assert (this->bounds != NULL);
 
-       ind -= this->bounds [0].lower_bound;
+       esize = mono_array_element_size (class);
+       ind = va_arg(ap, int);
+       ind -= (int)this->bounds [0].lower_bound;
+       if ((guint32)ind >= (guint32)this->bounds [0].length)
+               mono_raise_exception (mono_get_exception_index_out_of_range ());
        for (i = 1; i < class->rank; i++) {
-               ind = ind*this->bounds [i].length + va_arg(ap, int) -
-                       this->bounds [i].lower_bound;;
+               realidx = va_arg(ap, int) - (int)this->bounds [i].lower_bound;
+               if ((guint32)realidx >= (guint32)this->bounds [i].length)
+                       mono_raise_exception (mono_get_exception_index_out_of_range ());
+               ind *= this->bounds [i].length;
+               ind += realidx;
        }
+       esize *= ind;
 
-       if (ind >= this->max_length)
-               mono_raise_exception (mono_get_exception_index_out_of_range ());
-
-       esize = mono_array_element_size (class);
-       ea = (gpointer*)((char*)this->vector + (ind * esize));
+       ea = (gpointer*)((char*)this->vector + esize);
 
        va_end(ap);
 
@@ -331,6 +351,7 @@ static gpointer
 mono_class_static_field_address (MonoDomain *domain, MonoClassField *field)
 {
        MonoVTable *vtable;
+       gpointer addr;
        
        MONO_ARCH_SAVE_REGS;
 
@@ -339,11 +360,17 @@ mono_class_static_field_address (MonoDomain *domain, MonoClassField *field)
        mono_class_init (field->parent);
 
        vtable = mono_class_vtable (domain, field->parent);
+       if (!vtable->initialized)
+               mono_runtime_class_init (vtable);
 
        //printf ("SFLDA1 %p\n", (char*)vtable->data + field->offset);
 
+       if (!domain->thread_static_fields || !(addr = g_hash_table_lookup (domain->thread_static_fields, field)))
+               addr = (char*)vtable->data + field->offset;
+       else
+               addr = mono_threads_get_static_data (GPOINTER_TO_UINT (addr));
        
-       return (char*)vtable->data + field->offset;
+       return addr;
 }
 
 static gpointer