REF EXCEPTION John Gibson Apr 1996
COPYRIGHT University of Sussex 1996. All Rights Reserved.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< EXCEPTION >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< PROCEDURES >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
This file documents the Poplog exception handling facilities.
CONTENTS - (Use <ENTER> g to access required sections)
1 Overview
2 Raising an Exception
3 Handling Exceptions
4 Printing Exceptions
5 Exception ID Strings
5.1 Standard Exception Classes
... arith
... control
... exsys
... mem
... name
... syntax
... type
6 Exceptions Raised
-----------
1 Overview
-----------
An exception condition arises when a program detects that an error (or
possible error, etc) has occurred during its execution. A program can
signal an exception by calling sys_raise_exception, allowing
user-definable handler procedures (or standard system handlers) to deal
with the problem.
The arguments to sys_raise_exception comprise
¤ a severity code;
¤ an (optional) ID string that identifies the particular exception;
¤ a message string together with any associated data items.
The severity code recognises four levels of severity, namely
¤ Information
¤ Warning
¤ Recoverable error
¤ Error
The variable procedure pop_exception_handler represents the first stage
of exception handling, and may be redefined, either locally or globally.
sys_raise_exception calls all current (dynamically local) definitions of
this procedure, until one returns true to say that it has handled the
exception (or performs an abnormal exit). A true return from
pop_exception_handler indicates that sys_raise_exception should return
to its caller, and normal program execution should continue (however,
this is only permissible for Information, Warning and Recoverable
error).
If all current definitions of pop_exception_handler return false (i.e.
do not wish to handle the exception), then sys_exception_handler is
called as a backstop. This provides a second-stage variable handler
pop_exception_final, which is called in the same way as for
pop_exception_handler.
However, at the sys_exception_handler stage, it is assumed that
continuing with normal program execution after an error is no longer
possible, and that 'handling' an error will consist (for example) of
printing an appropriate message. Thus while a true return from
pop_exception_final prevents any further handlers from being called,
sys_exception_handler always finishes by either (a) returning true to
sys_raise_exception for Information or Warning, or (b) calling interrupt
for errors. (But, as with pop_exception_handler, pop_exception_final has
the option of performing an abnormal exit.)
The backstop for pop_exception_final is sys_exception_final, which
merely calls pop_pr_exception and returns true.
The normal sequence of events in processing an exception is summarised
by the following diagram (where ... means calling all current
definitions until one returns true):
sys_raise_exception -+
|
pop_exception_handler ... sys_exception_handler -+
| |
| pop_exception_final ... sys_exception_final
| | |
| | pop_pr_exception
| | |
|---------<--------(I,W)--+----<-----+
| |
| (R,E)
| |
return interrupt
(I,W,R only)
Note that pop_exception_handler is intended to be used to handle (and
recover from) specific exceptions only. All 'bulk' handling of errors
should be done with pop_exception_final.
For this reason, no part of the system ever locally redefines
pop_exception_handler, which is therefore completely free for use by
user programs. (The system does locally redefine pop_exception_final in
some contexts.)
-----------------------
2 Raising an Exception
-----------------------
sys_raise_exception(item1, ..., itemN, N, [procedure]
mess, idstring, severity)
sys_raise_exception(item1, ..., itemN, N, mess, severity)
sys_raise_exception(mess, itemlist, severity)
Raises an exception condition, and calls user-defined exception
handlers in pop_exception_handler to deal with it.
The arguments are as follows:
item1, ..., itemN, N
Zero or more data items involved in the exception, and
the number N of them: these are dependent on the
particular exception.
(For backward compatibility, the last form of the call
allows item1 ... itemN to be passed in a list itemlist
following the mess argument. This call form cannot
supply an idstring argument, and is now deprecated.)
mess
A message string describing the exception (or a vector
whose first element is the message string). See
* sys_pr_message for a full description of this
argument.
idstring
A string whose characters identify the particular
exception (defaults to nullstring if omitted). See
Exception ID Strings below.
severity
An integer ASCII character code specifying the severity
of the exception: `I` = Information, `W` = Warning, `R`
= Recoverable error, `E` = Error.
sys_raise_exception searches up the call stack for dynamic local
definitions of the variable procedure pop_exception_handler,
starting with its current value. Each handler procedure P found
is called with all the given arguments, i.e.
P(item1, ..., itemN, N, mess, idstring, severity)
A handler may do one of three things:
(1) Return false to say that it does not want to handle the
condition. sys_raise_exception will then continue by calling
the next handler. In addition to false, the handler must
also leave item1 ... itemN on the stack for the next
handler, i.e.
P(...) -> (item1, ..., itemN, false)
(Note that, if required, the code
repeat N times subscr_stack(N) endrepeat;
can be used to duplicate item1 ... itemN on top of the
stack.)
(2) Return true to say it has handled the condition. In this
case, sys_raise_exception will return normally to its
caller.
This is not permissible for severity = `E` (and results in a
recursive error with idstring 'exception-illret:control').
For a recoverable error `R`, the handler must additionally
leave on the stack any results expected by the particular
error.
(3) Perform an abnormal exit out of sys_raise_exception, using
exitfrom, chainfrom, setpop etc.
If all locally-defined handlers return false, the top-level
value of pop_exception_handler is run; by default this is
* sys_exception_handler, but if this is also redefined, and
returns false, sys_exception_handler is run anyway.
(N.B. If another exception is raised while calling a handler,
the recursive call of sys_raise_exception will call only those
handlers that have not yet been tried by outer invocations of
sys_raise_exception.)
mishap(item1, ..., itemN, N, mess, idstring) [procedure]
mishap(item1, ..., itemN, N, mess)
mishap(mess, itemlist)
This procedure is sys_raise_exception(% `E` %), i.e. raise an
error.
----------------------
3 Handling Exceptions
----------------------
pop_exception_handler(item1, ..., itemN, N, [procedure variable]
mess, idstring, severity) -> bool
A user-definable first-stage handler for exceptions. All current
definitions of this procedure are called by
* sys_raise_exception (described above). Its default value is
sys_exception_handler.
sys_exception_handler(item1, ..., itemN, N, [procedure]
mess, idstring, severity)
This procedure is the default value of pop_exception_handler,
called by sys_raise_exception. See * sys_raise_exception for
details of the arguments.
sys_exception_handler searches up the call stack for dynamic
local definitions of the variable procedure pop_exception_final,
starting with its current value. Each handler procedure P found
is called with all the given arguments, i.e.
P(item1, ..., itemN, N, mess, idstring, severity)
A handler may do one of three things:
(1) Return false to say that the next handler should be tried.
In addition to false, the handler must also leave item1 ...
itemN on the stack for the next handler, i.e.
P(...) -> (item1, ..., itemN, false)
(2) Return true to say no further handlers should be called.
(3) Perform an abnormal exit using exitfrom, chainfrom, setpop
etc.
If all locally-defined handlers return false, the top-level
value of pop_exception_final is run; by default this is
* sys_exception_final, but if this is also redefined, and
returns false, sys_exception_final is run anyway (this will
always return true).
(N.B. If another exception is raised while calling a handler, a
recursive call of sys_exception_handler will call only those
handlers that have not yet been tried by outer invocations of
sys_exception_handler.)
After calling the handlers, sys_exception_handler just returns
if severity = `I` or `W` (i.e. returns true to
sys_raise_exception).
Otherwise, for errors, the procedure in * interrupt is called
(and if that returns, * setpop). Before calling interrupt (in
fact, before calling the pop_exception_final handlers),
* pop_exit_ok is set to false if the standard input is not a
terminal. (Since the default value of interrupt under these
circumstances is sysexit, this guarantees that an error will
result in an error status being returned to the operating system
-- see REF * SYSTEM.)
pop_exception_final(item1, ..., itemN, N, [procedure variable]
mess, idstring, severity) -> bool
A user-definable final handler for exceptions. All current
definitions of this procedure are called by
* sys_exception_handler (described above). Its default value is
sys_exception_final.
sys_exception_final(item1, ..., itemN, N, [procedure]
mess, idstring, severity)
This procedure is the default value of pop_exception_final,
called by * sys_exception_handler.
It simply calls * pop_pr_exception with the given arguments, and
then returns true to sys_exception_handler.
----------------------
4 Printing Exceptions
----------------------
All the default Poplog routines for printing mishap and warning messages
use the procedure sys_pr_message to print the message, as well as the
current file, line number and other useful information.
pop_pr_exception(item1, ..., itemN, N, [procedure variable]
mess, idstring, severity)
A variable procedure called by * sys_exception_final to print an
error or warning message for an exception. Its default value is
sys_pr_exception. (However, the procedure sys_pr_exception is
only required for backward compatibility reasons; otherwise,
pop_pr_exception would default to sys_pr_message.)
pop_default_pr_exception(item1, ..., itemN, N, [procedure variable]
mess, idstring, severity)
If this variable has a non-undef value (i.e. not(isundef)) it
will be assigned to pop_pr_exception in contexts where otherwise
a system procedure would be locally assigned.
In particular inside Ved, pop_pr_exception has the value
ved_pr_exception. However, in immediate mode, sys_pr_exception
is assigned to it instead, and inside ved_lmr is is assigned a
special procedure which displays certain mishaps on the status
line, etc. In both these contexts pop_default_pr_exception will
be used instead, if defined by the user (e.g. in your init.p or
vedinit.p file).
sys_pr_exception(item1, ..., itemN, N, [procedure]
mess, idstring, severity)
This procedure is necessary only for backward compatibility
reasons, namely to call the obsolete procedures prmishap and
prwarning (i.e. when the exception relates to one of them, and
that one is set to something other than its default value).
Otherwise, sys_pr_exception just calls sys_pr_message.
sys_pr_message(item1, ..., itemN, N, [procedure]
mess, idstring, severity)
Prints a message (usually for an exception), outputting the
characters through * cucharerr.
The arguments are as follows:
item1, ..., itemN, N
Zero or more 'culprit' data items, and the number N of
them: these are dependent on the particular
message/exception.
mess
A message string to be printed. Alternatively, it may be
a 2- or 3-element vector whose first element is the
message string, and whose second or third element(s) are
a header_string and an integer detail_level, i.e.
{ message_string header_string detail_level }
If not supplied, header_string defaults to 'NOTE -' for
severity = `I`, to 'WARNING -' for severity = `W`, and
to 'MISHAP -' otherwise.
If not supplied, detail_level defaults to 4 for severity
= `I` or `W`, and to 5 otherwise. Note that the actual
detail level must be 0-5, and only the bottom 4 bits of
detail_level are used for this; the remaining bits can
specify a number of newlines to be output before the
message (e.g. 16:14 means 1 newline, detail level 4).
In all cases, the actual detail level used is got by
maximising the argument (or default) value with the
value of the variable pop_message_min_detail.
The actual message string used is got by processing the
given string (together with the idstring argument)
through the variable procedure pop_message_trans. (By
default, this just returns the same string.)
idstring
A string whose characters identify a particular
message/exception (see Exception ID Strings below).
severity
An integer ASCII character code specifying the severity
of the message/exception: `I` = Information, `W` =
Warning, `R` = Recoverable error, `E` = Error. (This
procedure does not distinguish between `R` and `E`.)
The full format of the message printed by sys_pr_message is
;;; header_string message_string
;;; INVOLVING: item1 item2 ... itemN
;;; FILE : popfilename LINE NUMBER poplinenum
;;; COMPILING: names of procedures being compiled
;;; DOING : pdprops of procedures currently executing
(popfilename and poplinenum are associated with the current
input list proglist -- see REF * PROGLIST.)
The detail level controls how many of the 5 lines are printed:
if 0, only the header string is printed; if 5, all 5 lines are
printed. Note that the INVOLVING line is present only if there
are 1 or more culprits, the FILE line is present only when
popfilename is true, and the COMPILING line is present only when
the Poplog VM is not at execute level.
message_string is printed using * sys_message_printf, with an
argument list containing item1 ... itemN. (That is, if
message_string starts with a % character, the string without the
initial % is printed using printf, otherwise the string is
printed literally.) Only the remaining items returned by
sys_message_printf (i.e those not picked up by printf % field
specifiers) will be used as culprits for the INVOLVING line.
See also * popsyscall, * pop_mishap_doing_lim, * popmessages,
* popmishaps, * popwarnings.
pop_message_trans(message_string, idstring) [procedure variable]
-> message_string
Called by sys_pr_message (with its idstring argument) to perform
any required translation of a message_string before printing.
The default value is erase (i.e. return the same
message_string).
pop_message_min_detail -> int [variable]
int -> pop_message_min_detail
The given (or default) detail level in sys_pr_message is
maximised with the value in this variable. Its default value is
0; setting it to 4 (for example) will cause warnings such as
DECLARING VARIABLE to print everything but the DOING line.
popsyscall -> bool [variable]
bool -> popsyscall
Controls which procedures currently executing are included in
the DOING list for messages produced by sys_pr_message.
If false (the default), only procedures whose pdprops are not
false and which are not "uninteresting" are printed (where an
"uninteresting" procedure is one whose pdprops are not "setpop",
or a word being with 'sys', 'ved', 'wved', 'xved', 'subsys' or
'pop11_'.
For a true value, all procedures are printed. If the true value
is additionally an integer, then system procedures whose pdprops
are false are printed as their hexadecimal addresses.
(In addition, a true value causes sys_pr_message to print each
invocation of * sys_raise_exception starting on a new line,
followed by the idstring argument of that invocation in
parentheses.)
pop_mishap_doing_lim -> false_or_int [variable]
false_or_int -> pop_mishap_doing_lim
Controls the number of procedures printed in the DOING list of
messages produced by sys_pr_message.
If false (the default), all currently executing procedures are
included; otherwise it should be a positive integer N,
specifying that only the most recent N callers are to be shown.
If set to 0, the DOING list is not printed at all.
popmessages -> list_or_false [variable]
list_or_false -> popmessages
Each time sys_pr_message is called to print a message it puts a
summary of the message (as a list of items) it this variable.
This can be disabled by assigning false to popmessages. (Default
value []).
popmishaps -> list_or_false [variable]
list_or_false -> popmishaps
Each time sys_pr_message is called to print an error message
(i.e. severity `R` or `E`) it puts in this variable a summary of
the message printed (as list of items); this is overwrites any
previous mishap message. You can prevent the message being
stored by assigning false to popmishaps. (Default value []).
popwarnings -> list_or_false [variable]
list_or_false -> popwarnings
When sys_pr_message is called to print a DECLARING VARIABLE
warning message by * sysdeclare (that is, a warning message with
idstring 'vm-ident:name-ref-none'), the name of the culprit
identifier is added to this list.
The initial value of popwarnings is []. If popwarnings is set
false, no list is created.
-----------------------
5 Exception ID Strings
-----------------------
The idstring argument to sys_raise_exception and other procedures in
this file is a string whose characters identify a particular exception
condition.
The general format of an idstring is a context part separated by a colon
from a class part, i.e.
context:class
The context part specifies the context or facility in which the
exception occurred, while the class part provides a generic
classification of the type of error, etc.
Each part may be further subdivided by hyphens into as many hierachical
components as required, i.e.
context-subcontext-subsubcontext:class-subclass-subsubclass
For example, the sysdeclare warning idstring
vm-ident:name-ref-none
specifies that the problem is in a Poplog VM procedure, and concerns an
identifier name; the class of the exception is name, subclass ref (using
the referent of a name), sub-subclass none (referent does not exist).
Note that the colon in an idstring is considered part of the class, i.e.
must always be present if class is non-empty. (An idstring of the form
:class indicates a 'generic' error.)
5.1 Standard Exception Classes
-------------------------------
The system currently defines the following standard classes for
exceptions (more will be added in future versions).
... arith
----------
Arithmetic errors.
arith-fltovf [exception class]
An arithmetic operation resulted in floating-point overflow.
arith-div0 [exception class]
Attempt to divide a rational number by integer zero (note that
dividing floating-point by zero produces arith-fltovf).
... control
------------
control [exception class]
Some kind of error in the flow of control.
... exsys
----------
This class is intended for exceptions relating to external systems, and
is further subclassed by (at least) the name of a particular system.
(For example, LIB * ODBC uses :exsys-odbc-sqlstate, where different
sqlstate values represent standard error classes as defined by X/Open
and SQL Access Group.)
... mem
--------
These are errors concerning the allocation of memory in some area of the
system (e.g. heap, userstack, callstack, etc). They divide into limit
errors (advisory limit reached) and nomore (no more memory available).
mem-limit [exception class]
While trying to allocate more space in a particular area of
memory, the advisory limit on the area's size was reached.
mem-nomore [exception class]
While trying to allocate more space in a particular area of
memory, the absolute (e.g. operating system imposed) limit on
the area's size was reached.
mem-fixedsize [exception class]
A fixed size memory area was exhausted.
... name
---------
name errors concern the association between a name and an object (its
referent). The name class subdivides into decl (declaring the name, i.e.
establishing a referent for it) and ref (using the referent).
name-decl-prot [exception class]
A name being declared already has a referent, and the
association is protected (i.e. cannot be overridden).
name-decl-ambig [exception class]
A name being declared already has a referent, which can be
overridden, but only if the new referent is sufficently similar
to the old in some respect (which it is not, hence the new
declaration is ambiguous).
name-ref-inval [exception class]
A name was supplied to an operation which uses its referent, but
the referent is invalid for the particular operation.
name-ref-none [exception class]
A name was supplied to an operation which uses its referent, but
the name has no referent.
... syntax
-----------
syntax [exception class]
Any kind of syntactic error in a language.
... type
---------
These concern supplying the wrong type of data as argument to an
operation. They are subclassed by the dataword (or pseudo-dataword) of
the type needed.
type-integer [exception class]
An argument was not an integer.
type-intrange [exception class]
An argument was an integer, but out-of-range.
type-real [exception class]
An argument was not a real number.
type-number [exception class]
An argument was not a number.
--------------------
6 Exceptions Raised
--------------------
This section describes exceptions generated by procedures in this file.
exception-illret:control [exception ID]
(Error) A pop_exception_handler procedure returned true to
sys_raise_exception for severity `E` (which is only allowed for
`I`, `W` and `R`).
+-+ C.all/ref/exception
+-+ Copyright University of Sussex 1996. All rights reserved.