[Mono-list] LCC and CIL

Dominic Cooney dominic@dcooney.com
Wed, 13 Mar 2002 07:39:44 +1000


I guess I need to brush up on my C! gcc allows this:

#include <setjmp.h>

jmp_buf env_buf;

int funcA()
{
	int v = setjmp(env_buf);
	printf("setjmp returned %d\n", v);
	return v;
}

int main()
{
	if (!funcA())
		longjmp(env_buf, 1);
}

gcc's executable works correctly, and I thought the program was legal.
MSVC++ accepts it and prints "setjmp returned 0, setjmp returned 1" but
then crashes.

-----Original Message-----
From: mono-list-admin@ximian.com [mailto:mono-list-admin@ximian.com] On
Behalf Of Fergus Henderson
Sent: Tuesday, 12 March 2002 4:39 PM
To: Dominic Cooney
Cc: mono-list@ximian.com
Subject: Re: [Mono-list] LCC and CIL

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.

_______________________________________________
Mono-list maillist  -  Mono-list@ximian.com
http://lists.ximian.com/mailman/listinfo/mono-list