[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]>
exception.diff
Description: exception.diff
exception.t
Description: exception.t