#89 Try/catch blocks

brian Wed 21 Jun 2006

I have try/catch blocks working:

try { ... } catch { ... }
try { ... } catch(Err e) { ... }

Note that you can leave off the catch parameter to catch anything (called a "catch all").

Here is an example method:

static Void main()
{
  try
  {
    throw IndexErr.make
  }
  catch(IndexErr err)
  {
    echo("caught $err")
  }
  catch
  {
    echo("catch all")
  }
}

This will result in the following fcode:

sys::Void main() [public static]
[Local 0] err: sys::IndexErr
[Code]
  0: CallNew          sys::IndexErr.make() -> sys::Void
  3: Throw
  4: Jump             47
  7: CatchErr         sys::IndexErr
 10: StoreVar         0
 13: CallNew          sys::StrBuf.make() -> sys::Void
 16: LoadStr          caught
 19: CallVirtual      sys::StrBuf.add(sys::Obj) -> sys::StrBuf
 22: LoadVar          0
 25: CallVirtual      sys::StrBuf.add(sys::Obj) -> sys::StrBuf
 28: CallVirtual      sys::StrBuf.toStr() -> sys::Str
 31: CallStatic       sys::Obj.echo(sys::Obj) -> sys::Void
 34: Jump             47
 37: CatchAll
 38: LoadStr          catch all
 41: CallStatic       sys::Obj.echo(sys::Obj) -> sys::Void
 44: Jump             47
 47: ReturnVoid
[ErrTable] len=18
  0 to 4 -> 7  sys::IndexErr
  0 to 4 -> 37  sys::Err

Note that the ErrTable is modeled as a method facet and has the exact same structure as a Java exception table. The fcode is similar to what a Java compiler would output with jumps around the catch blocks and jumps into the catch block declared via the err table. However note the two new opcodes CatchErr and CatchAll which begin the catch blocks. These are designed to give target platforms an explicit hook for handling exceptions. In Java the caught exception is always on the stack. CatchAll pops it. CatchErr makes a call to Err.make to map from a java.lang.Throwable into a sys::Err and perform a checkcast.

There is still a little bit more test code to write. Plus I want to polish up how the Java to Fan exception mapping works. For example I want a java.lang.NullPointerException to get mapped as a NullErr.

brian Thu 22 Jun 2006

Ok, I've got this feature completely wrapped up (not finally blocks, but catch blocks). I did some extra work to make sure exceptions generated by the Java runtime are handled correctly. For example if Java throws a NullPointerException, then a catch(Err) will be an instance of NullErr. More importantly if I do a catch(NullErr), then it will also catch NullPointerExceptions. This works because special types like NullErr will emit two entries in the Java exception table - one for fan.sys.NullErr$Val and another for java.lang.NullPointerException.

As part of this effort I added sys::ArgErr and sys::CastErr.

The full set of Fan to Java mappings:

NullErr         <->  java.lang.NullPointerException
CastErr         <->  java.lang.ClassCastException
IndexErr        <->  java.lang.IndexOutOfBoundsException
ArgErr          <->  java.lang.IllegalArgumentException
UnsupportedErr  <->  java.lang.UnsupportedOperationException
IOErr           <->  java.io.IOException

Login or Signup to reply.