diff: runtime/engine.h

Simon Taylor stayl at cs.mu.oz.au
Tue Jul 29 14:27:10 AEST 1997


Hi Fergus,

This is an updated diff of runtime/engine.h including ANSI-conformant
MR_setjmp/MR_longjmp and saving/restoring of the Mercury state
within MR_setjmp/MR_longjmp.

Simon.


Index: engine.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/engine.h,v
retrieving revision 1.13
diff -u -r1.13 engine.h
--- engine.h	1997/07/27 15:08:14	1.13
+++ engine.h	1997/07/29 02:49:53
@@ -13,6 +13,8 @@
 #ifndef	ENGINE_H
 #define	ENGINE_H
 
+#include <setjmp.h>
+
 #include "std.h"		/* for `bool' */
 #include "mercury_types.h"	/* for `Code *' */
 #include "goto.h"		/* for `Define_entry()' */
@@ -42,6 +44,75 @@
 #define	sregdebug	debugflag[SREGFLAG]
 #define	tracedebug	debugflag[TRACEFLAG]
 #define	detaildebug	debugflag[DETAILFLAG]
+
+	/* 
+	** MR_setjmp and MR_longjmp are wrappers around setjmp and longjmp 
+	** to ensure that
+	**	 call C -> setjmp -> call Mercury -> call C -> longjmp 
+	** works correctly. This is used by the exception handling code for
+	** the ODBC interface.
+	*/ 
+
+	/*
+	** We don't save hp or r1, r2 etc. because the longjmping
+	** code may want to return data on the heap or in registers.
+	*/
+typedef struct {
+		jmp_buf *mercury_env;	/* 
+					** used to save MR_engine_jmp_buf 
+					*/
+		jmp_buf env;		/* 
+					** used by calls to setjmp and longjmp 
+					*/
+		Word *saved_succip;
+		Word *saved_sp;
+		Word *saved_curfr;
+		Word *saved_maxfr;
+	} MR_jmp_buf;
+
+	/*
+	** MR_setjmp(MR_jmp_buf *env, longjmp_label)
+	**
+	** Save MR_engine_jmp_buf, save the Mercury state, call setjmp(env), 
+	** then fall through.
+	** When setjmp returns via a call to longjmp, control will pass to
+	** longjmp_label.
+	*/
+#define MR_setjmp(setjmp_env, longjmp_label)				\
+		do {							\
+			(setjmp_env)->mercury_env = MR_engine_jmp_buf;	\
+			(setjmp_env)->saved_succip = succip;		\
+			(setjmp_env)->saved_sp = sp;			\
+			(setjmp_env)->saved_curfr = curfr;		\
+			(setjmp_env)->saved_maxfr = maxfr;		\
+			if (setjmp((setjmp_env)->env)) {		\
+				restore_transient_registers();		\
+				goto longjmp_label;			\
+			}						\
+		} while (0)
+
+	/*
+	** MR_longjmp(MR_jmp_buf *env, int return)
+	**
+	** Reset MR_engine_jmp_buf to the value stored in env, restore the
+	** Mercury registers, then call longjmp().
+	*/
+#define MR_longjmp(setjmp_env, ret)					\
+		do {							\
+			MR_engine_jmp_buf = (setjmp_env)->mercury_env;	\
+			succip = (setjmp_env)->saved_succip;		\
+			sp = (setjmp_env)->saved_sp;			\
+			curfr = (setjmp_env)->saved_curfr;		\
+			maxfr = (setjmp_env)->saved_maxfr;		\
+			save_transient_registers();			\
+			longjmp((setjmp_env)->env, ret);		\
+		} while (0)
+
+	/* 
+	** engine_jmp_buf should only be referred to in engine.c
+	** and the MR_setjmp and MR_longjmp macros defined above.
+	*/
+extern	jmp_buf *MR_engine_jmp_buf;
 
 extern	bool	debugflag[];
 



More information about the developers mailing list