Here's how OZONE handles exceptions:
Here's how OZONE finds the active condition handler:
The routine that wants to trap an exception calls routine oz_sys_condhand_try:
status = oz_sys_condhand_try (routine_to_try, param_to_pass_to_it, catch_routine, param_for_it)
Input:
routine_to_try = entrypoint of routine that oz_sys_condhand_try is
to call under the protection of a condition handler
param_to_pass_to_it = parameter (void *) to pass to routine_to_try
catch_routine = entrypoint of routine to call if there is an
exception while routine_to_try is active
param_for_it = parameter (void *) to pass to catch_routine
Output:
status = value returned by routine_to_try or, if an
exception occurred, as returned by catch_routine
routine_to_try is called by oz_sys_condhand_try thusly:
status = routine_to_try (param_to_pass_to_it)
catch_routine is called by the kernel if there is an exception thusly:
status = catch_routine (param_for_it, OZ_Sigargs *sigargs, OZ_Mchargs *mchargs)
Input:
param_for_it = as passed to oz_sys_condhand_try
sigargs = points to signal arguments array
mchargs = points to machine arguments struct
Output:
status = OZ_RESIGNAL : this condition handler can't handle the condition,
resignal the exception to an outer level handler
OZ_RESUME : the state causing the exception has been corrected,
resume processing at the point of the exception
else : unwind the call stack (ie, longjmp) and return this
status value to caller of oz_sys_condhand_try
The oz_sys_condhand_try routine makes a 'burp' in the call frames on the stack. Then, when an exception
handler goes to look for a condition handler, it will see the burp in the call frames and it will know there is
a condition handler there.
A normal call frame looks like:
+---------------------------------+
| . |
| . |
| . |
| subroutine call arguments |
+---------------------------------+
| return address |
+---------------------------------+
| saved %ebp | <- %ebp
+---------------------------------+
| . |
| . |
| . |
| local variables |
+---------------------------------+
| optional saved %ebx,%esi,%edi |
+---------------------------------+
A 'burped' call frame looks like:
+---------------------------------+
| param_for_it |
+---------------------------------+
| catch_routine |
+---------------------------------+
| param_to_pass_to_it |
+---------------------------------+
| routine_to_try |
+---------------------------------+
| return address |
+---------------------------------+
| saved %ebp |
+---------------------------------+
| burp flag value | <- %ebp during oz_sys_condhand_try routine
+---------------------------------+
| saved %ebx,%esi,%edi |
+---------------------------------+
The burp flag has the value:
Notes: