[MLton] cvs commit: improved exception history for Overflow

Matthew Fluet fluet@cs.cornell.edu
Mon, 23 May 2005 11:33:17 -0400 (EDT)


> I ended up going for a two-piece solution that didn't require changing
> any ILs.  The elaborator wraps an Enter/Leave around each raise
> expression, just as it does around each function body.  

That works, but note that the body of the raise is an expression, which 
may itself raise.  So, the following program

-------------------------------------------------------------------
fun loop n =
   if n > 12345
      then let 
              val () = raise (raise (Fail "here"))
           in 2
           end
   else 1 + (loop (4 * n))
        handle Overflow => 1

val _ = loop 1
-------------------------------------------------------------------

gives the slightly incongruous

unhandled exception: Fail: here
with history:
	loop.raise z.sml 4.37
	loop.raise z.sml 4.30
	loop z.sml 1.5
	loop z.sml 1.5
	loop z.sml 1.5
	loop z.sml 1.5
	loop z.sml 1.5
	loop z.sml 1.5
	loop z.sml 1.5
	loop z.sml 1.5

This could be fixed by having the elaborator let-bind the exception and 
wrap Enter/Leave around the raise of the variable.  But, I suspect this 
sort of thing is sufficiently rare that it may not be worth complicating 
the elaborator.

> > On the other hand, adding the profile expressions in implementExceptions 
> > is late enough in the game that we've lost the distinction between the 
> > basis and the user code.  So, that means that _all_ raised exceptions 
> > would report the origin, not just those that were raised in user code.  
> > This is different than the current behavior where an exception raised in 
> > the basis is only given its point of origin when -profile-basis true is a 
> > compile option.  On the other hand, it is exactly one more entry in the 
> > history, so it doesn't seem that bad.
> 
> This is true of the approach I took too.  And I agree; it doesn't seem
> bad to me.

Actually, it isn't a problem.  I thought that the elaborator decided not
to insert profile Enter/Leave for basis code, but it turns out that that
decision is delayed all the way to the backend Profile pass.  So, as long
as the source positions for those raises are in the Basis Library, they
won't be reported.