2001-11-30 Dietmar Maurer <dietmar@ximian.com>
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 30 Nov 2001 12:39:30 +0000 (12:39 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 30 Nov 2001 12:39:30 +0000 (12:39 -0000)
* emit-x86.c (tree_preallocate_regs): improved register allocation

* x86.brg: impl. ISINST, CASTCLASS

* class.c (mono_install_runtime_class_init): impl.
(mono_class_init): renamed mono_class_metadata_init to
mono_class_init, also removed the metadata_inited flag

* object.c (mono_object_isinst): use faster algorithm

svn path=/trunk/mono/; revision=1493

16 files changed:
mono/interpreter/interp.c
mono/jit/ChangeLog
mono/jit/TODO
mono/jit/debug.c
mono/jit/emit-x86.c
mono/jit/jit.c
mono/jit/jit.h
mono/jit/x86.brg
mono/metadata/ChangeLog
mono/metadata/class.c
mono/metadata/class.h
mono/metadata/exception.c
mono/metadata/icall.c
mono/metadata/loader.c
mono/metadata/object.c
mono/metadata/object.h

index 27f9ca220d494690738028db5498f64a32ff2efa..89d5e31d07902b342085c59ce4a416fb8859da95 100644 (file)
@@ -100,12 +100,13 @@ interp_ex_handler (MonoException *ex) {
 }
 
 static void
-interp_ex_obj_init(MonoObject *obj, MonoClass *klass)
+runtime_object_init (MonoObject *obj)
 {
        int i;
        MonoInvocation call;
        MonoMethod *method = NULL;
-       
+       MonoClass *klass = obj->klass;
+
        for (i = 0; i < klass->method.count; ++i) {
                if (!strcmp (".ctor", klass->methods [i]->name) &&
                    klass->methods [i]->signature->param_count == 0) {
@@ -139,34 +140,23 @@ ves_real_abort (int line, MonoMethod *mh,
 #define ves_abort() do {ves_real_abort(__LINE__, frame->method, ip, frame->stack, sp); THROW_EX (get_exception_execution_engine (), ip);} while (0);
 
 /*
- * init_class:
+ * runtime_class_init:
  * @klass: klass that needs to be initialized
  *
- * This routine calls the class constructor for @class if it needs it.
+ * This routine calls the class constructor for @class.
  */
 static void
-init_class (MonoClass *klass)
+runtime_class_init (MonoClass *klass)
 {
        MonoMethod *method;
        MonoInvocation call;
        int i;
 
-       if (!klass->metadata_inited)
-               mono_class_metadata_init (klass);
-
-       if (klass->inited)
-               return;
-
-       if (klass->parent && !klass->parent->inited)
-               init_class (klass->parent);
-       
-       klass->inited = 1;
-
        for (i = 0; i < klass->method.count; ++i) {
                method = klass->methods [i];
-               if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && (strcmp (".cctor", method->name) == 0)) {
+               if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && 
+                   (strcmp (".cctor", method->name) == 0)) {
                        INIT_FRAME (&call, NULL, NULL, NULL, NULL, method);
-       
                        ves_exec_method (&call);
                        return;
                }
@@ -184,7 +174,7 @@ get_virtual_method (MonoMethod *m, stackval *objs)
        if ((m->flags & METHOD_ATTRIBUTE_FINAL) || !(m->flags & METHOD_ATTRIBUTE_VIRTUAL))
                        return m;
 
-       g_assert (m->klass->metadata_inited);
+       g_assert (m->klass->inited);
 
        obj = objs->data.p;
        klass = obj->klass;
@@ -196,116 +186,6 @@ get_virtual_method (MonoMethod *m, stackval *objs)
        return vtable [m->slot];
 }
 
-static MonoObject*
-get_exception_divide_by_zero ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "DivideByZeroException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_security ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "SecurityException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_arithmetic ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "ArithmeticException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_overflow ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "OverflowException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_null_reference ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "NullReferenceException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_execution_engine ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "ExecutionEngineException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_invalid_cast ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "InvalidCastException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_index_out_of_range ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "IndexOutOfRangeException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_array_type_mismatch ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "ArrayTypeMismatchException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_missing_method ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = mono_exception_from_name (mono_defaults.corlib, "System",
-                                      "MissingMethodException");
-       return ex;
-}
-
 void inline
 stackval_from_data (MonoType *type, stackval *result, const char *data)
 {
@@ -603,7 +483,7 @@ ves_runtime_method (MonoInvocation *frame)
        MonoObject *obj = (MonoObject*)frame->obj;
        MonoDelegate *delegate = (MonoDelegate*)frame->obj;
 
-       init_class(mono_defaults.delegate_class);
+       mono_class_init (mono_defaults.delegate_class);
        
        if (*name == '.' && (strcmp (name, ".ctor") == 0) && obj &&
                        mono_object_isinst (obj, mono_defaults.delegate_class)) {
@@ -834,8 +714,7 @@ ves_exec_method (MonoInvocation *frame)
        vtallocation *vtalloc = NULL;
        GOTO_LABEL_VARS;
 
-       if (!frame->method->klass->inited)
-               init_class (frame->method->klass);
+       mono_class_init (frame->method->klass);
 
        DEBUG_ENTER ();
 
@@ -2144,8 +2023,7 @@ array_constructed:
                        token = read32 (ip);
                        c = mono_class_get (image, token);
 
-                       if (!c->inited)
-                               init_class (c);
+                       mono_class_init (c);
 
                        g_assert (sp [-1].type == VAL_OBJ);
 
@@ -2297,13 +2175,11 @@ array_constructed:
                        /* need to handle fieldrefs */
                        if (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF) {
                                field = mono_field_from_memberref (image, token, &klass);
-                               if (!klass->inited)
-                                       init_class (klass);
+                               mono_class_init (klass);
                        } else {
                                klass = mono_class_get (image, 
                                        MONO_TOKEN_TYPE_DEF | mono_metadata_typedef_from_field (image, token & 0xffffff));
-                               if (!klass->inited)
-                                       init_class (klass);
+                               mono_class_init (klass);
                                field = mono_class_get_field (klass, token);
                        }
                        g_assert (field);
@@ -2331,8 +2207,7 @@ array_constructed:
                        /* need to handle fieldrefs */
                        klass = mono_class_get (image, 
                                MONO_TOKEN_TYPE_DEF | mono_metadata_typedef_from_field (image, token & 0xffffff));
-                       if (!klass->inited)
-                               init_class (klass);
+                       mono_class_init (klass);
                        field = mono_class_get_field (klass, token);
                        g_assert (field);
                        stackval_to_data (field->type, sp, (char*)MONO_CLASS_STATIC_FIELDS_BASE(klass) + field->offset);
@@ -3362,7 +3237,7 @@ test_load_class (MonoImage* image)
 
        for (i = 1; i <= t->rows; ++i) {
                klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i);
-               mono_class_metadata_init (klass);
+               mono_class_init (klass);
        }
 }
 #endif
@@ -3516,7 +3391,7 @@ check_corlib (MonoImage *corlib)
                        klass = mono_class_from_name (corlib, ndesc->name, cdesc->name);
                        if (!klass)
                                g_error ("Cannot find class %s", cdesc->name);
-                       mono_class_metadata_init (klass);
+                       mono_class_init (klass);
                        for (fdesc = cdesc->fields; fdesc->name; ++fdesc) {
                                field = mono_class_get_field_from_name (klass, fdesc->name);
                                if (!field || (field->offset != fdesc->offset))
@@ -3556,8 +3431,13 @@ main (int argc, char *argv [])
 
        mono_init ();
        mono_init_icall ();
+
+       mono_install_runtime_class_init (runtime_class_init);
+       mono_install_runtime_object_init (runtime_object_init);
+
        mono_install_handler (interp_ex_handler);
-       mono_exception_install_handlers(init_class, interp_ex_obj_init);
+
+       //mono_exception_install_handlers(init_class, interp_ex_obj_init);
        
        mono_add_internal_call ("__array_Set", ves_array_set);
        mono_add_internal_call ("__array_Get", ves_array_get);
index d64807a9708f249ff5c3ae4e9a047f3e1db18eae..e84cefa1bf810850a10bc275d8da66ecac311177 100644 (file)
@@ -1,3 +1,8 @@
+2001-11-30  Dietmar Maurer  <dietmar@ximian.com>
+
+       * emit-x86.c (tree_preallocate_regs): improved register allocation
+
+       * x86.brg: impl. ISINST, CASTCLASS
 
 Fri Nov 30 12:02:24 CET 2001 Paolo Molaro <lupus@ximian.com>
 
index 322d4b42877b8108e71218710eba40173a565b69..7a19fc67539404d82dda765a48a3bc5f3185d5bc 100644 (file)
@@ -1,9 +1,12 @@
+* impl. marshalling attributes for pinvoke
+* raise exceptions everywhere
+* implement all those CONV and CONV_OVF opcodes
+* impl. value type: simple thing works already
 * exceptions: handle exceptions inside unmanaged code
 * exceptions: save/restore floating point state
-* implementet all floating point instruction in x86.brg, we also need to check
+* implement all floating point instruction in x86.brg, we also need to check
   the floating branch instruction - some of them seems to be wrong, we need to
   write better tests for that.
-* implement exceptions
 * correctly align value types on the stack and in arrays
 * enum types can have several base types (not only int32)
 * document the functions and variables in the JIT 
index cef7e823efea08f7c9c442a25fedaba9e6dfd336..a1e7cf3fd0aab4b1a3e3378ce3a64afdd400bd6d 100644 (file)
@@ -216,7 +216,7 @@ mono_debug_add_method (MonoDebugHandle* debug, MonoFlowGraph *cfg)
        for (i = 0; name [i]; ++i)
                if (name [i] == '.') name [i] = '_';
 
-       mono_class_metadata_init (klass);
+       mono_class_init (klass);
        /*
         * Find the method index in the image.
         */
@@ -297,7 +297,7 @@ mono_debug_add_type (MonoDebugHandle* debug, MonoClass *klass)
        char buf [64];
        AssemblyDebugInfo* info = mono_debug_open_ass (debug, klass->image);
 
-       mono_class_metadata_init (klass);
+       mono_class_init (klass);
 
        /* output enums ...*/
        if (klass->enumtype) {
index 35e903f38092f9019cffc64f29352efb1a40ad7f..82480b3689e6c5269024c6338f73102c256cb58a 100644 (file)
@@ -91,6 +91,9 @@ enter_method (MonoMethod *method, gpointer ebp)
                case MONO_TYPE_I8:
                        printf ("%lld, ", *((gint64 *)(ebp)));
                        break;
+               case MONO_TYPE_R4:
+                       printf ("%f, ", *((float *)(ebp)));
+                       break;
                case MONO_TYPE_R8:
                        printf ("%f, ", *((double *)(ebp)));
                        break;
@@ -116,12 +119,19 @@ leave_method (MonoMethod *method, int edx, int eax, double test)
 {
        gint64 l;
 
+       printf ("LEAVE: %s.%s::%s ", method->klass->name_space,
+               method->klass->name, method->name);
+
        switch (method->signature->ret->type) {
        case MONO_TYPE_VOID:
-               printf ("LEAVE: %s.%s::%s\n", method->klass->name_space,
-                       method->klass->name, method->name);
                break;
        case MONO_TYPE_BOOLEAN:
+               if (eax)
+                       printf ("TRUE:%d", eax);
+               else 
+                       printf ("FALSE");
+                       
+               break;
        case MONO_TYPE_CHAR:
        case MONO_TYPE_I1:
        case MONO_TYPE_U1:
@@ -131,27 +141,23 @@ leave_method (MonoMethod *method, int edx, int eax, double test)
        case MONO_TYPE_U4:
        case MONO_TYPE_I:
        case MONO_TYPE_U:
-               printf ("LEAVE: %s.%s::%s EAX=%d\n", method->klass->name_space,
-                       method->klass->name, method->name, eax);
+               printf ("EAX=%d", eax);
                break;
        case MONO_TYPE_STRING:
-               printf ("LEAVE: %s.%s::%s [STRING:%s], ", method->klass->name_space,
-                       method->klass->name, method->name, 
-                       mono_string_to_utf8 ((MonoString *)(eax)));
+               printf ("[STRING:%s]", mono_string_to_utf8 ((MonoString *)(eax)));
                break;
        case MONO_TYPE_OBJECT: {
-               MonoObject *o = (MonoClass *)eax;
+               MonoObject *o = (MonoObject *)eax;
                
-               printf ("LEAVE: %s.%s::%s ", method->klass->name_space,
-                       method->klass->name, method->name);
-
                if (o->klass == mono_defaults.boolean_class) {
-                       printf ("[BOOLEAN:%p:%d]\n", o, *((guint8 *)o + sizeof (MonoObject)));          
+                       printf ("[BOOLEAN:%p:%d]", o, *((guint8 *)o + sizeof (MonoObject)));            
+               } else if  (o->klass == mono_defaults.int32_class) {
+                       printf ("[INT32:%p:%d]", o, *((gint32 *)((gpointer)o + sizeof (MonoObject))));  
                } else {
                        if (o)
-                               printf ("[%s.%s:%p]\n", o->klass->name_space, o->klass->name, o);
+                               printf ("[%s.%s:%p]", o->klass->name_space, o->klass->name, o);
                        else
-                               printf ("EAX=%p\n", (gpointer)eax);
+                               printf ("[OBJECT:%p]", (gpointer)eax);
                }
                break;
        }
@@ -160,23 +166,21 @@ leave_method (MonoMethod *method, int edx, int eax, double test)
        case MONO_TYPE_FNPTR:
        case MONO_TYPE_ARRAY:
        case MONO_TYPE_SZARRAY:
-               printf ("LEAVE: %s.%s::%s EAX=%p\n", method->klass->name_space,
-                       method->klass->name, method->name, (gpointer)eax);
+               printf ("EAX=%p", (gpointer)eax);
                break;
        case MONO_TYPE_I8:
                *((gint32 *)&l) = eax;
                *((gint32 *)&l + 1) = edx;
-               printf ("LEAVE: %s.%s::%s EAX/EDX=%lld\n", method->klass->name_space,
-                       method->klass->name, method->name, l);
+               printf ("EAX/EDX=%lld", l);
                break;
        case MONO_TYPE_R8:
-               printf ("LEAVE: %s.%s::%s FP=%f\n", method->klass->name_space,
-                       method->klass->name, method->name, test);
+               printf ("FP=%f\n", test);
                break;
        default:
-               printf ("LEAVE: %s.%s::%s (unknown return type)\n", method->klass->name_space,
-                       method->klass->name, method->name);
+               printf ("(unknown return type)");
        }
+
+       printf ("\n");
 }
 
 /**
@@ -430,14 +434,18 @@ mono_label_cfg (MonoFlowGraph *cfg)
 }
 
 static void
-tree_allocate_regs (MBTree *tree, int goal, MonoRegSet *rs) 
+tree_preallocate_regs (MBTree *tree, int goal, MonoRegSet *rs) 
 {
-       MBTree *kids[10];
-       int ern = mono_burg_rule (tree->state, goal);
-       guint16 *nts = mono_burg_nts [ern];
-       int i;
-       
-       mono_burg_kids (tree, ern, kids);
+       switch (tree->op) {
+       case MB_TERM_CALL_I4:
+       case MB_TERM_CALL_I8:
+       case MB_TERM_CALL_R8:
+//     case MB_TERM_CALL_VOID :
+               tree->reg1 = mono_regset_alloc_reg (rs, X86_EAX, tree->exclude_mask);
+               tree->reg2 = mono_regset_alloc_reg (rs, X86_EDX, tree->exclude_mask);
+               tree->reg3 = mono_regset_alloc_reg (rs, X86_ECX, tree->exclude_mask);
+               break;
+       }
 
        switch (goal) {
        case MB_NTERM_reg:
@@ -449,19 +457,12 @@ tree_allocate_regs (MBTree *tree, int goal, MonoRegSet *rs)
                        tree->exclude_mask |= (1 << X86_ECX);
                        tree->left->exclude_mask |= (1 << X86_ECX);
                        break;
-               case MB_TERM_CALL_I4:
-                       tree->reg1 = X86_EAX;
-                       break;
-               case MB_TERM_CALL_I8:
-                       tree->reg1 = X86_EAX;
-                       tree->reg2 = X86_EDX;
-                       break;
                case MB_TERM_DIV:
                case MB_TERM_DIV_UN:
                case MB_TERM_REM:
                case MB_TERM_REM_UN:
-                       tree->reg1 = X86_EAX;
-                       tree->reg2 = X86_EDX;
+                       tree->reg1 = mono_regset_alloc_reg (rs, X86_EAX, tree->exclude_mask);
+                       tree->reg2 = mono_regset_alloc_reg (rs, X86_EDX, tree->exclude_mask);
                        if (goal == MB_NTERM_reg) {
                                tree->left->exclude_mask |= (1 << X86_EDX);
                                tree->right->exclude_mask |= (1 << X86_EDX);
@@ -470,10 +471,22 @@ tree_allocate_regs (MBTree *tree, int goal, MonoRegSet *rs)
                default:
                        break;
                }
+               break;
        }
        default:
                break;
        }
+}
+
+static void
+tree_allocate_regs (MBTree *tree, int goal, MonoRegSet *rs) 
+{
+       MBTree *kids[10];
+       int ern = mono_burg_rule (tree->state, goal);
+       guint16 *nts = mono_burg_nts [ern];
+       int i;
+       
+       mono_burg_kids (tree, ern, kids);
 
        //printf ("RALLOC START %d %p %d\n",  tree->op, rs->free_mask, goal);
 
@@ -483,30 +496,34 @@ tree_allocate_regs (MBTree *tree, int goal, MonoRegSet *rs)
                return;
        }
 
+       for (i = 0; nts [i]; i++)
+               tree_preallocate_regs (kids [i], nts [i], rs);
+
        for (i = 0; nts [i]; i++)
                tree_allocate_regs (kids [i], nts [i], rs);
 
        for (i = 0; nts [i]; i++) {
                mono_regset_free_reg (rs, kids [i]->reg1);
                mono_regset_free_reg (rs, kids [i]->reg2);
+               mono_regset_free_reg (rs, kids [i]->reg3);
        }
 
        switch (goal) {
        case MB_NTERM_reg:
-               if ((tree->reg1 = 
-                    mono_regset_alloc_reg (rs, tree->reg1, tree->exclude_mask)) == -1) {
-                       g_warning ("register allocation failed %d 0x%08x 0x%08x\n",  tree->reg1, rs->free_mask, tree->exclude_mask);
-                       g_assert_not_reached ();
+               if (tree->reg1 < 0) { 
+                       tree->reg1 = mono_regset_alloc_reg (rs, -1, tree->exclude_mask);
+                       g_assert (tree->reg1 != -1);
                }
                break;
 
        case MB_NTERM_lreg:
-               if ((tree->reg1 = 
-                    mono_regset_alloc_reg (rs, tree->reg1, tree->exclude_mask)) == -1 ||
-                   (tree->reg2 = 
-                    mono_regset_alloc_reg (rs, tree->reg2, tree->exclude_mask)) == -1) {
-                       g_warning ("register allocation failed\n");
-                       g_assert_not_reached ();
+               if (tree->reg1 < 0) { 
+                       tree->reg1 = mono_regset_alloc_reg (rs, -1, tree->exclude_mask);
+                       g_assert (tree->reg1 != -1);
+               }
+               if (tree->reg2 < 0) { 
+                       tree->reg2 = mono_regset_alloc_reg (rs, -1, tree->exclude_mask);
+                       g_assert (tree->reg2 != -1);
                }
                break;
 
@@ -519,9 +536,6 @@ tree_allocate_regs (MBTree *tree, int goal, MonoRegSet *rs)
                        tree->reg1 = mono_regset_alloc_reg (rs, tree->left->reg1, tree->exclude_mask);
                        tree->reg2 = mono_regset_alloc_reg (rs, tree->right->reg1, tree->exclude_mask);
                }
-               //if (tree->op == MB_TERM_CALL_I4) {
-               //tree->reg1 = mono_regset_alloc_reg (rs, tree->left->reg1, tree->exclude_mask);
-               //}
                break;
                
        case MB_NTERM_base:
@@ -693,7 +707,7 @@ arch_compile_method (MonoMethod *method)
                        delegate = TRUE;
                                
                if (!target_offset) {
-                       mono_jit_init_class (mono_defaults.delegate_class);
+                       mono_class_init (mono_defaults.delegate_class);
 
                        field = mono_class_get_field_from_name (mono_defaults.delegate_class, "m_target");
                        target_offset = field->offset;
index f7700a38afdb885264b75fe1e7a59fad0a0ec78f..4f0777ecfb57cce4d6f86016154d4277adda3bbc 100644 (file)
@@ -240,30 +240,18 @@ mono_jit_info_table_add (MonoJitInfoTable *table, MonoJitInfo *ji)
 }
 
 /**
- * mono_jit_init_class:
+ * runtime_class_init:
  * @klass: the class to initialise
  *
- * Initialise the class @klass by calling the class
- * constructor.
+ * Initialise the class @klass by calling the class constructor.
  */
-void
-mono_jit_init_class (MonoClass *klass)
+static void
+runtime_class_init (MonoClass *klass)
 {
        MonoCCtor cctor;
        MonoMethod *method;
        int i;
 
-       if (!klass->metadata_inited)
-               mono_class_metadata_init (klass);
-
-       if (klass->inited)
-               return;
-
-       if (klass->parent && !klass->parent->inited)
-               mono_jit_init_class (klass->parent);
-       
-       klass->inited = 1;
-
        if (mono_debug_handle)
                mono_debug_add_type (mono_debug_handle, klass);
        
@@ -307,8 +295,7 @@ map_stvalue_type (MonoClass *class)
 
        g_assert (class->valuetype);
 
-       if (!class->inited)
-               mono_jit_init_class (class);
+       mono_class_init (class);
 
        if (class == mono_defaults.double_class)
                return MB_TERM_STIND_R8;
@@ -329,6 +316,58 @@ map_stvalue_type (MonoClass *class)
        return MB_TERM_STIND_OBJ;
 }
 
+static int
+map_stvaluearg_type (MonoClass *class)
+{
+       int size;
+
+       g_assert (class->valuetype);
+
+       mono_class_init (class);
+
+       if (class == mono_defaults.double_class)
+               return MB_TERM_STIND_R8;
+
+       if (class == mono_defaults.single_class)
+               return MB_TERM_STIND_R4;
+
+       size =  class->instance_size - sizeof (MonoObject);
+
+       switch (size) {
+       case 4:
+       case 2:
+       case 1:
+               return MB_TERM_STIND_I4;
+       }
+       return MB_TERM_STIND_OBJ;
+}
+
+static int
+map_argvalue_type (MonoClass *class)
+{
+       int size;
+
+       g_assert (class->valuetype);
+
+       mono_class_init (class);
+
+       if (class == mono_defaults.double_class)
+               return MB_TERM_ARG_R8;
+
+       if (class == mono_defaults.single_class)
+               return MB_TERM_ARG_R4;
+
+       size =  class->instance_size - sizeof (MonoObject);
+
+       switch (size) {
+       case 4:
+       case 2:
+       case 1:
+               return MB_TERM_ARG_I4;
+       }
+       return MB_TERM_ARG_OBJ;
+}
+
 /**
  * map_stind_type:
  * @type: the type to map
@@ -379,6 +418,91 @@ map_stind_type (MonoType *type)
        return -1;
 }
 
+static int
+map_starg_type (MonoType *type)
+{
+       if (type->byref) 
+               return MB_TERM_STIND_I4;
+
+       switch (type->type) {
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_I:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_CLASS:
+       case MONO_TYPE_OBJECT:
+       case MONO_TYPE_STRING:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_SZARRAY:
+       case MONO_TYPE_ARRAY:    
+               return MB_TERM_STIND_I4;
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+               return MB_TERM_STIND_I8;
+       case MONO_TYPE_R4:
+               return MB_TERM_STIND_R4;
+       case MONO_TYPE_R8:
+               return MB_TERM_STIND_R8;
+       case MONO_TYPE_VALUETYPE: 
+               return map_stvaluearg_type (type->data.klass);
+       default:
+               g_warning ("unknown type %02x", type->type);
+               g_assert_not_reached ();
+       }
+
+       g_assert_not_reached ();
+       return -1;
+}
+
+static int
+map_arg_type (MonoType *type, gboolean pinvoke)
+{
+       if (type->byref) 
+               return MB_TERM_ARG_I4;
+
+       switch (type->type) {
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_I:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_CLASS:
+       case MONO_TYPE_OBJECT:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_SZARRAY:
+       case MONO_TYPE_ARRAY:    
+               return MB_TERM_ARG_I4;
+       case MONO_TYPE_STRING:
+               if (pinvoke)
+                       return MB_TERM_ARG_STRING;
+               return MB_TERM_ARG_I4;
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+               return MB_TERM_ARG_I8;
+       case MONO_TYPE_R4:
+               return MB_TERM_ARG_R4;
+       case MONO_TYPE_R8:
+               return MB_TERM_ARG_R8;
+       case MONO_TYPE_VALUETYPE: 
+               return map_argvalue_type (type->data.klass);
+       default:
+               g_warning ("unknown type %02x", type->type);
+               g_assert_not_reached ();
+       }
+
+       g_assert_not_reached ();
+       return -1;
+}
+
 /**
  * map_ldind_type:
  * @type: the type to map
@@ -461,6 +585,67 @@ map_ldind_type (MonoType *type, MonoValueType *svt)
        return -1;
 }
 
+static int
+map_ldarg_type (MonoType *type, MonoValueType *svt)
+{
+       if (type->byref) {
+               *svt = VAL_POINTER;
+               return MB_TERM_LDIND_I4;
+       }
+
+       switch (type->type) {
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_I:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+               *svt = VAL_I32;
+               return MB_TERM_LDIND_U4;
+       case MONO_TYPE_CLASS:
+       case MONO_TYPE_OBJECT:
+       case MONO_TYPE_STRING:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_SZARRAY:
+       case MONO_TYPE_ARRAY:    
+               *svt = VAL_POINTER;
+               return MB_TERM_LDIND_U4;
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+               *svt = VAL_I64;
+               return MB_TERM_LDIND_I8;
+       case MONO_TYPE_R4:
+               *svt = VAL_DOUBLE;
+               return MB_TERM_LDIND_R4;
+       case MONO_TYPE_R8:
+               *svt = VAL_DOUBLE;
+               return MB_TERM_LDIND_R8;
+       case MONO_TYPE_VALUETYPE: {
+               int size, align;
+               size = mono_type_size (type, &align);
+
+               switch (size) {
+               case 4:
+               case 2:
+               case 1:
+                       *svt = VAL_I32;
+                       return MB_TERM_LDIND_U1;
+               default:
+                       g_assert_not_reached ();
+               }
+       }
+       default:
+               g_warning ("unknown type %02x", type->type);
+               g_assert_not_reached ();
+       }
+
+       g_assert_not_reached ();
+       return -1;
+}
+
 /**
  * map_call_type:
  * @type: the type to map
@@ -677,7 +862,7 @@ mono_allocate_excvar (MonoFlowGraph *cfg)
  * Creates a tree to load the value at address @addr.
  */
 inline static MBTree *
-ctree_create_load (MonoFlowGraph *cfg, MonoType *type, MBTree *addr, MonoValueType *svt)
+ctree_create_load (MonoFlowGraph *cfg, MonoType *type, MBTree *addr, MonoValueType *svt, gboolean arg)
 {
        MonoMemPool *mp = cfg->mp;
        int ldind, size, align, vnum;
@@ -695,7 +880,11 @@ ctree_create_load (MonoFlowGraph *cfg, MonoType *type, MBTree *addr, MonoValueTy
                }
        }
 
-       ldind = map_ldind_type (type, svt);
+       if (arg)
+               ldind = map_ldarg_type (type, svt);
+       else
+               ldind = map_ldind_type (type, svt);
+
        t = mono_ctree_new (mp, ldind, addr, NULL);
 
        return t;
@@ -712,12 +901,16 @@ ctree_create_load (MonoFlowGraph *cfg, MonoType *type, MBTree *addr, MonoValueTy
  * Creates a tree to store the value @s at address @addr.
  */
 inline static MBTree *
-ctree_create_store (MonoFlowGraph *cfg, int addr_type, MBTree *s, MonoType *type, gpointer addr)
+ctree_create_store (MonoFlowGraph *cfg, int addr_type, MBTree *s, MonoType *type, gpointer addr, gboolean arg)
 {
        MonoMemPool *mp = cfg->mp;
-       int stind = map_stind_type (type);
+       int stind
        MBTree *t;
-
+       
+       if (arg)
+               stind = map_starg_type (type);
+       else
+               stind = map_stind_type (type);
 
        t = mono_ctree_new_leaf (mp, addr_type);
        t->data.p = addr;
@@ -907,23 +1100,14 @@ mono_cfg_free (MonoFlowGraph *cfg)
 }
 
 
-static MonoObject*
-get_named_exception (const char *name)
+static void
+runtime_object_init (MonoObject *obj)
 {
-       MonoClass *klass;
+       MonoClass *klass = obj->klass;
        MonoMethod *method = NULL;
-       MonoObject *o;
        void (*ctor) (gpointer this);
        int i;
 
-       klass = mono_class_from_name (mono_defaults.corlib, "System", name);
-
-       o = mono_object_new (klass);
-       g_assert (o != NULL);
-
-       if (!klass->inited)
-               mono_jit_init_class (klass);
-       
        for (i = 0; i < klass->method.count; ++i) {
                if (!strcmp (".ctor", klass->methods [i]->name) &&
                    klass->methods [i]->signature->param_count == 0) {
@@ -935,29 +1119,7 @@ get_named_exception (const char *name)
        g_assert (method);
 
        ctor = arch_compile_method (method);
-       ctor (o);
-
-       return o;
-}
-
-static MonoObject*
-get_exception_divide_by_zero ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = get_named_exception ("DivideByZeroException");
-       return ex;
-}
-
-static MonoObject*
-get_exception_execution_engine ()
-{
-       static MonoObject *ex = NULL;
-       if (ex)
-               return ex;
-       ex = get_named_exception ("ExecutionEngineException");
-       return ex;
+       ctor (obj);
 }
 
 static MonoBBlock *
@@ -1663,7 +1825,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        c = mono_class_get (image, token);
                        g_assert (c->valuetype);
 
-                       t1 = ctree_create_load (cfg, &c->byval_arg, *sp, &svt);
+                       t1 = ctree_create_load (cfg, &c->byval_arg, *sp, &svt, FALSE);
                        PUSH_TREE (t1, svt);
                        break;
                }
@@ -1698,8 +1860,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 
                                mono_metadata_typedef_from_field (image, token & 0xffffff));
 
-                       if (!klass->inited)
-                               mono_jit_init_class (klass);
+                       mono_class_init (klass);
 
                        field = mono_class_get_field (klass, token);
                        g_assert (field);
@@ -1713,7 +1874,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        } else {
                                t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_G);
                                t1->data.p = addr;
-                               t1 = ctree_create_load (cfg, field->type, t1, &svt);
+                               t1 = ctree_create_load (cfg, field->type, t1, &svt, FALSE);
                        }
 
                        PUSH_TREE (t1, svt);
@@ -1735,8 +1896,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 
                                mono_metadata_typedef_from_field (image, token & 0xffffff));
 
-                       if (!klass->inited)
-                               mono_jit_init_class (klass);
+                       mono_class_init (klass);
 
                        field = mono_class_get_field (klass, token);
                        g_assert (field);
@@ -1773,14 +1933,13 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 
                                mono_metadata_typedef_from_field (image, token & 0xffffff));
 
-                       if (!klass->inited)
-                               mono_jit_init_class (klass);
-
+                       mono_class_init (klass);
+       
                        field = mono_class_get_field (klass, token);
                        g_assert (field);
 
                        addr = MONO_CLASS_STATIC_FIELDS_BASE (klass) + field->offset;
-                       t1 = ctree_create_store (cfg, MB_TERM_ADDR_G, *sp, field->type, addr);
+                       t1 = ctree_create_store (cfg, MB_TERM_ADDR_G, *sp, field->type, addr, FALSE);
 
                        ADD_TREE (t1, cli_addr);
                        break;
@@ -1799,8 +1958,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 
                                mono_metadata_typedef_from_field (image, token & 0xffffff));
 
