Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ (2) — Plan9 3rd Edition (Vita Nuova)

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

sh(1)

prog(3)

SYS-EXCEPTION(2)

NAME

Exception, raise, rescue, rescued, unrescue − exception handling

SYNOPSIS

include "sys.m";
sys := load Sys Sys->PATH;
 Exception: adt
{
  name: string;  # name of exception
  mod:  string;  # module
  pc:   int;     # program counter
};
 raise:    fn(s: string);
rescue:   fn(s: string, e: ref Exception): int;
rescued:  fn(flag: int, s: string);
unrescue: fn();

DESCRIPTION

These functions provide exception handling in Limbo. 

­Exception communicates the nature of the exception.  ­Exception.pc is the virtual machine program counter at the point of the raised exception, relative to the start of the module. 

­Raise throws an exception with the name s, and sets the error string for sys-print(2) (the value of the format %r) to s.

­Rescue installs a rescue block for exceptions matched by s. If a matching exception occurs, ­rescue will return Sys->EXCEPTION; otherwise it returns Sys->HANDLER.  ­S matches an exception name when the two are equal, or ­s is a string (the prefix) followed by ∗, which matches any exception name starting with the same prefix.  In particular, "∗" matches all exceptions.  Rescue blocks can only handle exceptions that are raised in the same thread.  If an exception needs to be handled in a spawned thread, a rescue block must be installed there. 

if(sys->rescue("fail:∗", e) == Sys->EXCEPTION) {
# exception handling code ...
sys->rescued(Sys->EXIT, nil);
}

­Rescued tells the system what to do after an exception has been handled, as specified by flag:

­ACTIVE Leave the handler installed; execution continues. 

­RAISE Re-raise this exception or raise a different one.  If ­s is nil, the current exception is re-raised; otherwise, exception ­s is raised instead. 

­EXIT The thread exits. 

­ONCE Remove the handler; execution continues.  For example:

if(sys->rescue("an exception", e) == Sys->HANDLER) {
# normal execution code here
} else {
# handler code here
sys->rescued(Sys->ONCE, nil);  # removes the handler
}

­Unrescue removes the most recently installed handler and continues execution. 

EXAMPLES

The first example removes the handler if normal execution completes:

if(sys->rescue("an exception", e) == Sys->HANDLER) {
# normal execution code here
sys->unrescue();
} else {
# exception handling code here
}

The next example is a complete program that demonstrates the behaviour of exception handling by executing both the normal execution code and the handler code. 

implement Excep;
include "sys.m";
sys: Sys;
include "draw.m";
Excep: module
{
init:   fn(ctxt: ref Draw->Context, argv: list of string);
};
init(ctxt: ref Draw->Context, argv: list of string)
{
    sys = load Sys Sys->PATH;
    e := ref sys->Exception;
    if(sys->rescue("an exception", e) == Sys->EXCEPTION) {
   sys->print("rescue: exception\n");
   sys->print("e.name = %s\ne.mod = %s\ne.pc  = %d\n",
    e.name, e.mod, e.pc);
   sys->rescued(Sys->ONCE, nil);
    } else {
   sys->print("rescue: normal execution\n");
   sys->raise("an exception");
   }
   sys->print("raise: %r\n");
   sys->raise("nasty thing");# won’t be handled
}

SEE ALSO

sh(1), prog(3)

Plan 9  —  June 07, 2000

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026