Bläddra i källkod

2003-05-22 Dietmar Maurer <[email protected]>

	* exceptions-x86.c (mono_arch_handle_exception): bug fix.

	* more docu

svn path=/trunk/mono/; revision=14803
Dietmar Maurer 22 år sedan
förälder
incheckning
9bc145b02b
7 ändrade filer med 44 tillägg och 19 borttagningar
  1. 4 5
      docs/exceptions
  2. 13 2
      docs/mini-porting.txt
  3. 2 0
      mono/mini/ChangeLog
  4. 12 8
      mono/mini/exceptions-x86.c
  5. 13 2
      mono/mini/mini-porting.txt
  6. 0 1
      mono/mini/mini-ppc.h
  7. 0 1
      mono/mini/mini-x86.h

+ 4 - 5
docs/exceptions

@@ -62,16 +62,15 @@ to the local variables of the enclosing method. Its is possible that
 instructions inside those handlers modify the stack pointer, thus we save the
 stack pointer at the start of the handler, and restore it at the end. We have
 to use a "call" instruction to execute such finally handlers. This makes it
-also possible to execute them inside the stack unwinding code. Filters receives
-the exception object in ECX.
+also possible to execute them inside the stack unwinding code. The exception
+object for filters is passed in a local variable (cfg->exvar).
 
 throw: we first save all regs into a sigcontext struct (we pass the
 exception object in register ECX), and then call the stack unwinding
 code.
 
-catch handler: receives the exception object in ECX. They store that
-object into a local variable, so that rethrow can access the object.
-
+catch handler: catch hanlders are always called from the stack unwinding
+code. The exception object is passed in a local variable (cfg->exvar).
 
 gcc support for Exceptions
 ==========================

+ 13 - 2
docs/mini-porting.txt

@@ -272,8 +272,7 @@ To make this possible we implement them like subroutines, ending with a
 need access to the local variables of the enclosing method. Its is possible
 that instructions inside those handlers modify the stack pointer, thus we save
 the stack pointer at the start of the handler, and restore it at the end. We
-have to use a "call" instruction to execute such finally handlers. Filters
-receives the exception object inside a register (ECX on x86).
+have to use a "call" instruction to execute such finally handlers.
 
 The MIR code for filter and finally handlers looks like:
 
@@ -296,6 +295,18 @@ we simply emit a call instruction to invoke the handler. Its usually
 possible to use the same code to call filter and finally handlers (see
 arch_get_call_filter).
 
+** Calling catch handlers
+
+Catch handlers are always called from the stack unwinding code. Unlike finally clauses
+or filters, catch handler never return. Instead we simply restore the whole
+context, and restart execution at the catch handler.
+
+** Passing Exception objects to catch handlers and filters.
+
+We use a local variable to store exception objects. The stack unwinding code
+must store the exception object into this variable before calling catch handler
+or filter.
+
 * Minor helper methods
 
 A few minor helper methods are referenced from the arch-independent code.

+ 2 - 0
mono/mini/ChangeLog

@@ -1,5 +1,7 @@
 2003-05-22  Dietmar Maurer  <[email protected]>
 
+	* exceptions-x86.c (mono_arch_handle_exception): bug fix.
+
 	* mini-x86.c (mono_arch_output_basic_block): cleanup up exception code
 
 	* inssel-x86.brg: added OP_START_HANDLER, CEE_ENDFINALLY, OP_ENDFILTER

+ 12 - 8
mono/mini/exceptions-x86.c

@@ -511,7 +511,7 @@ arch_get_call_filter (void)
 		return start;
 
 	inited = 1;
-	/* call_filter (struct sigcontext *ctx, unsigned long eip, gpointer exc) */
+	/* call_filter (struct sigcontext *ctx, unsigned long eip) */
 	code = start;
 
 	x86_push_reg (code, X86_EBP);
@@ -526,8 +526,7 @@ arch_get_call_filter (void)
 	x86_mov_reg_membase (code, X86_ECX, X86_EBP, 12, 4);
 	/* save EBP */
 	x86_push_reg (code, X86_EBP);
-	/* push exc */
-	x86_push_membase (code, X86_EBP, 16);
+
 	/* set new EBP */
 	x86_mov_reg_membase (code, X86_EBP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_EBP), 4);
 	/* restore registers used by global register allocation (EBX & ESI) */
@@ -538,7 +537,6 @@ arch_get_call_filter (void)
 	/* call the handler */
 	x86_call_reg (code, X86_ECX);
 
