[self-interest] exceptions (was: oz patch)

Jecel Assumpcao Jr jecel at merlintec.com
Sat Nov 13 03:13:50 UTC 1999

David Ungar wrote:
> Neat! I'll have to try it out.

I wasn't able to add the 'currentMorph' slot to the world before
reading the patch in Self 4.1. I tried it three different ways
(for the prompt, from the shell and graphically with an outliner)
and got three different errors, though these work just fine in
Self 4.0. So I haven't tried the patch in Self 4.1 yet.

Note that as it is now, this sometimes works and sometimes
doesn't (a new world/debugger pops up instead). It is probably
a timing problem.

And I haven't tested it much - just copied baseDrawOn: to some
unsuspecting morph and then adding a line like "3 / 0." to this

> And if you want exceptions, it should be easy to implement them:
> just a push-down stack in the process objects (one per process) containing
> blocks.
> You should be able to hide it behind a "tryIfFail:" method.

It certainly should be possible to implement them as you suggested.
I haven't looked much into it, but I think that killAllActivationsUpTo:
would come in handy.

> Jecel, I'm sure you know we already have the unwinding methods for blocks,
> you would probably want to use them to pop the exception handler stack on NLRs.

I hadn't seen it - very interesting. But I was thinking about
something like this:

   tryIfFail: failBlock = ( | iAmALittleExceptionMarker |
           [^ self value ] value.
           failBlock value

If all goes well, the last line is never executed. If an error
occurs, we can scan up the stack until we find the marker and
kill all frames up to it (somehow forcing the first line to
return nil or something) and then continue execution from
there. This is hardly the most complete exception system in
the world, of course :-)

Mario Wolczko wrote:
> Seriously, this is a pretty tricky system.  (I hope I get these
> details right; I haven't looked at the code in quite a while.)
> One reason is that the only way to safely handle problems in one
> thread is to hand off to another thread, so the code contain some
> tricky synchronizations.  For example, if a morph is sent a step
> message, and does not complete within 5(?) seconds, a watcher thread
> suspends the thread, and removes the morph from the list of morphs
> being stepped.  Also, if there is a problem in a thread (such as a
> failure in the basic display loop) we need to spawn another world,
> with another thread, containing a debugger on the failing thread.  I
> doubt this could have all been done with conventional exception
> handling in a single thread, although it may have simplified the code
> a bit (I would have to take a fresh look to be sure).

A normal exception system (does that make sense? :-) doesn't deal
with timeouts, so the watcher thread would have to remain pretty much
what it is now. Though timeout exceptions might be a great idea
in themselves. And note that though the exception handler runs in
the same process in which the error happened, nothing prevents it
from spawning new threads to do its job if it has to.

Please note that I have totally ignored things like semaphores
which might have processes waiting on them and other complicated
things the UI does.

The two most common problems while programming in Self is breaking
the drawing methods directly and allowing bad numbers to be sent to
the canvas drawing primitives (like having "inf" as one of your
bounds coordinates). I don't find it any easier to fix these from
a new world, so I am trying to avoid that.

-- Jecel

More information about the Self-interest mailing list