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_tryThe 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: