[Apologies if this is a repeat, but the last message was early Wed. and
hasn't gone through yet]

The promised patches (against Wednesday morning's CVS-latest) are
attached to this message.
[You might need to reverse the first patch, against MANIFEST]

These patches add the following:

a) Exception register stack (E0-E31 for the moment, will trim down to
just E0)
b) div_i_i_ic altered to raise an exception when ic==0 (Which is to say,
sets E0 to 1)
c) New instructions set_e_i, set_i_e, push_e, pop_e
d) New test file t/op/exception.t, updated MANIFEST file

The tests exercise the new instructions and validate that div_i_i_ic
properly "raises" an exception.

The patches are a -very- crude form of exception handling. The constants
for errors like DIVIDE_BY_ZERO should probably be imported as manifest
constants, but that change would have been beyond the scope of the patch
:) Sample code that catches the divide-by-zero exception is in the
t/op/exception.t test #4, but here's a better explanation (Code uses
instructions that aren't implemented yet):

pushe                                # Save the current exceptions
set I2,5
div I1,I2,0                          # This would ordinarily trigger a
coredump. Not now.
eq E0,DIVIDE_BY_ZERO,CATCH_EXCEPTION # Not in the current patch, but
easy to add
pope                                 # Restore the exception stack

Rather than implementing a static set of flags in some sort of exception
register, each exception becomes an integer constant that can be tested
against. This leaves plenty of expansion room ((2**31)-1 possible
exceptions, assuming they're all negative) with the slight inconvenience
of not being able to test for a bitwise-or of exception flags. I don't
see this as being a major inconvenience, as most of the time you'll be
testing for a specific exception, at least at the assembler level.

The patch is incomplete, but then, so is the list of instructions that
can raise exceptions. This way we have a mechanism in place to handle
I/O exceptions when they're implemented (And I'm planning to work on
instructions such as open_i_s, read_i, close_i over the weekend). For
instance, an open I0,"<foo" instruction (Just an idea, syntax will
likely be very different) would be able to set constants such as
FILE_NOT_FOUND and such.

Since we're in assembler here, I'm not sure if a single instruction
should throw multiple exceptions, and it probably shouldn't -anyway-. In
that case, we could use E1-E31 for the others, but I feel that a single
instruction should throw only one of a limited range of exceptions. For
instance open_i_sc should only throw one of (FILE_NOT_FOUND,
NO_PERMISSION, FILE_READ_ONLY, ...).

I did consider using a bitfield of exceptions, but found it too
limiting. Also, the only benefit I can see of doing this is being able
to test for multiple exceptions at the same time. It isn't worth
limiting the number of flags to 32 or whatever just to be able to handle
this rare case.

As usual, comments, criticisms, and questions more than welcome.

-Jeff
<[EMAIL PROTECTED]> <[EMAIL PROTECTED]>

Attachment: exception.diff
Description: exception.diff

Attachment: exception.t
Description: exception.t

Reply via email to