bug fixes, code cleanup
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Thu, 29 Nov 2001 10:46:40 +0000 (10:46 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Thu, 29 Nov 2001 10:46:40 +0000 (10:46 -0000)
svn path=/trunk/mono/; revision=1466

mono/jit/ChangeLog
mono/jit/TODO
mono/jit/emit-x86.c
mono/jit/jit.c
mono/jit/jit.h
mono/jit/x86.brg
mono/metadata/loader.c
mono/metadata/loader.h
mono/metadata/object.h

index 9fd99ed70d39569328cef96d1a030d01869f9c6d..ef8da3d937453d818bad0b04bb7adc722431356d 100644 (file)
@@ -1,3 +1,6 @@
+2001-11-29  Dietmar Maurer  <dietmar@ximian.com>
+
+       * jit.c (mono_analyze_stack): bug fix in DUP
 
 Thu Nov 29 12:32:01 CET 2001 Paolo Molaro <lupus@ximian.com>
 
index ffd176770d54e84d21287960408a4a9fdcacc6bc..322d4b42877b8108e71218710eba40173a565b69 100644 (file)
@@ -1,3 +1,5 @@
+* 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
   the floating branch instruction - some of them seems to be wrong, we need to
   write better tests for that.
index a310d3fa68217b116ebe839adbfcf3f6643709b7..35e903f38092f9019cffc64f29352efb1a40ad7f 100644 (file)
@@ -598,11 +598,6 @@ mono_emit_cfg (MonoFlowGraph *cfg)
                for (j = 0; j < top; j++) {
                        MBTree *t1 = (MBTree *) g_ptr_array_index (forest, j);
                        tree_emit (1, cfg, t1);
-
-                       /* debug infos 
-                       if (t1->cli_addr >= 0)
-                               printf ("CLIADDR: %IL%05x %p\n", t1->cli_addr, cfg->start + t1->addr);
-                       */
                }
        }
                
@@ -878,5 +873,191 @@ arch_compile_method (MonoMethod *method)
        return method->addr;
 }
 
