Index: engine/verify_except.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/verify_except.c,v
retrieving revision 1.9
diff -c -r1.9 verify_except.c
*** engine/verify_except.c	26 May 2003 05:47:03 -0000	1.9
--- engine/verify_except.c	14 May 2004 17:32:40 -0000
***************
*** 32,124 ****
  static void OutputExceptionTable(ILCoder *coder, ILMethod *method,
  								 ILException *exceptions, int hasRethrow)
  {
! 	ILUInt32 offset;
! 	ILUInt32 end;
! 	ILUInt32 lowestTry;
! 	ILException *exception;
  	ILClass *classInfo;
  
! 	/* Process all regions in the method */
! 	offset = 0;
! 	for(;;)
  	{
! 		/* Find the exception region that matches the offset */
! 		exception = exceptions;
! 		lowestTry = IL_MAX_UINT32;
! 		while(exception != 0)
  		{
! 			if(offset >= exception->tryOffset &&
! 			   offset < (exception->tryOffset + exception->tryLength))
  			{
! 				/* The offset is within this region */
! 				break;
  			}
! 			else if(offset < exception->tryOffset)
  			{
! 				/* The offset starts entirely before this region */
! 				lowestTry = exception->tryOffset;
! 				break;
  			}
- 			exception = exception->next;
- 		}
- 		if(!exception)
- 		{
- 			break;
- 		}
- 		if(lowestTry != IL_MAX_UINT32)
- 		{
- 			end = lowestTry;
- 		}
- 		else
- 		{
- 			end = exception->tryOffset + exception->tryLength;
  		}
  
! 		/* Output the region information to the table */
! 		ILCoderTryHandlerStart(coder, offset, end);
  
! 		/* Output exception matching code for this region */
! 		exception = exceptions;
! 		while(exception != 0)
  		{
! 			if(offset >= exception->tryOffset &&
! 			   offset < (exception->tryOffset + exception->tryLength))
  			{
! 				if((exception->flags & (IL_META_EXCEPTION_FINALLY |
! 										IL_META_EXCEPTION_FAULT)) != 0)
! 				{
! 					/* Call a "finally" or "fault" clause */
! 					ILCoderJsr(coder, exception->handlerOffset);
! 				}
! 				else if((exception->flags & IL_META_EXCEPTION_FILTER) == 0)
! 				{
! 					/* Match against a "catch" clause */
! 					classInfo = ILProgramItemToClass
! 						((ILProgramItem *)ILImageTokenInfo
! 							(ILProgramItem_Image(method), exception->extraArg));
! 					ILCoderCatch(coder, exception, classInfo, hasRethrow);
! 				}
! 				else
  				{
! 					/* TODO: handle a "filter" clause */
  				}
  			}
! 			exception = exception->next;
  		}
  
! 		/* If execution falls off the end of the matching code,
! 		   then throw the exception to the calling method */
! 		ILCoderThrow(coder, 0);
  
! 		/* Mark the end of the handler */
  		ILCoderTryHandlerEnd(coder);
  
! 		/* Advance to the next region within the code */
! 		offset = end;
  	}
  
! 	/* If execution gets here, then there were no applicable catch blocks,
! 	   so we always throw the exception to the calling method */
  	ILCoderTryHandlerStart(coder, 0, IL_MAX_UINT32);
  	ILCoderThrow(coder, 0);
  	ILCoderTryHandlerEnd(coder);
--- 32,162 ----
  static void OutputExceptionTable(ILCoder *coder, ILMethod *method,
  								 ILException *exceptions, int hasRethrow)
  {
! 	int allowFilter;
! 	int isNested;
! 	ILUInt32 tryOffset;
! 	ILUInt32 tryLength;
! 	ILUInt32 tryEnd;
! 	ILUInt32 handlerOffset;
! 	ILException *e;
! 	ILException *x;
! 	ILException *last;
! 	ILException *prev;
  	ILClass *classInfo;
  
! 	/* add each exception to the exception table after its verification */
! 	for(e = exceptions; e != 0; e = e->next)
  	{
! 		allowFilter = 1;
! 		isNested = 0;
! 		tryOffset = e->tryOffset;
! 		tryLength = e->tryLength;
! 		tryEnd = tryOffset + tryLength;
! 		handlerOffset = e->handlerOffset;
! 		last = e;
! 
! 		/* go through remaining exceptions to ensure proper ordering */
! 		for(x = e->next, prev = e; x != 0; prev = x, x = x->next)
  		{
! 			/* mutual, nested, disjoint, or error */
! 			if((tryOffset == x->tryOffset) &&
! 			   (tryLength == x->tryLength))
  			{
! 				/* handlers in a group must be listed consecutively */
! 				if(prev != last)
! 				{
! 					/* TODO: verification error */
! 				}
! 
! 				/* set this handler as the end of the group */
! 				last = x;
  			}
! 			else if((tryOffset >= x->tryOffset) &&
! 			        (tryEnd < (x->tryOffset + x->tryLength)))
  			{
! 				/* x is handler for outer try block (e is nested in x) */
! 				isNested = 1;
! 			}
! 			else if((x->tryOffset > tryEnd) ||
! 			        (tryOffset > (x->tryOffset + x->tryLength)))
! 			{
! 				/* x is handler for separate try block */
! 			}
! 			else
! 			{
! 				/* error at this point - malformed/out-of-order exceptions */
! 				/* TODO: verification error */
  			}
  		}
  
! 		/* start a new region */
! 		ILCoderTryHandlerStart(coder, tryOffset, tryEnd);
! 
! 		/* save a pointer to the last handler in the group */
! 		prev = last;
  
! 		/* save a pointer to one past the end of the group */
! 		last = last->next;
! 
! 		/* add all handlers for this region */
! 		for(x = e; x != last; x = x->next)
  		{
! 			/* ensure handlers come after their try blocks */
! 			if(tryEnd > handlerOffset)
  			{
! 				/* TODO: verification error */
! 			}
! 
! 			/* output the handler code based on the flags */
! 			if((x->flags & (IL_META_EXCEPTION_FINALLY |
! 			                IL_META_EXCEPTION_FAULT)) != 0)
! 			{
! 				/* call a "finally" or "fault" clause */
! 				ILCoderJsr(coder, handlerOffset);
! 
! 				/* mark that we've already had a fault/finally in this group */
! 				allowFilter = 0;
! 			}
! 			else if((x->flags & IL_META_EXCEPTION_FILTER) == 0)
! 			{
! 				/* match against a "catch" clause */
! 				classInfo = ILProgramItemToClass
! 					((ILProgramItem *)ILImageTokenInfo
! 						(ILProgramItem_Image(method), e->extraArg));
! 				ILCoderCatch(coder, e, classInfo, hasRethrow);
! 
! 				/* mark that we've already had a catch in this group */
! 				allowFilter = 0;
! 			}
! 			else
! 			{
! 				/* TODO: handle a "filter" clause */
! 
! 				/* filters must come before all other handlers */
! 				if(!allowFilter)
  				{
! 					/* TODO: verification error */
  				}
  			}
! 
! 			/* TODO: handle other handler type ordering constraints */
  		}
  
! 		/* only throw to caller from the outermost handlers */
! 		if(!isNested)
! 		{
! 			/* throw the exception to the calling method */
! 			ILCoderThrow(coder, 0);
! 		}
  
! 		/* mark the end of the handler */
  		ILCoderTryHandlerEnd(coder);
  
! 		/* advance to the end of the region just added */
! 		e = prev;
  	}
  
! 	/* if unhandled at the top-level region, throw to caller */
  	ILCoderTryHandlerStart(coder, 0, IL_MAX_UINT32);
  	ILCoderThrow(coder, 0);
  	ILCoderTryHandlerEnd(coder);