-                       if (!klass->inited)
-                               mono_jit_init_class (klass);
+                       mono_class_init (klass);
 
                        field = mono_class_get_field (klass, token);
                        g_assert (field);
@@ -1830,8 +1988,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
 
                        class = mono_class_get (image, token);
 
-                       if (!class->inited)
-                               mono_jit_init_class (class);
+                       mono_class_init (class);
 
                        esize = mono_class_instance_size (class);
                        if (class->valuetype)
@@ -1980,9 +2137,10 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        }
 
                        for (i = csig->param_count - 1; i >= 0; i--) {
-                               t1 = mono_ctree_new (mp, MB_TERM_ARG, arg_sp [i], NULL);        
+                               MonoType *type = cm->signature->params [i];
+                               t1 = mono_ctree_new (mp, map_arg_type (type, FALSE), arg_sp [i], NULL); 
                                ADD_TREE (t1, cli_addr);
-                               size = mono_type_size (cm->signature->params [i], &align);
+                               size = mono_type_size (type, &align);
                                args_size += (size + 3) & ~3;
                        }
 
@@ -2076,13 +2234,10 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        }
 
                        for (i = nargs - 1; i >= 0; i--) {
-                               if (pinvoke && cm->signature->params [i]->type == MONO_TYPE_STRING) {
-                                       t1 = mono_ctree_new (mp, MB_TERM_STRING_ARG, arg_sp [i], NULL);
-                               } else {
-                                       t1 = mono_ctree_new (mp, MB_TERM_ARG, arg_sp [i], NULL);
-                               }       
+                               MonoType *type = cm->signature->params [i];
+                               t1 = mono_ctree_new (mp, map_arg_type (type, pinvoke), arg_sp [i], NULL);
                                ADD_TREE (t1, cli_addr);
-                               size = mono_type_size (cm->signature->params [i], &align);
+                               size = mono_type_size (type, &align);
                                args_size += (size + 3) & ~3;
 
                                // fixme: align value type arguments  to 8 byte boundary on the stack
@@ -2141,8 +2296,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        } else {
 
                                if (virtual) {
-                                       if (!cm->klass->metadata_inited)
-                                               mono_class_metadata_init (cm->klass);
+                                       mono_class_init (cm->klass);
 
                                        if (cm->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
                                                t2 = mono_ctree_new_leaf (mp, MB_TERM_INTF_ADDR);
@@ -2185,13 +2339,36 @@ mono_analyze_stack (MonoFlowGraph *cfg)
 
                        break;
                }
-               case CEE_ISINST:
+               case CEE_ISINST: {
+                       MonoClass *c;
+                       guint32 token;
+                       ++ip;
+                       token = read32 (ip);
+                       --sp;
+
+                       c = mono_class_get (image, token);
+
+                       t1 = mono_ctree_new (mp, MB_TERM_ISINST, *sp, NULL);
+                       t1->data.klass = c;
+                       
+                       PUSH_TREE (t1, VAL_I32);
+
+                       ip += 4;
+                       break;
+               }
                case CEE_CASTCLASS: {
+                       MonoClass *c;
                        guint32 token;
                        ++ip;
                        token = read32 (ip);
+                       --sp;
+
+                       c = mono_class_get (image, token);
+
+                       t1 = mono_ctree_new (mp, MB_TERM_CASTCLASS, *sp, NULL);
+                       t1->data.klass = c;
                        
-                       /* fixme: do something */
+                       PUSH_TREE (t1, VAL_I32);
 
                        ip += 4;
                        break;
@@ -2273,7 +2450,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
 
                        t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
                        t1->data.i = LOCAL_POS (n);
-                       t1 = ctree_create_load (cfg, LOCAL_TYPE (n), t1, &svt);
+                       t1 = ctree_create_load (cfg, LOCAL_TYPE (n), t1, &svt, FALSE);
 
                        PUSH_TREE (t1, svt);
                        break;
@@ -2283,7 +2460,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        
                        t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
                        t1->data.i = LOCAL_POS (*ip);
-                       t1 = ctree_create_load (cfg, LOCAL_TYPE (*ip), t1, &svt);
+                       t1 = ctree_create_load (cfg, LOCAL_TYPE (*ip), t1, &svt, FALSE);
                        ++ip;
 
                        PUSH_TREE (t1, svt);
@@ -2307,7 +2484,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        --sp;
 
                        t1 = ctree_create_store (cfg, MB_TERM_ADDR_L, *sp, LOCAL_TYPE (n), 
-                                                (gpointer)LOCAL_POS (n));
+                                                (gpointer)LOCAL_POS (n), FALSE);
 
                        ADD_TREE (t1, cli_addr);                        
                        break;
@@ -2317,7 +2494,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        --sp;
 
                        t1 = ctree_create_store (cfg, MB_TERM_ADDR_L, *sp, LOCAL_TYPE (*ip), 
-                                                (gpointer)LOCAL_POS (*ip));
+                                                (gpointer)LOCAL_POS (*ip), FALSE);
                        ++ip;
 
                        ADD_TREE (t1, cli_addr);                        
@@ -2570,7 +2747,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
 
                        t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
                        t1->data.i = ARG_POS (n);
-                       t1 = ctree_create_load (cfg, ARG_TYPE (n), t1, &svt);
+                       t1 = ctree_create_load (cfg, ARG_TYPE (n), t1, &svt, TRUE);
                        PUSH_TREE (t1, svt);
                        break;
                }