+/*
+ * arch_get_restore_context:
+ *
+ * Returns a pointer to a method which restores a previously saved sigcontext.
+ */
+static gpointer
+arch_get_restore_context ()
+{
+       static guint8 *start = NULL;
+       guint8 *code;
+
+       if (start)
+               return start;
+
+       /* restore_contect (struct sigcontext *ctx) */
+       /* we do not restore X86_EAX, X86_EDX */
+
+       start = code = malloc (1024);
+       
+       /* load ctx */
+       x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4);
+
+       /* get return address, stored in EDX */
+       x86_mov_reg_membase (code, X86_EDX, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, eip), 4);
+
+       /* restore EBX */
+       x86_mov_reg_membase (code, X86_EBX, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, ebx), 4);
+       /* restore EDI */
+       x86_mov_reg_membase (code, X86_EDI, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, edi), 4);
+       /* restore ESI */
+       x86_mov_reg_membase (code, X86_ESI, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, esi), 4);
+       /* restore ESP */
+       x86_mov_reg_membase (code, X86_ESP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, esp), 4);
+       /* restore EBP */
+       x86_mov_reg_membase (code, X86_EBP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, ebp), 4);
+       /* restore ECX. the exception object is passed here to the catch handler */
+       x86_mov_reg_membase (code, X86_ECX, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, ecx), 4);
+
+       /* jump to the saved IP */
+       x86_jump_reg (code, X86_EDX);
+
+       return start;
+}
+
+/*
+ * arch_get_call_finally:
+ *
+ * Returns a pointer to a method which calls a finally handler.
+ */
+static gpointer
+arch_get_call_finally ()
+{
+       static guint8 *start = NULL;
+       guint8 *code;
+
+       if (start)
+               return start;
+
+       /* call_finally (struct sigcontext *ctx, unsigned long eip) */
+       start = code = malloc (1024);
+
+       x86_push_reg (code, X86_EBP);
+       x86_mov_reg_reg (code, X86_EBP, X86_ESP, 4);
+       x86_push_reg (code, X86_EBX);
+       x86_push_reg (code, X86_EDI);
+       x86_push_reg (code, X86_ESI);
+
+       /* load ctx */
+       x86_mov_reg_membase (code, X86_EAX, X86_EBP, 8, 4);
+       /* load eip */
+       x86_mov_reg_membase (code, X86_ECX, X86_EBP, 12, 4);
+       /* save EBP */
+       x86_push_reg (code, X86_EBP);
+       /* set new EBP */
+       x86_mov_reg_membase (code, X86_EBP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, ebp), 4);
+       /* call the handler */
+       x86_call_reg (code, X86_ECX);
+       /* restore EBP */
+       x86_pop_reg (code, X86_EBP);
+       /* restore saved regs */
+       x86_pop_reg (code, X86_ESI);
+       x86_pop_reg (code, X86_EDI);
+       x86_pop_reg (code, X86_EBX);
+       x86_leave (code);
+       x86_ret (code);
+
+       return start;
+}
+
+/**
+ * arch_handle_exception:
+ * @ctx: saved processor state
+ * @obj:
+ */
+void
+arch_handle_exception (struct sigcontext *ctx, gpointer obj)
+{
+       MonoJitInfo *ji;
+       gpointer ip = (gpointer)ctx->eip;
+       static void (*restore_context) (struct sigcontext *);
+       static void (*call_finally) (struct sigcontext *, unsigned long);
+
+       ji = mono_jit_info_table_find (mono_jit_info_table, ip);
+
+       if (!restore_context)
+               restore_context = arch_get_restore_context ();
+       
+       if (!call_finally)
+               call_finally = arch_get_call_finally ();
+
+       if (ji) { /* we are inside managed code */
+               MonoMethod *m = ji->method;
+               unsigned next_bp, next_ip;
+               int offset = 2;
+
+               if (ji->num_clauses) {
+                       int i;
+
+                       g_assert (ji->clauses);
+                       
+                       for (i = 0; i < ji->num_clauses; i++) {
+                               MonoJitExceptionInfo *ei = &ji->clauses [i];
+
+                               if (ei->try_start <= ip && ip < (ei->try_end)) { 
+                               
+                                       /* catch block */
+                                       if (ei->flags == 0 && mono_object_isinst (obj, 
+                                               mono_class_get (m->klass->image, ei->token_or_filter))) {
+                                       
+                                               ctx->eip = (unsigned long)ei->handler_start;
+                                               ctx->ecx = (unsigned long)obj;
+                                               restore_context (ctx);
+                                               g_assert_not_reached ();
+                                       }
+                               }
+                       }
+
+                       /* no handler found - we need to call all finally handlers */
+                       for (i = 0; i < ji->num_clauses; i++) {
+                               MonoJitExceptionInfo *ei = &ji->clauses [i];
+
+                               if (ei->try_start <= ip && ip < (ei->try_end) &&
+                                   (ei->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
+                                       call_finally (ctx, (unsigned long)ei->handler_start);
+                               }
+                       }
+               }
+
+               /* continue unwinding */
+
+               /* restore caller saved registers */
+               if (ji->used_regs & X86_ESI_MASK) {
+                       ctx->esi = *((int *)ctx->ebp + offset);
+                       offset++;
+               }
+               if (ji->used_regs & X86_EDI_MASK) {
+                       ctx->edi = *((int *)ctx->ebp + offset);
+                       offset++;
+               }
+               if (ji->used_regs & X86_EBX_MASK) {
+                       ctx->ebx = *((int *)ctx->ebp + offset);
+               }
+
+               ctx->esp = ctx->ebp;
+
+               next_bp = *((int *)ctx->ebp);
+               next_ip = *((int *)ctx->ebp + 1);
+               
+               if (next_bp < (unsigned)mono_end_of_stack) {
+
+                       ctx->eip = next_ip;
+                       ctx->ebp = next_bp;
+                       arch_handle_exception (ctx, obj);
+
+               } else {
+                       mono_jit_abort (obj);
+               }
+
+       } else {
+               /* fixme: implement exceptions inside unmanaged code */
+               mono_jit_abort (obj);
+       }
+
+       g_assert_not_reached ();
+}
+
 
 
index 7d39020b437bd0892b4414bf138389ca2bda4bcb..14af8199076176074e742d255ecd31cf9a847b90 100644 (file)
@@ -712,11 +712,13 @@ 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 (MonoMemPool *mp, int addr_type, MBTree *s, MonoType *type, gpointer addr)
+ctree_create_store (MonoFlowGraph *cfg, int addr_type, MBTree *s, MonoType *type, gpointer addr)
 {
+       MonoMemPool *mp = cfg->mp;
        int stind = map_stind_type (type);
        MBTree *t;
 
+
        t = mono_ctree_new_leaf (mp, addr_type);
        t->data.p = addr;
        t = mono_ctree_new (mp, stind, t, s);
@@ -1781,7 +1783,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        g_assert (field);
 
                        addr = MONO_CLASS_STATIC_FIELDS_BASE (klass) + field->offset;
-                       t1 = ctree_create_store (mp, MB_TERM_ADDR_G, *sp, field->type, addr);
+                       t1 = ctree_create_store (cfg, MB_TERM_ADDR_G, *sp, field->type, addr);
 
                        ADD_TREE (t1, cli_addr);
                        break;
@@ -2307,7 +2309,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        ++ip;
                        --sp;
 
-                       t1 = ctree_create_store (mp, MB_TERM_ADDR_L, *sp, LOCAL_TYPE (n), 
+                       t1 = ctree_create_store (cfg, MB_TERM_ADDR_L, *sp, LOCAL_TYPE (n), 
                                                 (gpointer)LOCAL_POS (n));
 
                        ADD_TREE (t1, cli_addr);                        
@@ -2317,7 +2319,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        ++ip;
                        --sp;
 
-                       t1 = ctree_create_store (mp, MB_TERM_ADDR_L, *sp, LOCAL_TYPE (*ip), 
+                       t1 = ctree_create_store (cfg, MB_TERM_ADDR_L, *sp, LOCAL_TYPE (*ip), 
                                                 (gpointer)LOCAL_POS (*ip));
                        ++ip;
 
@@ -2598,7 +2600,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        ++ip;
                        --sp;
 
-                       t1 = ctree_create_store (mp, MB_TERM_ADDR_L, *sp, ARG_TYPE (*ip), 
+                       t1 = ctree_create_store (cfg, MB_TERM_ADDR_L, *sp, ARG_TYPE (*ip), 
                                                 (gpointer)ARG_POS (*ip));
                        ++ip;
 
@@ -2606,14 +2608,20 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        break;
                }
                case CEE_DUP: {
+                       int vnum;
+
                        ++ip; 
                        sp--;
-                       /* fixme: IMO we can use the temp. variable associated
-                        * with the current slot instead of -1 
-                        */
-                       if ((t2 = mono_store_tree (cfg, -1, *sp, &t1)) != NULL)
-                               ADD_TREE (t2, cli_addr);
 
+                       vnum = mono_allocate_intvar (cfg, sp - stack, sp [0]->svt);
+                       t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
+                       t1->data.i = vnum;
+                      
+                       t2 = mono_ctree_new (mp, map_store_svt_type (sp [0]->svt), t1, sp [0]);
+                       t2->svt = sp [0]->svt;
+                       ADD_TREE (t2, cli_addr);
+
+                       t1 = ctree_create_dup (mp, t2);         
                        PUSH_TREE (t1, t1->svt);
                        t1 = ctree_create_dup (mp, t1);         
                        PUSH_TREE (t1, t1->svt);
@@ -2676,6 +2684,13 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        PUSH_TREE (t1, VAL_DOUBLE);             
                        break;
                }
+               case CEE_CONV_R4: {
+                       ++ip;
+                       sp--;
+                       t1 = mono_ctree_new (mp, MB_TERM_CONV_R4, *sp, NULL);
+                       PUSH_TREE (t1, VAL_DOUBLE);             
+                       break;
+               }
                case CEE_CONV_OVF_U4: {
                        // fixme: raise exceptions ?
                        ++ip;
@@ -2909,195 +2924,6 @@ usage (char *name)
        exit (1);
 }
 
-static gpointer
-arch_get_restore_context ()
-{
-       static guint8 *start = NULL;
-       guint8 *code;
-
-       if (start)
-               return start;
-
-       /* restore_contect (struct sigcontext *ctx) */
-       /* we do not restore X86_EAX, X86_EDX */
-
-       start = code = malloc (1024);
-       
-       /* load ctx */
-       x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4);
-
-       /* get return address, stored in EDX */
-       x86_mov_reg_membase (code, X86_EDX, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, eip), 4);
-
-       /* restore EBX */
-       x86_mov_reg_membase (code, X86_EBX, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, ebx), 4);
-       /* restore EDI */
-       x86_mov_reg_membase (code, X86_EDI, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, edi), 4);
-       /* restore ESI */
-       x86_mov_reg_membase (code, X86_ESI, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, esi), 4);
-       /* restore ESP */
-       x86_mov_reg_membase (code, X86_ESP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, esp), 4);
-       /* restore EBP */
-       x86_mov_reg_membase (code, X86_EBP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, ebp), 4);
-       /* restore ECX. the exception object is passed here to the catch handler */
-       x86_mov_reg_membase (code, X86_ECX, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, ecx), 4);
-
-       /* jump to the saved IP */
-       x86_jump_reg (code, X86_EDX);
-
-       return start;
-}
-
-static gpointer
-arch_get_call_finally ()
-{
-       static guint8 *start = NULL;
-       guint8 *code;
-
-       if (start)
-               return start;
-
-       /* call_finally (struct sigcontext *ctx, unsigned long eip) */
-       start = code = malloc (1024);
-
-       x86_push_reg (code, X86_EBP);
-       x86_mov_reg_reg (code, X86_EBP, X86_ESP, 4);
-       x86_push_reg (code, X86_EBX);
-       x86_push_reg (code, X86_EDI);
-       x86_push_reg (code, X86_ESI);
-
-       /* load ctx */
-       x86_mov_reg_membase (code, X86_EAX, X86_EBP, 8, 4);
-       /* load eip */
-       x86_mov_reg_membase (code, X86_ECX, X86_EBP, 12, 4);
-       /* save EBP */
-       x86_push_reg (code, X86_EBP);
-       /* set new EBP */
-       x86_mov_reg_membase (code, X86_EBP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, ebp), 4);
-       /* call the handler */
-       x86_call_reg (code, X86_ECX);
-       /* restore EBP */
-       x86_pop_reg (code, X86_EBP);
-       /* restore saved regs */
-       x86_pop_reg (code, X86_ESI);
-       x86_pop_reg (code, X86_EDI);
-       x86_pop_reg (code, X86_EBX);
-       x86_leave (code);
-       x86_ret (code);
-
-       return start;
-}
-
-void
-arch_handle_exception (struct sigcontext *ctx, gpointer obj)
-{
-       MonoJitInfo *ji;
-       gpointer ip = (gpointer)ctx->eip;
-       static void (*restore_context) (struct sigcontext *);
-       static void (*call_finally) (struct sigcontext *, unsigned long);
-       ji = mono_jit_info_table_find (mono_jit_info_table, ip);
-
-       if (!restore_context)
-               restore_context = arch_get_restore_context ();
-       
-       if (!call_finally)
-               call_finally = arch_get_call_finally ();
-
-       if (ji) { /* we are inside managed code */
-               MonoMethod *m = ji->method;
-               unsigned next_bp, next_ip;
-               int offset = 2;
-
-               g_warning ("exception inside managed code %s.%s::%s",
-                          m->klass->name_space, m->klass->name, m->name);
-
-               if (ji->num_clauses) {
-                       int i;
-
-                       g_assert (ji->clauses);
-                       
-                       for (i = 0; i < ji->num_clauses; i++) {
-                               MonoJitExceptionInfo *ei = &ji->clauses [i];
-
-                               if (ei->try_start <= ip && ip < (ei->try_end)) { 
-                               
-                                       /* catch block */
-                                       if (ei->flags == 0 && mono_object_isinst (obj, 
-                                               mono_class_get (m->klass->image, ei->token_or_filter))) {
-                                       
-                                               ctx->eip = (unsigned long)ei->handler_start;
-                                               ctx->ecx = (unsigned long)obj;
-                                               restore_context (ctx);
-                                               g_assert_not_reached ();
-                                       }
-                               }
-                       }
-
-                       /* no handler found - we need to call all finally handlers */
-                       for (i = 0; i < ji->num_clauses; i++) {
-                               MonoJitExceptionInfo *ei = &ji->clauses [i];
-
-                               if (ei->try_start <= ip && ip < (ei->try_end) &&
-                                   (ei->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
-                                       call_finally (ctx, (unsigned long)ei->handler_start);
-                               }
-                       }
-               }
-
-               /* continue unwinding */
-
-               /* restore caller saved registers */
-               if (ji->used_regs & X86_ESI_MASK) {
-                       ctx->esi = *((int *)ctx->ebp + offset);
-                       offset++;
-               }
-               if (ji->used_regs & X86_EDI_MASK) {
-                       ctx->edi = *((int *)ctx->ebp + offset);
-                       offset++;
-               }
-               if (ji->used_regs & X86_EBX_MASK) {
-                       ctx->ebx = *((int *)ctx->ebp + offset);
-               }
-
-               ctx->esp = ctx->ebp;
-
-               next_bp = *((int *)ctx->ebp);
-               next_ip = *((int *)ctx->ebp + 1);
-
-               //printf ("EI %08lx %08x %p %08lx %08x\n", ctx->ebp, next_bp, 
-               //mono_end_of_stack, ctx->eip, next_ip);
-               
-               if (next_bp < (unsigned)mono_end_of_stack) {
-
-                       ctx->eip = next_ip;
-                       ctx->ebp = next_bp;
-                       arch_handle_exception (ctx, obj);
-
-               } else {
-                       char *message = "";
-                       MonoString *str = ((MonoException *)obj)->message;
-                       
-                       if (str)
-                               message = mono_string_to_utf8 (str);
-
-                       g_warning ("unhandled exception \"%s\" - no more frames to unwind", message);
-                       g_assert_not_reached ();
-               }
-
-       } else {
-               char *message = "";
-               MonoString *str = ((MonoException *)obj)->message;
-                       
-               if (str)
-                       message = mono_string_to_utf8 (str);
-               
-               g_warning ("exception \"%s\" inside unmanaged code - not implemented %08lx", message, ctx->eip);
-               g_assert_not_reached ();
-       }
-
-       g_assert_not_reached ();
-}
-
 static void
 sigfpe_signal_handler (int _dummy)
 {
@@ -3126,6 +2952,38 @@ sigsegv_signal_handler (int _dummy)
        g_error ("we should never reach this code");
 }
 
+/**
+ * mono_jit_abort:
+ * @obj: exception object
+ *
+ * abort the program, print exception information and stack trace
+ */
+void
+mono_jit_abort (MonoObject *obj)
+{
+       char *message = "";
+       char *trace = NULL;
+       MonoString *str; ;
+
+       g_assert (obj);
+
+       if (mono_object_isinst (obj, mono_defaults.exception_class)) {
+               if ((str = ((MonoException *)obj)->message))
+                       message = mono_string_to_utf8 (str);
+               if ((str = ((MonoException *)obj)->stack_trace))
+                       trace = mono_string_to_utf8 (str);
+       }                               
+       
+       g_warning ("unhandled exception \"%s\"", message);
+       
+       if (trace) {
+               g_printerr (trace);
+               g_printerr ("\n");
+       }
+
+       exit (1);
+}
+
 int 
 main (int argc, char *argv [])
 {
@@ -3175,7 +3033,7 @@ main (int argc, char *argv [])
        sa.sa_handler = sigsegv_signal_handler;
        sigemptyset (&sa.sa_mask);
        sa.sa_flags = 0;
-       g_assert (syscall (SYS_sigaction, SIGSEGV, &sa, NULL) != -1);
+       //g_assert (syscall (SYS_sigaction, SIGSEGV, &sa, NULL) != -1);
 
        mono_init ();
        mono_init_icall ();
index 1d29d77f45b1f2abf63b3b5559222e90933f70e6..75c3787c2aef973ee00fd6ec26f9b8bb466b7f57 100644 (file)
@@ -4,6 +4,7 @@
 #include <signal.h>
 
 #include <mono/metadata/loader.h>
+#include <mono/metadata/object.h>
 
 #include "regset.h"
 #include "mempool.h"
@@ -118,6 +119,9 @@ mono_jit_info_table_find   (MonoJitInfoTable *table, gpointer addr);
 void
 arch_handle_exception      (struct sigcontext *ctx, gpointer obj);
 
+void
+mono_jit_abort             (MonoObject *obj);
+
 MonoFlowGraph *
 mono_cfg_new               (MonoMethod *method, MonoMemPool *mp);
 
index 610f99511758c90848926b8fdb54cba5b4dc5206..3c994f0461311014ef73df17ded9099b9817d374 100644 (file)
@@ -150,7 +150,7 @@ x86_pop_reg (s->code, X86_EAX);
 %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_R8
+%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 LDLEN
@@ -1864,6 +1864,10 @@ stmt: BLE_UN (lreg, lreg) {
 #      x86_fist_pop_membase (s->code, X86_EBP, tree->data.i, FALSE);
 #} 
 
+freg: CONV_R8 (freg) {
+       /* nothing to do */
+}
+
 freg: CONV_R8 (LDIND_I4 (ADDR_G)) {
        x86_fild (s->code, tree->left->left->data.p, FALSE);
 }
@@ -1878,6 +1882,16 @@ freg: CONV_R8 (reg) {
        x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 4);
 }
 
+freg: CONV_R4 (reg) {
+       /* I found no direct way to move an integer register to 
+        * the floating point stack, so we need to store the register
+        * to memory
+        */
+       x86_push_reg (s->code, tree->left->reg1);
+       x86_fild_membase (s->code, X86_ESP, 0, FALSE);
+       x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 4);
+}
+
 freg: CONST_R4 {
        float f = *(float *)tree->data.p;
 
index 34c488430bcae0874ce47133c5d117aef5b365a1..6d1355e36eefe14416ab460c86b013fdc72fb1fb 100644 (file)
@@ -169,6 +169,10 @@ mono_init (void)
        mono_defaults.monotype_class = mono_class_from_name (
                 mono_defaults.corlib, "System", "MonoType");
        g_assert (mono_defaults.monotype_class != 0);
+
+       mono_defaults.exception_class = mono_class_from_name (
+                mono_defaults.corlib, "System", "Exception");
+       g_assert (mono_defaults.exception_class != 0);
 }
 
 static GHashTable *icall_hash = NULL;
index 8f25f9f2b8fded68c7494e17d7e8cf731b33d8d2..2d1532a945d067fa72550d3e1d4729ca030c02b0 100644 (file)
@@ -53,6 +53,7 @@ typedef struct {
        MonoClass *fieldhandle_class;
        MonoClass *methodhandle_class;
        MonoClass *monotype_class;
+       MonoClass *exception_class;
 } MonoDefaults;
 
 extern MonoDefaults mono_defaults;
index 386cea6bd95417e8baa28e47377ae11465366cf5..ca7f65fb55e03ab3fe9ffbc8c1e8d3a271c41f21 100644 (file)
@@ -31,6 +31,11 @@ typedef struct {
        MonoObject object;
        MonoObject *inner_ex;
        MonoString *message;
+       MonoString *help_link;
+       MonoString *class_name;
+       MonoString *stack_trace;
+       gint32      hresult;
+       MonoString *source;
 } MonoException;
 
 typedef struct {