Finally Block

In D, there are several restrictions in a finally block. It does not contain a return nor another try/catch block. To go around this restrictions TioPort applies a more complex refactoring. Given this code:

  try{
    // (1)
    return expr1;
    // ...
  }
  catch( IOException e ){
    // (2)
    return expr2;
  }
  finally{
    // (3)
    return expr3;
  }

Tioport will change this in D like this:

  {
    bool       tioport_stat_set_01;
    T          tioport_stat_ret_01;
    Object     tioport_stat_exc_01;
    try{
      try{
        // (1)
        {
          tioport_set_01 = true;
          tioport_ret_01 = expr1;
          goto try_end_01;
        }
        // ...
        tioport_tryend_01:;
      }
      catch( IOException e ){
        // (2)
        {
          tioport_set_01 = true;
          tioport_ret_01 = expr1;
          goto tioport_catchend_01;
        }
        // ...
      }
      tioport_catchend_01:;
    catch ( Object tioport_caughtExc_1 ) {
      tioport_stat_exc_1 = tioport_caughtExc_1;
    }
    {
      // (3)
      return expr3;
    }
    if( tioport_exc_01 !is null ) throw tioport_exc_01;
    if( tioport_set_01 ) return tioport_val_01;
  }

In (1) and (2) all return statements are replaced with the two assignments and the goto statement. The finally block in D is now a normal code block and has no more restrictions. It can now hold sub try/catch/finally and returns.

This pattern is applied recursivelly.