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