Statement generateReattachTable() {
    final Expression readField = stateField.accessor(thisExpr);
    final Statement defaultCase =
        Statement.throwExpression(MethodRef.RUNTIME_UNEXPECTED_STATE_ERROR.invoke(readField));
    return new Statement() {
      @Override
      protected void doGen(final CodeBuilder adapter) {
        int[] keys = new int[reattaches.size()];
        for (int i = 0; i < keys.length; i++) {
          keys[i] = i;
        }
        readField.gen(adapter);
        // Generate a switch table.  Note, while it might be preferable to just 'goto state', Java
        // doesn't allow computable gotos (probably because it makes verification impossible).  So
        // instead we emulate that with a jump table.  And anyway we still need to execute 'restore'
        // logic to repopulate the local variable tables, so the 'case' statements are a natural
        // place for that logic to live.
        adapter.tableSwitch(
            keys,
            new TableSwitchGenerator() {
              @Override
              public void generateCase(int key, Label end) {
                if (key == 0) {
                  // State 0 is special, it means initial state, so we just jump to the very end
                  adapter.goTo(end);
                  return;
                }
                ReattachState reattachState = reattaches.get(key);
                // restore and jump!
                reattachState.restoreStatement().gen(adapter);
                adapter.goTo(reattachState.reattachPoint());
              }

              @Override
              public void generateDefault() {
                defaultCase.gen(adapter);
              }
            },
            // Use tableswitch instead of lookupswitch.  TableSwitch is appropriate because our case
            // labels are sequential integers in the range [0, N).  This means that switch is O(1)
            // and
            // there are no 'holes' meaning that it is compact in the bytecode.
            true);
      }
    };
  }
Statement generateReattachTable ( ) { final Expression readField = stateField . accessor ( thisExpr ) ; final Statement defaultCase = Statement . throwExpression ( MethodRef . RUNTIME_UNEXPECTED_STATE_ERROR . invoke ( readField ) ) ; return new Statement ( ) { @ Override protected void doGen ( final CodeBuilder adapter ) { int [ ] keys = new int [ reattaches . size ( ) ] ; for ( int i = 0 ; i < keys . length ; i ++ ) { keys [ i ] = i ; } readField . gen ( adapter ) ; adapter . tableSwitch ( keys , new TableSwitchGenerator ( ) { @ Override public void generateCase ( int key , Label end ) { if ( key == 0 ) { adapter . goTo ( end ) ; return ; } ReattachState reattachState = reattaches . get ( key ) ; reattachState . restoreStatement ( ) . gen ( adapter ) ; adapter . goTo ( reattachState . reattachPoint ( ) ) ; } @ Override public void generateDefault ( ) { defaultCase . gen ( adapter ) ; } } , true ) ; } } ; }
Returns a statement that generates the reattach jump table.

<p>Note: This statement should be the <em>first</em> statement in any detachable method.