@@ -2579,7 +2756,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
 
                        t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
                        t1->data.i = ARG_POS (*ip);
-                       t1 = ctree_create_load (cfg, ARG_TYPE (*ip), t1, &svt);
+                       t1 = ctree_create_load (cfg, ARG_TYPE (*ip), t1, &svt, TRUE);
                        PUSH_TREE (t1, svt);
                        ++ip;
                        break;
@@ -2598,7 +2775,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        --sp;
 
                        t1 = ctree_create_store (cfg, MB_TERM_ADDR_L, *sp, ARG_TYPE (*ip), 
-                                                (gpointer)ARG_POS (*ip));
+                                                (gpointer)ARG_POS (*ip), TRUE);
                        ++ip;
 
                        ADD_TREE (t1, cli_addr);                        
@@ -2769,7 +2946,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
 
                                t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
                                t1->data.i = ARG_POS (n);
-                               t1 = ctree_create_load (cfg, ARG_TYPE (n), t1, &svt);
+                               t1 = ctree_create_load (cfg, ARG_TYPE (n), t1, &svt, TRUE);
                                PUSH_TREE (t1, svt);
                                break;
                        }
@@ -3039,6 +3216,9 @@ main (int argc, char *argv [])
 
        mono_jit_info_table = mono_jit_info_table_new ();
 
