Hi Christoph,
Christoph Thiede wrote
Instead of reinventing the unwinding wheel in Process, I reused the
existing logic from Context which is important deduplication. Well, actually I didn't reinvent the unwind pattern but intentionally reused it with as few changes as possible - I think it improves readability because people easily recognize this pattern from #resume:, #resume:through:, #unwindTo and even the previous #terminate used the exact same pattern for
an active process termination. Besides, using the same pattern for achieving a similar goal feels "safer" to me.
A pattern is good, but reusing the same code is even better. :-) I still see some signification duplication between #runUntilErrorOrReturnFrom: and #runUnwindUntilErrorOrReturnFrom: as well as between Process >> #terminate and Context >> #unwindTo:. But Kernel-jar.1411 already is a good step into the right direction as far as I can tell. :-)
Yes, I was wondering why I couldn't get rid of the duplication and now I think it's because there really are two distinct unwind semantics : one "light" for regular returns and one "heavy" for termination. Both are very similar yet each require a slightly different behavior - that's why the duality #runUntilErrorOrReturnFrom / #runUnwindUntilErrorOrReturnFrom or #complete: / #complete:to: and #unwindTo: / #terminate.
With regards to #unwindTo: - I haven't tested it yet but I'm wondering whether it wouldn't have the same unwind problem with non-local returns as the original #terminate and require a similar fix?
Christoph Thiede wrote
What remains unacceptable or dangerous to me are your hard-coded exceptions in Process >> #complete:to:. If this is crucial to prevent akwards infinite recursions, we might not be immune against similar incidents for other kinds of recursion as well. Object >> #at:, for example, is no better than Object >> #doesNotUnderstand:. Actually, any exception or exception handler might produce a similar behavior. Could you provide a few concrete examples where this check is needed? Maybe we can find a more holistic solution to this issue.
Yes, this bothers me as well. I consider two common sources of infinite recursions: (1) MessageNotUnderstood - #doesNotUnderstand is intentionally written so that it resends the unknown message to facilitate writing new methods while debugging. So for the moment to recover termination from this error I suggested to deal with it on an individual basis - i.e. skip the unwind block with the error. (and yes, you're right this only applies to the "heavy" version of unwinding) (2) BlockCannonReturn - we'll discuss this in [2]
But in general - yes, any method/exception purposefully (or not) written to create a loop will break this patch (I admit it is just a patch really). I extracted it to #complete:to: to make #terminate clean; this is a WIP; I wish there was a holistic solution to this - maybe checking for exception recursion by default? :)
Christoph Thiede wrote
Again, I wanted to make as few changes as possible; but agreed absolutely :)
That is also a very reasonable goal which I had to learn myself the hard way. :) Keep going! :-)
Best, Christoph
[1] http://forum.world.st/The-semantics-of-halfway-executed-unwind-contexts-duri... [2] http://forum.world.st/The-Inbox-Kernel-ct-1405-mcz-tp5129706p5130114.html
----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html