-	x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);
 	/* restore EBP */
 	x86_pop_reg (code, X86_EBP);
 
@@ -964,7 +962,7 @@ mono_arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
 {
 	MonoDomain *domain = mono_domain_get ();
 	MonoJitInfo *ji, rji;
-	static int (*call_filter) (MonoContext *, gpointer, gpointer) = NULL;
+	static int (*call_filter) (MonoContext *, gpointer) = NULL;
 	MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
 	MonoLMF *lmf = jit_tls->lmf;		
 	GList *trace_ips = NULL;
@@ -1038,10 +1036,17 @@ mono_arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
 					if (ei->try_start <= MONO_CONTEXT_GET_IP (ctx) && 
 					    MONO_CONTEXT_GET_IP (ctx) <= ei->try_end) { 
 						/* catch block */
+
+						if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE) || (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER)) {
+							/* store the exception object int cfg->excvar */
+							g_assert (ji->exvar_offset);
+							*((gpointer *)((char *)MONO_CONTEXT_GET_BP (ctx) + ji->exvar_offset)) = obj;
+						}
+
 						if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE && 
 						     mono_object_isinst (obj, mono_class_get (ji->method->klass->image, ei->data.token))) ||
 						    ((ei->flags == MONO_EXCEPTION_CLAUSE_FILTER &&
-						      call_filter (ctx, ei->data.filter, obj)))) {
+						      call_filter (ctx, ei->data.filter)))) {
 							if (test_only) {
 								((MonoException*)obj)->trace_ips = glist_to_array (trace_ips);
 								g_list_free (trace_ips);
@@ -1051,7 +1056,6 @@ mono_arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
 							if (mono_jit_trace_calls)
 								g_print ("EXCEPTION: catch found at clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE));
 							MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
-							*((gpointer *)((char *)MONO_CONTEXT_GET_BP (ctx) + ji->exvar_offset)) = obj;
 							jit_tls->lmf = lmf;
 							g_free (trace);
 							return 0;
@@ -1061,7 +1065,7 @@ mono_arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
 						    (ei->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
 							if (mono_jit_trace_calls)
 								g_print ("EXCEPTION: finally clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE));
-							call_filter (ctx, ei->handler_start, NULL);
+							call_filter (ctx, ei->handler_start);
 						}
 						
 					}

+ 13 - 2
mono/mini/mini-porting.txt

@@ -272,8 +272,7 @@ To make this possible we implement them like subroutines, ending with a
 need access to the local variables of the enclosing method. Its is possible
 that instructions inside those handlers modify the stack pointer, thus we save
 the stack pointer at the start of the handler, and restore it at the end. We
-have to use a "call" instruction to execute such finally handlers. Filters
-receives the exception object inside a register (ECX on x86).
+have to use a "call" instruction to execute such finally handlers.
 
 The MIR code for filter and finally handlers looks like:
 
@@ -296,6 +295,18 @@ we simply emit a call instruction to invoke the handler. Its usually
 possible to use the same code to call filter and finally handlers (see
 arch_get_call_filter).
 
+** Calling catch handlers
+
+Catch handlers are always called from the stack unwinding code. Unlike finally clauses
+or filters, catch handler never return. Instead we simply restore the whole
+context, and restart execution at the catch handler.
+
+** Passing Exception objects to catch handlers and filters.
+
+We use a local variable to store exception objects. The stack unwinding code
+must store the exception object into this variable before calling catch handler
+or filter.
+
 * Minor helper methods
 
 A few minor helper methods are referenced from the arch-independent code.

+ 0 - 1
mono/mini/mini-ppc.h

@@ -13,7 +13,6 @@
 #define MONO_ARCH_BASEREG X86_EBP
 #define MONO_ARCH_RETREG1 ppc_r3
 #define MONO_ARCH_RETREG2 ppc_r4
-#define MONO_ARCH_EXC_REG ppc_r5
 
 struct MonoLMF {
 	gpointer    previous_lmf;

+ 0 - 1
mono/mini/mini-x86.h

@@ -12,7 +12,6 @@
 #define MONO_ARCH_BASEREG X86_EBP
 #define MONO_ARCH_RETREG1 X86_EAX
 #define MONO_ARCH_RETREG2 X86_EDX
-#define MONO_ARCH_EXC_REG X86_ECX
 
 #define MONO_ARCH_ENCODE_LREG(r1,r2) (r1 | (r2<<3))