+       mono_install_runtime_class_init (runtime_class_init);
+       mono_install_runtime_object_init (runtime_object_init);
+
        /*
         * This doesn't seem to work... :-(
        if (mono_debug_handle)
index 75c3787c2aef973ee00fd6ec26f9b8bb466b7f57..0690908d4f8f9ab74a4467dc2c2453f37aecb71b 100644 (file)
@@ -143,9 +143,6 @@ mono_analyze_stack         (MonoFlowGraph *cfg);
 void
 mono_disassemble_code      (guint8 *code, int size);
 
-void
-mono_jit_init_class        (MonoClass *klass);
-
 gpointer 
 arch_compile_method        (MonoMethod *method);
 
@@ -163,5 +160,4 @@ mono_print_ctree           (MBTree *tree);
 void
 mono_print_forest          (GPtrArray *forest);
 
-
 #endif
index 64f6227052d65295f9c116233032765697f093d9..f3da2dc4d213d35371ba6586a67d55e6842a8cb2 100644 (file)
@@ -17,6 +17,7 @@
 #include <mono/metadata/metadata.h>
 #include <mono/metadata/loader.h>
 #include <mono/metadata/object.h>
+#include <mono/metadata/tabledefs.h>
 #include <mono/arch/x86/x86-codegen.h>
 
 #include "regset.h"
@@ -59,6 +60,7 @@ struct _MBTree {
 
        gint8     reg1;
        gint8     reg2;
+       gint8     reg3;
        
        MonoValueType svt;
 
@@ -69,6 +71,7 @@ struct _MBTree {
                MonoBBlock *bb;
                MonoMethod *m;
                MethodCallInfo *ci;
+               MonoClass *klass;
                X86AddressInfo ainfo;
        } data;
 };
@@ -79,7 +82,11 @@ gint64  mono_llrem     (gint64 a, gint64 b);
 guint64 mono_lldiv_un  (guint64 a, guint64 b);
 guint64 mono_llrem_un  (guint64 a, guint64 b);
 
-gpointer get_throw_exception (void);
+gpointer 
+get_throw_exception    (void);
+
+gpointer
+get_mono_object_isinst (void);
 
 #define MB_OPT_LEVEL 1
 
@@ -144,14 +151,14 @@ x86_pop_reg (s->code, X86_EAX);
 %term LDIND_I1 LDIND_U1 LDIND_I2 LDIND_U2 LDIND_I4 LDIND_I8 LDIND_R4 LDIND_R8
 %term LDIND_U4 LDIND_OBJ
 %term STIND_I1 STIND_I2 STIND_I4 STIND_I8 STIND_R4 STIND_R8 STIND_OBJ
-%term ADDR_L ADDR_G ARG STRING_ARG CALL_I4 CALL_I8 CALL_R8 CALL_VOID
+%term ADDR_L ADDR_G ARG_I4 ARG_I8 ARG_R4 ARG_R8 ARG_OBJ ARG_STRING CALL_I4 CALL_I8 CALL_R8 CALL_VOID
 %term BREAK SWITCH BR RET RETV ENDFINALLY
 %term ADD SUB MUL DIV DIV_UN REM REM_UN AND OR XOR SHL SHR SHR_UN NEG NOT
 %term BLT BLT_UN BEQ BNE_UN BRTRUE BRFALSE BGE BGE_UN BLE BLE_UN BGT BGT_UN 
 %term CEQ CLT
 %term CONV_I4 CONV_I1 CONV_I2 CONV_I8 CONV_U8 CONV_R4 CONV_R8
-%term INTF_ADDR VFUNC_ADDR NOP NEWARR NEWOBJ CPOBJ POP INITOBJ VTYPE 
-%term EXCEPTION THROW RETHROW HANDLER
+%term INTF_ADDR VFUNC_ADDR NOP NEWARR NEWOBJ CPOBJ POP INITOBJ VTYPE ISINST CASTCLASS
+%term EXCEPTION THROW RETHROW HANDLER 
 %term LDLEN
 
 #
@@ -281,7 +288,6 @@ stmt: RETHROW {
 stmt: HANDLER {
        gint32 addr = tree->data.bb->addr - tree->addr - 5;
        tree->is_jump = 1;    
-       
        x86_call_imm (s->code, addr); 
 }
 
@@ -776,6 +782,117 @@ reg: NEWOBJ {
        }
 }
 
+reg: CASTCLASS (reg) {
+       guint8 *start = s->code, *l1, *l2, *l3, *l4, *le;
+       int i;
+
+       tree->is_jump = TRUE;
+       l1 = l2 = l3 = l4 = le = NULL;
+
+       for (i = 0; i < 2; i++) {
+               s->code = start;
+
+               if (tree->reg1 != X86_EAX)
+                       x86_push_reg (s->code, X86_EAX);
+
+               x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, 0);
+               x86_branch8 (s->code, X86_CC_EQ, le - l2, FALSE);
+               l2 = s->code;
+               x86_push_reg (s->code, X86_ECX);
+               x86_push_reg (s->code, X86_EDX);
+
+               x86_push_imm (s->code, tree->data.klass);
+               x86_push_reg (s->code, tree->left->reg1);
+               x86_call_code (s->code, mono_object_isinst);
+               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 8);
+               x86_pop_reg (s->code, X86_EDX);
+               x86_pop_reg (s->code, X86_ECX);
+
+               x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0);
+               x86_branch8 (s->code, X86_CC_NE, le - l3, FALSE);
+               l3 = s->code;
+
+               x86_mov_reg_imm (s->code, X86_ECX, get_exception_invalid_cast ());
+               x86_call_code (s->code, get_throw_exception ());
+
+               le = s->code;
+
+       }
+}
+
+reg: ISINST (reg) {
+       if (tree->reg1 != X86_EAX)
+               x86_push_reg (s->code, X86_EAX);
+       x86_push_reg (s->code, X86_ECX);
+       x86_push_reg (s->code, X86_EDX);
+
+       x86_push_imm (s->code, tree->data.klass);
+       x86_push_reg (s->code, tree->left->reg1);
+       x86_call_code (s->code, mono_object_isinst);
+       x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 8);
+
+       x86_pop_reg (s->code, X86_EDX);
+       x86_pop_reg (s->code, X86_ECX);
+       if (tree->reg1 != X86_EAX) {
+               x86_mov_reg_reg (s->code, tree->reg1, X86_EAX, 4);
+               x86_pop_reg (s->code, X86_EAX);
+       }
+
+}
+
+#reg: ISINST (reg) {
+#      guint8 *start = s->code, *l1, *l2, *l3, *l4, *le;
+#      MonoClass *k = tree->data.klass;
+#      int treg = tree->reg1;
+#      gint32 i;
+#
+#      tree->is_jump = TRUE;
+#      l1 = l2 = l3 = l4 = le = NULL;
+#
+#      for (i = 0; i < 2; i++) {
+#              s->code = start;
+#
+#              x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, 0);
+#              x86_branch8 (s->code, X86_CC_EQ, le - l1, FALSE);
+#              l1 = s->code;
+#      
+#              x86_push_reg (s->code, tree->left->reg1);
+#
+#              if (k->flags & TYPE_ATTRIBUTE_INTERFACE) {
+#                      x86_mov_reg_membase (s->code, treg, treg, 0, 4); // treg = o->klass
+#                      x86_mov_reg_membase (s->code, treg, treg, G_STRUCT_OFFSET (MonoClass, max_interface_id), 4);
+#                      x86_alu_reg_imm (s->code, X86_CMP, treg, k->interface_id);
+#                      x86_branch8 (s->code, X86_CC_GE, l3 - l2, FALSE);
+#                      l2 = s->code;
+#                      x86_pop_reg (s->code, treg);
+#                      x86_alu_reg_reg (s->code, X86_XOR, treg, treg);
+#                      x86_jump8 (s->code, le - l3);
+#                      l3 = s->code;
+#                      x86_mov_reg_membase (s->code, treg, X86_ESP, 0, 4); // treg = o
+#                      x86_mov_reg_membase (s->code, treg, treg, 0, 4); // treg = o->klass
+#                      x86_mov_reg_membase (s->code, treg, treg, G_STRUCT_OFFSET (MonoClass, interface_offsets), 4);
+#                      x86_mov_reg_membase (s->code, treg, treg, (k->interface_id << 2), 4);
+#                      x86_alu_reg_imm (s->code, X86_CMP, treg, 0);
+#                      x86_pop_reg (s->code, treg);
+#                      x86_branch8 (s->code, X86_CC_NE, le - l4, FALSE);
+#                      l4 = s->code;
+#                      x86_alu_reg_reg (s->code, X86_XOR, treg, treg);
+#              } else {
+#                      x86_mov_reg_membase (s->code, treg, treg, 0, 4); // treg = o->klass
+#                      x86_mov_reg_membase (s->code, treg, treg, G_STRUCT_OFFSET (MonoClass, baseval), 4);
+#                      x86_alu_reg_imm (s->code, X86_SUB, treg, k->baseval);
+#                      x86_alu_reg_imm (s->code, X86_CMP, treg, k->diffval);
+#                      x86_pop_reg (s->code, treg);
+#                      x86_branch8 (s->code, X86_CC_LE, le - l2, FALSE);
+#                      l2 = s->code;
+#                      x86_alu_reg_reg (s->code, X86_XOR, treg, treg);
+#              }
+#              
+#              le = s->code;
+#              //x86_breakpoint (s->code);
+#      }
+#}
+
 stmt: INITOBJ (reg) {
        int i, j;
 
@@ -1101,12 +1218,12 @@ stmt: RET {
        } 
 }
 
-stmt: ARG (reg) {
+stmt: ARG_I4 (reg) {
        x86_push_reg (s->code, tree->left->reg1);
 }
 
 # fixme: we must free the allocated strings somewhere
-stmt: STRING_ARG (reg) {
+stmt: ARG_STRING (reg) {
        x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 4);
        x86_push_reg (s->code, X86_EAX);
        x86_push_reg (s->code, X86_ECX);
@@ -1123,11 +1240,11 @@ stmt: STRING_ARG (reg) {
        x86_pop_reg (s->code, X86_EAX);
 }
 
-stmt: ARG (ADDR_G) {
+stmt: ARG_I4 (ADDR_G) {
        x86_push_imm (s->code, tree->left->data.p);
 }
 
-stmt: ARG (CONST_I4) "MB_USE_OPT1(0)" {
+stmt: ARG_I4 (CONST_I4) "MB_USE_OPT1(0)" {
        x86_push_imm (s->code, tree->left->data.i);
 }
 
@@ -1660,7 +1777,7 @@ stmt: RETV (lreg) {
 }
 
 
-stmt: ARG (lreg) {
+stmt: ARG_I8 (lreg) {
        x86_push_reg (s->code, tree->left->reg2);
        x86_push_reg (s->code, tree->left->reg1);
 }
@@ -1863,6 +1980,12 @@ stmt: BLE_UN (lreg, lreg) {
 #      x86_fist_pop_membase (s->code, X86_EBP, tree->data.i, FALSE);
 #} 
 
+reg: CONV_I4 (freg) {
+       x86_push_reg (s->code, X86_EAX); // SP = SP - 4
+       x86_fist_pop_membase (s->code, X86_ESP, 0, FALSE);
+       x86_pop_reg (s->code, tree->reg1);
+}
+
 freg: CONV_R8 (freg) {
        /* nothing to do */
 }
