[Mono-list] LCC and CIL

Fergus Henderson fjh@cs.mu.oz.au
Tue, 12 Mar 2002 17:39:09 +1100


On 12-Mar-2002, Dominic Cooney <dominic@dcooney.com> wrote:
> I wonder how they compile setjmp(), longjmp()...

The right way to handle this would be to convert it to code using
exception handling.  Code that calls setjmp() would get converted to use
`try' and longjmp() can be implemented using `throw'.

It does require some special treatment of setjmp() in the compiler,
to process blocks containing calls to setjmp().
Suppose the block is divided into STATEMENTS_BEFORE_THE_SETJMP,
STATEMENT_CONTAINING_THE_SETJMP, and STATEMENTS_AFTER_THE_SETJMP,
and suppose the argument to setjmp() is BUF.
Then the compiler could convert it as follows:

	STATEMENTS_BEFORE_THE_SETJMP
	{
		__jmp_buf_struct *__tmp = BUF;
		int __setjmp_retval = 0;
	__loop:
		try {
			STATEMENT_CONTAINING_THE_SETJMP
			STATEMENTS_AFTER_THE_SETJMP
		} catch (__SetjmpException e) {
			if (e.__buf != __tmp) throw;
			__setjmp_retval = e.__retval;
			goto __loop;
		}
	}

With this transformation, the remaining implementation of setjmp()
and longjmp() would be easy.  <setjmp.h> could just contain the following

	typedef struct __jmp_buf_struct {
		int __retval;
	} jmp_buf[1];

	struct __SetjmpException {
		struct __jmp_buf_struct *buf;
		int __retval;
	};

	void longjmp(jmp_buf env, int retval);

	#define setjmp(buf) __setjmp_retval

and setjmp.c needs only

	void longjmp(jmp_buf env, int retval) {
		env->__retval = val;
		throw __SetjmpException;
	}

Well, this is just off the top of my head; I may have some details wrong.
But hopefully you get the idea.

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.