Am Montag, 18. September 2006 03:56 schrieb Bob Rogers: > The attached patch consolidates most of the existing stack-unwinding > code into Continuation:invoke; previously, RetContinuation:invoke and > find_exception_handler also did stack-unwinding, and none of the three > did it quite the same way.
Very good. > Here are the effects: > > 1. Improved code sharing, a prerequisite for improving semantics. > > 2. Actions are now triggered when a continuation is called, fixing > two TODO cases (and also two others which were looking for the buggy > behavior). Previously, this only worked for exception handling and > RetContinuation. There are (ought to be) presumably 2 different kinds of continuations: 1) I leave this call frame for now, but I'll be back 2) I'm done with this call frame forever An exit_handler action would be invoked only for the 2nd case. And while at it, we probably want some more specialized (limited) continuations with e.g. a given range of call frames, which the continuation will not leave. > 3. Actions are no longer triggered as a side-effect of discovering > that there are no active exception handlers, which is more in the spirit > of PDD23. IMHO there is always an exception handler, assuming a toplevel default handler, which is implicitely handling the "No exception handler found" case. Avoiding this side-effect seems to be the reason for the very complex and costly search for active handlers, which I really don't like. Re PDD23 see below. > 4. Variable names are now more consistent between > Continuation:invoke and RetContinuation:invoke (or what's left of it). Great. > Questions: > > 1. I notice that parameter passing is handled by Continuation:invoke > but not by RetContinuation:invoke. Currently I have to use some > cumbersome "Am I a RetContinuation?" logic in what is supposed to be the > generic method in order to deal with this. It would be nicer if they > both passed parameters in the same way. Is there some reason this can't > be done? Currently set_returns and set_args are 2 different opcodes: .return (foo, bar) # RetContinuation.invoke - set_returns cc(foo, bar) # Continuation.invoke - set_args But with a few changes, we could unify "results" value handling: - the current_results pointer *should* be part of the continuation structure and not of the context like now (it is already in the Continuation) - then unifying set_returns and set_args would give us common {Ret,}Continuation argument->results passing. > 2. The exception handling case is not as efficient as it could be > (quadratic handler search followed by re-searching for the handler's > stack entry). This would be helped by splitting the unwinding code into > a separate routine, and calling it from each of the invoke methods, > rather than trying to use inheritance. But I assume this will need to > be rewritten anyway when PDD23 is fully implemented. With that in mind, > is this OK for now? Given that it'll be rewritten yes ;-) > 3. Around src/exceptions.c:268 (unpatched) there is an assignment of > e->entry_type to NO_STACK_ENTRY_TYPE, after a comment explaining why. > The patch disables this assignment, with no ill effect. If the code is > still needed for some reason, it will have to be moved to > RetContinuation:invoke, but I don't have a test case to ensure that I've > done this right. Should I just chuck it? It was IIRC needed for DOD. I.e. at some time there was a stale stack entry, which caused troubles during stack marking. This could have been due to an error elsewhere of course. > Suggestions are cordially invited. If I hear no complaints by > tomorrow night, I will assume all answers are "yes," and commit this (or > something close to it). Ok. BTW: + && ! ret_continuation_p) { fprintf(stderr, "[oops; continuation %p of type %d " "is trying to jump from runloop %d to runloop %d]\n", This meessage is triggered for exceptions too, which is wrong. Only continuations that *would* possibly resume this runloop are a problem (i.e. the 1) case above). Re PDD23: It's not implementable the way it is. The main problem is of course the already discussed continuation border of C code. E.g. <cite> The embedding program may choose to handle the exception and continue execution by invoking the exception's continuation. </cite> But there's no way currently to safely invoke the continuation from C code and continue at some arbitrary runloop nesting. I also dislike the stated mandantory closure-ish behavior of handlers. The general case seems to be that the handler is a label in the context of the handling call frame. If HLL semantics are different, the handler code can still create and call a closure for handling the exception. And I don't get the rational of: <cite> 3 Invoke the handler (note: this is still in the thrower's dynamic con- text). </cite> To me it seems that this should always be the exception handler's context. > -- Bob Rogers > http://rgrjr.dyndns.org/ leo