@@ -1913,12 +2036,12 @@ freg: CONST_R8 {
                x86_fld (s->code, tree->data.p, TRUE);
 }
 
-freg: LDIND_R4 (locaddr) {
-       x86_fld_membase (s->code, X86_EBP, tree->left->data.i, FALSE);
+freg: LDIND_R4 (reg) {
+       x86_fld_membase (s->code, tree->left->reg1, 0, FALSE);
 }
 
-freg: LDIND_R8 (locaddr) {
-       x86_fld_membase (s->code, X86_EBP, tree->left->data.i, TRUE);
+freg: LDIND_R8 (reg) {
+       x86_fld_membase (s->code, tree->left->reg1, 0, TRUE);
 }
 
 freg: LDIND_R8 (reg) {
@@ -1953,19 +2076,20 @@ freg: NEG (freg) {
 
 stmt: POP (freg)
 
-stmt: STIND_R4 (locaddr, freg) {
-       x86_fst_membase (s->code, X86_EBP, tree->left->data.i, FALSE, TRUE);
-}
-
-stmt: STIND_R8 (locaddr, freg) {
-       x86_fst_membase (s->code, X86_EBP, tree->left->data.i, TRUE, TRUE);
+stmt: STIND_R4 (reg, freg) {
+       x86_fst_membase (s->code, tree->left->reg1, 0, FALSE, TRUE);
 }
 
 stmt: STIND_R8 (reg, freg) {
        x86_fst_membase (s->code, tree->left->reg1, 0, TRUE, TRUE);
 }
 
-stmt: ARG (freg) {
+stmt: ARG_R4 (freg) {
+       x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 4);
+       x86_fst_membase (s->code, X86_ESP, 0, FALSE, TRUE);
+}
+
+stmt: ARG_R8 (freg) {
        x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 8);
        x86_fst_membase (s->code, X86_ESP, 0, TRUE, TRUE);
 }
@@ -2191,7 +2315,7 @@ stmt: STIND_OBJ (reg, vtype) {
        x86_pop_reg (s->code, X86_EAX);
 }
 
-stmt: ARG (vtype) {
+stmt: ARG_OBJ (vtype) {
        int treg = X86_EAX;
        int offset = g_array_index (s->varinfo, MonoVarInfo, tree->left->data.i).offset;
        int size = g_array_index (s->varinfo, MonoVarInfo, tree->left->data.i).size;
@@ -2286,6 +2410,7 @@ mono_ctree_new (MonoMemPool *mp, int op, MBTree *left, MBTree *right)
        t->right = right;
        t->reg1 = -1;
        t->reg2 = -1;
+       t->reg3 = -1;
        t->svt = VAL_UNKNOWN;
        t->cli_addr = -1;
        return t;
@@ -2347,7 +2472,6 @@ get_throw_exception (void)
        return start;
 }
 
-
 #ifdef DEBUG
 void *
 MEMCOPY (void *dest, const void *src, size_t n)
@@ -2363,3 +2487,4 @@ MEMCOPY (void *dest, const void *src, size_t n)
        return memcpy (dest, src, n);
 }
 #endif
+
index afe68e75291481053ac74200112a7527a78e644b..e1fd68c3fefba4acf7e4b9e9c988388d50a22d92 100644 (file)
@@ -1,3 +1,11 @@
+2001-11-30  Dietmar Maurer  <dietmar@ximian.com>
+
+       * class.c (mono_install_runtime_class_init): impl.
+       (mono_class_init): renamed mono_class_metadata_init to
+       mono_class_init, also removed the metadata_inited flag
+
+       * object.c (mono_object_isinst): use faster algorithm
+
 2001-11-30  Radek Doulik  <rodo@ximian.com>
 
        * mono-endian.h: reverted last change
index fb0c4263e37e2c461cf6686c60c30432ad119377..60d674ff2c79a7f6b2f3bce929256f85f5bf2e14 100644 (file)
@@ -34,13 +34,27 @@ default_trampoline (MonoMethod *method)
        return method;
 }
 
+static void
+default_runtime_class_init (MonoClass *klass)
+{
+       return;
+}
+
 static MonoTrampoline arch_create_jit_trampoline = default_trampoline;
+static MonoRuntimeClassInit mono_runtime_class_init = default_runtime_class_init;
 
 void
-mono_install_trampoline (MonoTrampoline func) {
+mono_install_trampoline (MonoTrampoline func) 
+{
        arch_create_jit_trampoline = func? func: default_trampoline;
 }
 
+void
+mono_install_runtime_class_init (MonoRuntimeClassInit func)
+{
+       mono_runtime_class_init = func? func: default_runtime_class_init;
+}
+
 static MonoClass *
 mono_class_create_from_typeref (MonoImage *image, guint32 type_token)
 {
@@ -183,7 +197,7 @@ class_compute_field_layout (MonoClass *class)
 }
 
 void
-mono_class_metadata_init (MonoClass *class)
+mono_class_init (MonoClass *class)
 {
        MonoClass *k, *ic;
        MonoMethod **tmp_vtable, **vtable = (MonoMethod **)class->vtable;
@@ -191,13 +205,13 @@ mono_class_metadata_init (MonoClass *class)
 
        g_assert (class);
 
-       if (class->metadata_inited)
+       if (class->inited)
                return;
-       class->metadata_inited = 1;
+       class->inited = 1;
 
        if (class->parent) {
-               if (!class->parent->metadata_inited)
-                       mono_class_metadata_init (class->parent);
+               if (!class->parent->inited)
+                       mono_class_init (class->parent);
                class->instance_size += class->parent->instance_size;
                class->class_size += class->parent->class_size;
                class->min_align = class->parent->min_align;
@@ -235,8 +249,8 @@ mono_class_metadata_init (MonoClass *class)
                for (i = 0; i < k->interface_count; i++) {
                        ic = k->interfaces [i];
 
-                       if (!ic->metadata_inited)
-                               mono_class_metadata_init (ic);
+                       if (!ic->inited)
+                               mono_class_init (ic);
 
                        if (max_iid < ic->interface_id)
                                max_iid = ic->interface_id;
@@ -423,6 +437,8 @@ mono_class_metadata_init (MonoClass *class)
                        vtable [cm->slot] = arch_create_jit_trampoline (cm);
        }
 
+       mono_runtime_class_init (class);
+
        /*
        for (i = 0; i < class->vtable_size; ++i) {
                MonoMethod *cm;
@@ -772,8 +788,8 @@ mono_array_class_get (MonoClass *eclass, guint32 rank)
        if (!parent)
                parent = mono_defaults.array_class;
 
-       if (!parent->metadata_inited)
-               mono_class_metadata_init (parent);
+       if (!parent->inited)
+               mono_class_init (parent);
 
        image = eclass->image;
 
@@ -824,8 +840,8 @@ gint32
 mono_class_instance_size (MonoClass *klass)
 {
        
-       if (!klass->metadata_inited)
-               mono_class_metadata_init (klass);
+       if (!klass->inited)
+               mono_class_init (klass);
 
        return klass->instance_size;
 }
@@ -871,8 +887,8 @@ gint32
 mono_class_data_size (MonoClass *klass)
 {
        
-       if (!klass->metadata_inited)
-               mono_class_metadata_init (klass);
+       if (!klass->inited)
+               mono_class_init (klass);
 
        return klass->class_size;
 }
@@ -1040,7 +1056,7 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class)
                MonoClass *class;
                guint32 type = mono_metadata_typedef_from_field (image, mono_metadata_token_index (token));
                class = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type);
-               mono_class_metadata_init (class);
+               mono_class_init (class);
                if (handle_class)
                                *handle_class = mono_class_from_name (mono_defaults.corlib, "System", "RuntimeFieldHandle");
                return mono_class_get_field (class, token);
index ed52989ca4fb5d3352e22a8cf1f207407ab63808..386c82d16d53c5935c4f658889b7b72fc01e9f61 100644 (file)
@@ -23,7 +23,6 @@ struct _MonoClass {
 
        guint dummy           : 1; /* temorary hack */
        guint inited          : 1;
-       guint metadata_inited : 1;
        guint valuetype       : 1; /* derives from System.ValueType */
        guint enumtype        : 1; /* derives from System.Enum */
        guint min_align       : 4;
@@ -84,11 +83,14 @@ struct _MonoClass {
        gpointer vtable [0];
 };
 
+typedef gpointer (*MonoTrampoline)       (MonoMethod *method);
+typedef void     (*MonoRuntimeClassInit) (MonoClass *klass);
+
 MonoClass *
 mono_class_get             (MonoImage *image, guint32 type_token);
 
 void
-mono_class_metadata_init   (MonoClass *klass);
+mono_class_init            (MonoClass *klass);
 
 MonoClass *
 mono_class_from_name       (MonoImage *image, const char* name_space, const char *name);
@@ -123,9 +125,10 @@ mono_class_from_mono_type  (MonoType *type);
 gpointer
 mono_ldtoken               (MonoImage *image, guint32 token, MonoClass **retclass);
 
-typedef gpointer (*MonoTrampoline) (MonoMethod *method);
-
 void
 mono_install_trampoline (MonoTrampoline func);
 
+void
+mono_install_runtime_class_init (MonoRuntimeClassInit func);
+
 #endif /* _MONO_CLI_CLASS_H_ */
index a69af08508d58d4d63ea3c45cdf428615483e9dd..1d740908315c1542f38a27d53737b28d1c678e40 100644 (file)
 #include <mono/metadata/exception.h>
 #include <mono/metadata/class.h>
 
-static MonoExceptionClassInitFunc ex_init_class = NULL;
-static MonoExceptionObjectInitFunc ex_init_obj = NULL;
-
-void
-mono_exception_install_handlers(MonoExceptionClassInitFunc class_init,
-                               MonoExceptionObjectInitFunc obj_init)
-{
-       ex_init_class = class_init;
-       ex_init_obj = obj_init;
-}
-
 MonoObject*
 mono_exception_from_name (MonoImage *image, const char *name_space,
                          const char *name)
@@ -34,14 +23,119 @@ mono_exception_from_name (MonoImage *image, const char *name_space,
 
        o = mono_object_new (klass);
        g_assert (o != NULL);
-
-       if(!klass->inited && ex_init_class) {
-               ex_init_class(klass);
-       }
        
-       if(ex_init_obj) {
-               ex_init_obj(o, klass);
-       }
+       mono_runtime_object_init (o);
 
        return o;
 }
+
+MonoObject*
+get_exception_divide_by_zero ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "DivideByZeroException");
+       return ex;
+}
+
+MonoObject*
+get_exception_security ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "SecurityException");
+       return ex;
+}
+
+MonoObject*
+get_exception_arithmetic ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "ArithmeticException");
+       return ex;
+}
+
+MonoObject*
+get_exception_overflow ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "OverflowException");
+       return ex;
+}
+
+MonoObject*
+get_exception_null_reference ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "NullReferenceException");
+       return ex;
+}
+
+MonoObject*
+get_exception_execution_engine ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "ExecutionEngineException");
+       return ex;
+}
+
+MonoObject*
+get_exception_invalid_cast ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "InvalidCastException");
+       return ex;
+}
+
+MonoObject*
+get_exception_index_out_of_range ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "IndexOutOfRangeException");
+       return ex;
+}
+
+MonoObject*
+get_exception_array_type_mismatch ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "ArrayTypeMismatchException");
+       return ex;
+}
+
+MonoObject*
+get_exception_missing_method ()
+{
+       static MonoObject *ex = NULL;
+       if (ex)
+               return ex;
+       ex = mono_exception_from_name (mono_defaults.corlib, "System",
+                                      "MissingMethodException");
+       return ex;
+}
+
index 1e8c1a4148272d7e3ba327c2a095bc7a9768188d..06cf529f89d1d00e6283ffed67e6ddd5ec8fd968 100644 (file)
@@ -251,8 +251,8 @@ ves_icall_System_Reflection_Assembly_GetType (MonoReflectionAssembly *assembly,
        g_free (namespace);
        if (!klass)
                return NULL;
-       if (!klass->metadata_inited)
-               mono_class_metadata_init (klass);
+       if (!klass->inited)
+               mono_class_init (klass);
 
        return my_mono_new_mono_type (&klass->byval_arg);
 }
index 6d1355e36eefe14416ab460c86b013fdc72fb1fb..bd37e5a5a0a0f9754831adff196fe59e4f1ca716 100644 (file)
@@ -265,7 +265,7 @@ mono_field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass
                        mimage = image->references [scopeindex-1]->image;
 
                        klass = mono_class_from_name (mimage, nspace, name);
-                       mono_class_metadata_init (klass);
+                       mono_class_init (klass);
 
                        /* mostly dumb search for now */
                        for (i = 0; i < klass->field.count; ++i) {
@@ -339,7 +339,7 @@ method_from_memberref (MonoImage *image, guint32 index)
                        mimage = image->references [scopeindex-1]->image;
 
                        klass = mono_class_from_name (mimage, nspace, name);
-                       mono_class_metadata_init (klass);
+                       mono_class_init (klass);
 
                        /* 
                         * FIXME: this is a workaround for the different signatures
@@ -589,7 +589,7 @@ mono_method_get_param_names (MonoMethod *method, const char **names)
        for (i = 0; i < method->signature->param_count; ++i)
                names [i] = "";
 
-       mono_class_metadata_init (klass);
+       mono_class_init (klass);
        if (!klass->methods)
                return;
 
index 87040095c15a5f8448b1306ae71721e9ded538dc..111262076d21d03d93390e05d7546bd794fed1d6 100644 (file)
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <mono/metadata/tabledefs.h>
 #include <mono/metadata/loader.h>
 #include <mono/metadata/object.h>
 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
 #endif
 #endif
 
+static void
+default_runtime_object_init (MonoObject *o)
+{
+       return;
+}
+
+MonoRuntimeObjectInit mono_runtime_object_init = default_runtime_object_init;
+
+void
+mono_install_runtime_object_init (MonoRuntimeObjectInit func)
+{
+       mono_runtime_object_init = func? func: default_runtime_object_init;
+}
+
 /**
  * mono_object_allocate:
  * @size: number of bytes to allocate
@@ -64,8 +79,8 @@ mono_object_new (MonoClass *klass)
 {
        MonoObject *o;
 
-       if (!klass->metadata_inited)
-               mono_class_metadata_init (klass);
+       if (!klass->inited)
+               mono_class_init (klass);
 
        o = mono_object_allocate (klass->instance_size);
        o->klass = klass;
@@ -122,8 +137,8 @@ mono_array_new_full (MonoClass *array_class, guint32 *lengths, guint32 *lower_bo
        MonoArrayBounds *bounds;
        int i;
 
-       if (!array_class->metadata_inited)
-               mono_class_metadata_init (array_class);
+       if (!array_class->inited)
+               mono_class_init (array_class);
        byte_len = mono_array_element_size (array_class);
 
        bounds = g_malloc0 (sizeof (MonoArrayBounds) * array_class->rank);
@@ -255,19 +270,31 @@ mono_value_box (MonoClass *class, gpointer value)
  * @obj: an object
  * @klass: a pointer to a class 
  *
- * Returns: #TRUE if @obj is derived from @klass
+ * Returns: @obj if @obj is derived from @klass
  */
-gboolean
+MonoObject *
 mono_object_isinst (MonoObject *obj, MonoClass *klass)
 {
-       MonoClass *oklass = obj->klass;
+       MonoClass *oklass;
+
+       if (!obj)
+               return NULL;
 
-       while (oklass) {
-               if (oklass == klass)
-                       return TRUE;
-               oklass = oklass->parent;
+       oklass = obj->klass;
+
+       if (!klass->inited)
+               mono_class_init (klass);
+
+       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+               if ((klass->interface_id <= oklass->max_interface_id) &&
+                   oklass->interface_offsets [klass->interface_id])
+                       return obj;
+       } else {
+               if ((oklass->baseval - klass->baseval) <= klass->diffval)
+                       return obj;
        }
-       return FALSE;
+
+       return NULL;
 }
 
 static GHashTable *ldstr_table = NULL;
index ca7f65fb55e03ab3fe9ffbc8c1e8d3a271c41f21..25a463722748eb527262aaaa63aab2dead08a3dc 100644 (file)
@@ -46,6 +46,10 @@ typedef struct {
        gpointer    method_ptr;
 } MonoDelegate;
 
+typedef void  (*MonoRuntimeObjectInit) (MonoObject *o);
+
+extern MonoRuntimeObjectInit mono_runtime_object_init;
+
 #define mono_array_length(array) ((array)->bounds->length)
 #define mono_array_addr(array,type,index) ( ((char*)(array)->vector) + sizeof (type) * (index) )
 #define mono_array_addr_with_size(array,size,index) ( ((char*)(array)->vector) + (size) * (index) )
@@ -97,7 +101,7 @@ mono_value_box              (MonoClass *klass, gpointer val);
 MonoObject *
 mono_object_clone           (MonoObject *obj);
 
-gboolean
+MonoObject *
 mono_object_isinst          (MonoObject *obj, MonoClass *klass);
 
 typedef void (*MonoExceptionFunc) (MonoException *ex);
@@ -108,5 +112,38 @@ mono_install_handler        (MonoExceptionFunc func);
 void
 mono_raise_exception        (MonoException *ex);
 
+void
+mono_install_runtime_object_init (MonoRuntimeObjectInit func);
+
+MonoObject*
+get_exception_divide_by_zero      (void);
+
+MonoObject*
+get_exception_security            (void);
+
+MonoObject*
+get_exception_arithmetic          (void);
+
+MonoObject*
+get_exception_overflow            (void);
+
+MonoObject*
+get_exception_null_reference      (void);
+
+MonoObject*
+get_exception_execution_engine    (void);
+
+MonoObject*
+get_exception_invalid_cast        (void);
+
+MonoObject*
+get_exception_index_out_of_range  (void);
+
+MonoObject*
+get_exception_array_type_mismatch (void);
+
+MonoObject*
+get_exception_missing_method      (void);
+
 #endif